From: Michael Tremer Date: Wed, 25 Aug 2010 10:56:31 +0000 (+0200) Subject: Remove the old pomona installer. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f532b07fd39b5ca455da7f394c0941ebba2496e;p=ipfire-3.x.git Remove the old pomona installer. --- diff --git a/pkgs/core/pomona/pomona.nm b/pkgs/core/pomona/pomona.nm deleted file mode 100644 index 4c256f549..000000000 --- a/pkgs/core/pomona/pomona.nm +++ /dev/null @@ -1,64 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# 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 3 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 . # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include $(PKGROOT)/Include - -PKG_NAME = pomona -PKG_VER = -PKG_REL = 0 - -PKG_MAINTAINER = -PKG_GROUP = System/Installer -PKG_URL = http://www.ipfire.org -PKG_LICENSE = GPLv3+ -PKG_SUMMARY = The IPFire 3.x installer. - -PKG_BUILD_DEPS+= pychecker -PKG_DEPS += e2fsprogs initscripts libuser newt pakfire parted pciutils popt \ - pyfire python python-dbus python-parted python-pyblock syslog-ng udev - -define PKG_DESCRIPTION - Pomona is the installer for IPFire 3.x. -endef - -DIR_APP = src - -define STAGE_PREPARE - cd $(DIR_APP) && make clean - #cd $(DIR_APP) && make -C po update-po -endef - -define STAGE_BUILD - cd $(DIR_APP) && make -endef - -define STAGE_TEST - cd $(DIR_APP) && make test -endef - -define STAGE_INSTALL - cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) \ - NAME=$(NAME) SNAME=$(SNAME) VERSION=$(VERSION) KVER=$(KVER) - cd $(DIR_APP) && make clean -endef diff --git a/pkgs/core/pomona/src/Makefile b/pkgs/core/pomona/src/Makefile deleted file mode 100644 index 41c9fc4f8..000000000 --- a/pkgs/core/pomona/src/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# 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 3 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 . # -# # -############################################################################### - -include Makefile.inc - -SUBDIRS = isys po - -all: subdirs - -install: all - rm -rf $(PYTHONLIBDIR) - -mkdir -p $(PYTHONLIBDIR) - [ -d "$(PYTHONLIBDIR)" ] - for d in $(SUBDIRS); do \ - make DESTDIR=`cd $(DESTDIR); pwd` -C $$d install; \ - [ $$? = 0 ] || exit 1; \ - done - cp -avf *.py storage lang-table $(PYTHONLIBDIR) - #sed -e "s/VERSION/$(VERSION)/g" \ - # -e "s/SNAME/$(SNAME)/g" \ - # -e "s/NAME/$(NAME)/g" \ - # -i $(PYTHONLIBDIR)/constants.py - -mkdir -p $(DESTDIR)/sbin - install -m 755 pomona $(DESTDIR)/sbin/pomona - -test: - ./runpychecker.sh - -clean: - rm -vf *.o *.so *.pyc *.pyo - for d in $(SUBDIRS); do make -C $$d clean; done - -subdirs: - for d in $(SUBDIRS); do make -C $$d; [ $$? = 0 ] || exit 1; done diff --git a/pkgs/core/pomona/src/Makefile.inc b/pkgs/core/pomona/src/Makefile.inc deleted file mode 100644 index 26f9eb95b..000000000 --- a/pkgs/core/pomona/src/Makefile.inc +++ /dev/null @@ -1,31 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# 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 3 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 . # -# # -############################################################################### - -DESTDIR=$(INSTALLER_DIR) - -INSTALL = install -c -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 -INSTALLNLSDIR = $(DESTDIR)/usr/share/locale - -PYTHONLIBDIR = $(DESTDIR)/usr/lib/pomona -PYTHONINCLUDE= /usr/include/python2.7/ - -CC = $(CROSS)gcc diff --git a/pkgs/core/pomona/src/console.py b/pkgs/core/pomona/src/console.py deleted file mode 100644 index 7fbb49fd7..000000000 --- a/pkgs/core/pomona/src/console.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/python - -from language import Language, LanguageWindow -from keyboard import Keyboard, KeyboardWindow - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) -N_ = lambda x: x - -from constants import * - -class Console: - def __init__(self, installer): - self.installer = installer - - self.language = Language(installer) - self.keyboard = Keyboard(installer) diff --git a/pkgs/core/pomona/src/constants.py b/pkgs/core/pomona/src/constants.py deleted file mode 100644 index 900948650..000000000 --- a/pkgs/core/pomona/src/constants.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) -N_ = lambda x: x - -PRODUCT_NAME = "IPFire" -PROCUCT_SNAME = "ipfire" -PRODUCT_VERSION = "3.0-prealpha2" -PRODUCT_SLOGAN = "Gluttony" -PRODUCT_URL = "http://www.ipfire.org/" - -SCREEN_ROOTLINE = _("Welcome to %s-v%s (%s)") % (PRODUCT_NAME, PRODUCT_VERSION, PRODUCT_SLOGAN,) -SCREEN_HELPLINE = _(" for help | between elements | selects | next screen") - -LOGFILE = "/tmp/installer.log" - -DISPATCH_FORWARD = 1 -DISPATCH_BACK = -1 -DISPATCH_NOOP = None - -INSTALL_OK = 0 -INSTALL_BACK = -1 -INSTALL_NOOP = -2 - -class Translator: - """A simple class to facilitate on-the-fly translation for newt buttons""" - def __init__(self, button, check): - self.button = button - self.check = check - - def __getitem__(self, which): - if which == 0: - return _(self.button) - elif which == 1: - return self.check - raise IndexError - - def __len__(self): - return 2 - -TEXT_OK_STR = N_("OK") -TEXT_OK_CHECK = "ok" -TEXT_OK_BUTTON = Translator(TEXT_OK_STR, TEXT_OK_CHECK) - -TEXT_CANCEL_STR = N_("Cancel") -TEXT_CANCEL_CHECK = "cancel" -TEXT_CANCEL_BUTTON = Translator(TEXT_CANCEL_STR, TEXT_CANCEL_CHECK) - -TEXT_BACK_STR = N_("Back") -TEXT_BACK_CHECK = "back" -TEXT_BACK_BUTTON = Translator(TEXT_BACK_STR, TEXT_BACK_CHECK) - -TEXT_YES_STR = N_("Yes") -TEXT_YES_CHECK = "yes" -TEXT_YES_BUTTON = Translator(TEXT_YES_STR, TEXT_YES_CHECK) - -TEXT_NO_STR = N_("No") -TEXT_NO_CHECK = "no" -TEXT_NO_BUTTON = Translator(TEXT_NO_STR, TEXT_NO_CHECK) diff --git a/pkgs/core/pomona/src/datastore.py b/pkgs/core/pomona/src/datastore.py deleted file mode 100644 index eed9fa7db..000000000 --- a/pkgs/core/pomona/src/datastore.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/python - -import console -import storage -#import timezone - -class DataStore: - def __init__(self, installer): - self.installer = installer - - self.console = console.Console(self.installer) - self.storage = storage.Storage(self.installer) - #self.timezone = timezone.Timezone(self.installer) diff --git a/pkgs/core/pomona/src/dispatch.py b/pkgs/core/pomona/src/dispatch.py deleted file mode 100644 index 26c404fc9..000000000 --- a/pkgs/core/pomona/src/dispatch.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python - -from storage import storageInitialize -from storage.partitioning import doAutoPartition - -from constants import * -from windows import * - -installSteps = [ - ("welcome", welcomeWindow,), - ("experimental", experimentalWindow,), - ("console", [ "LanguageWindow", "KeyboardWindow",]), - ("storage", storageInitialize,), - ("partmethod", partmethodWindow,), - ("autopartition", autopartitionWindow,), - #("autopartitionexecute", doAutoPartition,), - ("partition", [ "PartitionWindow",]), - ("bootloader", bootloaderWindow,), - ("complete", finishedWindow,), - ] - - -class Dispatcher: - def __init__(self, installer): - self.installer = installer - - self.step = None - self.skipSteps = {} - self.dir = DISPATCH_FORWARD - - def stepIsDirect(self, step): - """Takes a step number""" - if len(installSteps[step]) == 2: - return True - else: - return False - - def stepInSkipList(self, step): - return False # XXX - - def nextStep(self): - while self.step <= len(installSteps) or self.step == None: - if self.step == None: - self.step = 0 - else: - self.step += self.dir - - if self.stepInSkipList(self.step): - continue - else: - break - - if self.step == len(installSteps): - return None - else: - return installSteps[self.step] diff --git a/pkgs/core/pomona/src/exception.py b/pkgs/core/pomona/src/exception.py deleted file mode 100644 index 36fd2b004..000000000 --- a/pkgs/core/pomona/src/exception.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/python - -import os -import signal -import string -import sys -import traceback -import types - -from cPickle import Pickler - -dumpHash = {} - -def dumpClass(instance, fd, level=0, parentkey=""): - # protect from loops - try: - if not dumpHash.has_key(instance): - dumpHash[instance] = None - else: - fd.write("Already dumped\n") - return - except TypeError: - fd.write("Cannot dump object\n") - return - - if (instance.__class__.__dict__.has_key("__str__") or - instance.__class__.__dict__.has_key("__repr__")): - fd.write("%s\n" % (instance,)) - return - - fd.write("%s instance, containing members:\n" % (instance.__class__.__name__)) - pad = ' ' * ((level) * 2) - - for key, value in instance.__dict__.items(): - if parentkey != "": - curkey = parentkey + "." + key - else: - curkey = key - - if type(value) == types.ListType: - fd.write("%s%s: [" % (pad, curkey)) - first = 1 - for item in value: - if not first: - fd.write(", ") - else: - first = 0 - if type(item) == types.InstanceType: - dumpClass(item, fd, level + 1,) - else: - fd.write("%s" % (item,)) - fd.write("]\n") - - elif type(value) == types.DictType: - fd.write("%s%s: {" % (pad, curkey)) - first = 1 - for k, v in value.items(): - if not first: - fd.write(", ") - else: - first = 0 - if type(k) == types.StringType: - fd.write("'%s': " % (k,)) - else: - fd.write("%s: " % (k,)) - if type(v) == types.InstanceType: - dumpClass(v, fd, level + 1, parentkey = curkey) - else: - fd.write("%s" % (v,)) - fd.write("}\n") - - elif type(value) == types.InstanceType: - fd.write("%s%s: " % (pad, curkey)) - dumpClass(value, fd, level + 1, parentkey=curkey) - - else: - fd.write("%s%s: %s\n" % (pad, curkey, value)) - -def dumpException(out, text, tb, installer): - p = Pickler(out) - - out.write(text) - - trace = tb - if trace is not None: - while trace.tb_next: - trace = trace.tb_next - frame = trace.tb_frame - out.write("\nLocal variables in innermost frame:\n") - try: - for (key, value) in frame.f_locals.items(): - out.write("%s: %s\n" % (key, value)) - except: - pass - - try: - out.write("\n\n") - dumpClass(installer, out) - except: - out.write("\nException occurred during state dump:\n") - traceback.print_exc(None, out) - - for file in ("/root/syslog", "/root/pomona.log", "/root/install.log"): - try: - f = open(file, 'r') - line = "\n\n%s:\n" % (file,) - while line: - out.write(line) - line = f.readline() - f.close() - except IOError: - pass - except: - out.write("\nException occurred during %s file copy:\n" % (file,)) - traceback.print_exc(None, out) - -# Reverse the order that tracebacks are printed so people will hopefully quit -# giving us the least useful part of the exception in bug reports. -def formatException(type, value, tb): - lst = traceback.format_tb(tb) - lst.reverse() - lst.insert(0, 'Traceback (most recent call first):\n') - lst.extend(traceback.format_exception_only(type, value)) - return lst - -def handleException(installer, (type, value, tb)): - # restore original exception handler - sys.excepthook = sys.__excepthook__ - - installer.log.error("Exception occured. Read more in /tmp/instdump.txt.") - - # get traceback information - list = formatException(type, value, tb) - text = string.joinfields(list, "") - - # save to local storage - out = open("/tmp/instdump.txt", "w") - dumpException(out, text, tb, installer) - out.close() - - win = installer.intf.exceptionWindow(text, "/tmp/instdump.txt") - if not win: - installer.intf.__del__() - os.kill(os.getpid(), signal.SIGKILL) - - while 1: - win.run() - - if win.getrc() == 0: - installer.intf.__del__() - os.kill(os.getpid(), signal.SIGKILL) diff --git a/pkgs/core/pomona/src/isys/Makefile b/pkgs/core/pomona/src/isys/Makefile deleted file mode 100644 index 680ae057b..000000000 --- a/pkgs/core/pomona/src/isys/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# 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 3 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 . # -# # -############################################################################### - -include ../Makefile.inc - -OBJECTS = isys.o mount.o - -CFLAGS += -I$(PYTHONINCLUDE) -LDFLAGS = -LIBS = - -all: depend _isys.so - -depend: $(patsubst %.o,%.c,$(OBJECTS)) - $(CPP) -M $(CFLAGS) $(patsubst %.o,%.c,$(OBJECTS)) > depend - -%.o: %.c - $(CC) -c $(CFLAGS) -o $@ $< - -_isys.so: $(OBJECTS) - $(CC) -shared $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@ $(OBJECTS) - -install: _isys.so isys.py - cp -vf _isys.so isys.py $(PYTHONLIBDIR) - -clean: - rm -vf $(OBJECTS) depend _isys.so *.py[co] - -test: _isys.so - python -c "import isys" - -ifeq (depend,$(wildcard depend)) -include depend -endif diff --git a/pkgs/core/pomona/src/isys/isys.c b/pkgs/core/pomona/src/isys/isys.c deleted file mode 100644 index 08684fac2..000000000 --- a/pkgs/core/pomona/src/isys/isys.c +++ /dev/null @@ -1,62 +0,0 @@ - - -#include - -#include "isys.h" -#include "mount.h" - - -static PyObject * doMount(PyObject * s, PyObject * args); -static PyObject * doUMount(PyObject * s, PyObject * args); - -static PyMethodDef isysModuleMethods[] = { - { "mount", (PyCFunction) doMount, METH_VARARGS, NULL }, - { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL }, -}; - -void init_isys(void) { - PyObject * m, * d; - - m = Py_InitModule("_isys", isysModuleMethods); - d = PyModule_GetDict(m); -} - -static PyObject * doMount(PyObject * s, PyObject * args) { - char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; - int rc; - - if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, - &flags)) return NULL; - - rc = doPwMount(device, mntpoint, fs, flags, &err); - if (rc == MOUNT_ERR_ERRNO) - PyErr_SetFromErrno(PyExc_SystemError); - else if (rc) { - PyObject *tuple = PyTuple_New(2); - - PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); - PyTuple_SetItem(tuple, 1, PyString_FromString(err)); - PyErr_SetObject(PyExc_SystemError, tuple); - } - - if (rc) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doUMount(PyObject * s, PyObject * args) { - char * fs; - - if (!PyArg_ParseTuple(args, "s", &fs)) - return NULL; - - if (umount(fs)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} diff --git a/pkgs/core/pomona/src/isys/isys.h b/pkgs/core/pomona/src/isys/isys.h deleted file mode 100644 index 4757e4cd0..000000000 --- a/pkgs/core/pomona/src/isys/isys.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef H_ISYS -#define H_ISYS - - -#endif diff --git a/pkgs/core/pomona/src/isys/isys.py b/pkgs/core/pomona/src/isys/isys.py deleted file mode 100644 index ffc2c976f..000000000 --- a/pkgs/core/pomona/src/isys/isys.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/python - -import _isys - -import os -import string - -mountCount = {} - -## Mount a filesystem, similar to the mount system call. -# @param device The device to mount. If bindMount is 1, this should be an -# already mounted directory. Otherwise, it should be a device -# name. -# @param location The path to mount device on. -# @param fstype The filesystem type on device. This can be disk filesystems -# such as vfat or ext3, or pseudo filesystems such as proc or -# selinuxfs. -# @param readOnly Should this filesystem be mounted readonly? -# @param bindMount Is this a bind mount? (see the mount(8) man page) -# @param remount Are we mounting an already mounted filesystem? -# @return The return value from the mount system call. -def mount(device, location, fstype = "ext2", readOnly = 0, bindMount = 0, remount = 0, options = "defaults"): - flags = None - location = os.path.normpath(location) - opts = string.split(options) - - # We don't need to create device nodes for devices that start with '/' - # (like '/usbdevfs') and also some special fake devices like 'proc'. - # First try to make a device node and if that fails, assume we can - # mount without making a device node. If that still fails, the caller - # will have to deal with the exception. - # We note whether or not we created a node so we can clean up later. - - if mountCount.has_key(location) and mountCount[location] > 0: - mountCount[location] = mountCount[location] + 1 - return - - if readOnly or bindMount or remount: - if readOnly: - opts.append("ro") - if bindMount: - opts.append("bind") - if remount: - opts.append("remount") - - flags = ",".join(opts) - - #log.debug("isys.py:mount()- going to mount %s on %s with options %s" %(device, location, flags)) - rc = _isys.mount(fstype, device, location, flags) - - if not rc: - mountCount[location] = 1 - - return rc - -## Unmount a filesystem, similar to the umount system call. -# @param what The directory to be unmounted. This does not need to be the -# absolute path. -# @param removeDir Should the mount point be removed after being unmounted? -# @return The return value from the umount system call. -def umount(what, removeDir = 1): - what = os.path.normpath(what) - - if not os.path.isdir(what): - raise ValueError, "isys.umount() can only umount by mount point" - - if mountCount.has_key(what) and mountCount[what] > 1: - mountCount[what] = mountCount[what] - 1 - return - - rc = _isys.umount(what) - - if removeDir and os.path.isdir(what): - os.rmdir(what) - - if not rc and mountCount.has_key(what): - del mountCount[what] - - return rc diff --git a/pkgs/core/pomona/src/isys/mount.c b/pkgs/core/pomona/src/isys/mount.c deleted file mode 100644 index 6b0f17529..000000000 --- a/pkgs/core/pomona/src/isys/mount.c +++ /dev/null @@ -1,186 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mount.h" - -static int mkdirIfNone(char * directory); - -static int readFD(int fd, char **buf) { - char *p; - size_t size = 4096; - int s, filesize = 0; - - *buf = calloc(4096, sizeof (char)); - if (*buf == NULL) - abort(); - - do { - p = &(*buf)[filesize]; - s = read(fd, p, 4096); - if (s < 0) - break; - - filesize += s; - if (s == 0) - break; - - size += s; - *buf = realloc(*buf, size); - if (*buf == NULL) - abort(); - } while (1); - - if (filesize == 0 && s < 0) { - free(*buf); - *buf = NULL; - return -1; - } - - return filesize; -} - -int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { - int rc, child, status, pipefd[2]; - char *opts = NULL, *device; - - if (mkdirChain(where)) - return MOUNT_ERR_ERRNO; - - if (strstr(fs, "nfs")) { - if (options) { - if (asprintf(&opts, "%s,nolock", options) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - opts = strdup("nolock"); - } - device = strdup(dev); - } else { - if ((options && strstr(options, "bind") == NULL) && - strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) && - *dev != '/') { - if (asprintf(&device, "/dev/%s", dev) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - device = strdup(dev); - } - if (options) - opts = strdup(options); - } - - if (pipe(pipefd)) - return MOUNT_ERR_ERRNO; - - if (!(child = fork())) { - int fd; - - close(pipefd[0]); - - /* Close stdin entirely, redirect stdout to tty5, and redirect stderr - * to a pipe so we can put error messages into exceptions. We'll - * only use these messages should mount also return an error code. - */ - fd = open("/dev/tty5", O_RDONLY); - close(STDIN_FILENO); - dup2(fd, STDIN_FILENO); - close(fd); - - fd = open("/dev/tty5", O_WRONLY); - close(STDOUT_FILENO); - dup2(fd, STDOUT_FILENO); - - dup2(pipefd[1], STDERR_FILENO); - - if (opts) { - rc = execl("/bin/mount", - "/bin/mount", "-n", "-t", fs, "-o", opts, device, where, NULL); - exit(1); - } - else { - rc = execl("/bin/mount", "/bin/mount", "-n", "-t", fs, device, where, NULL); - exit(1); - } - } - - close(pipefd[1]); - - if (err != NULL) - rc = readFD(pipefd[0], err); - - close(pipefd[0]); - waitpid(child, &status, 0); - - free(opts); - free(device); - if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) - return MOUNT_ERR_OTHER; - - return 0; -} - -int mkdirChain(char * origChain) { - char * chain; - char * chptr; - - chain = alloca(strlen(origChain) + 1); - strcpy(chain, origChain); - chptr = chain; - - while ((chptr = strchr(chptr, '/'))) { - *chptr = '\0'; - if (mkdirIfNone(chain)) { - *chptr = '/'; - return MOUNT_ERR_ERRNO; - } - - *chptr = '/'; - chptr++; - } - - if (mkdirIfNone(chain)) - return MOUNT_ERR_ERRNO; - - return 0; -} - -static int mkdirIfNone(char * directory) { - int rc, mkerr; - char * chptr; - - /* If the file exists it *better* be a directory -- I'm not going to - actually check or anything */ - if (!access(directory, X_OK)) - return 0; - - /* if the path is '/' we get ENOFILE not found" from mkdir, rather - then EEXIST which is weird */ - for (chptr = directory; *chptr; chptr++) - if (*chptr != '/') - break; - if (!*chptr) - return 0; - - rc = mkdir(directory, 0755); - mkerr = errno; - - if (!rc || mkerr == EEXIST) - return 0; - - return MOUNT_ERR_ERRNO; -} diff --git a/pkgs/core/pomona/src/isys/mount.h b/pkgs/core/pomona/src/isys/mount.h deleted file mode 100644 index b50532264..000000000 --- a/pkgs/core/pomona/src/isys/mount.h +++ /dev/null @@ -1,13 +0,0 @@ - -#ifndef H_MOUNT -#define H_MOUNT - -#define MOUNT_ERR_ERRNO 1 -#define MOUNT_ERR_OTHER 2 - -#include /* for umount() */ - -int doPwMount(char *dev, char *where, char *fs, char *options, char **err); -int mkdirChain(char * origChain); - -#endif diff --git a/pkgs/core/pomona/src/keyboard.py b/pkgs/core/pomona/src/keyboard.py deleted file mode 100644 index 304462695..000000000 --- a/pkgs/core/pomona/src/keyboard.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python - -import os - -from snack import ListboxChoiceWindow - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -from constants import * - -def gkn(str): - idx = str.find("|") - if idx == -1: - return str - return str[idx + 1:] - -class KeyboardModels: - def __init__(self): - self._modelDict = { - 'ar-azerty' : [N_('keyboard|Arabic (azerty)'), 'us,ara', 'pc105', 'azerty', 'grp:shifts_toggle,grp_led:scroll'], - 'ar-azerty-digits' : [N_('keyboard|Arabic (azerty/digits)'), 'us,ara', 'pc105', 'azerty_digits', 'grp:shifts_toggle,grp_led:scroll'], - 'ar-digits' : [N_('keyboard|Arabic (digits)'), 'us,ara', 'pc105', 'digits', 'grp:shifts_toggle,grp_led:scroll'], - 'ar-qwerty' : [N_('keyboard|Arabic (qwerty)'), 'us,ara', 'pc105', 'qwerty', 'grp:shifts_toggle,grp_led:scroll'], - 'ar-qwerty-digits' : [N_('keyboard|Arabic (qwerty/digits)'), 'us,ara', 'pc105', 'qwerty_digits', 'grp:shifts_toggle,grp_led:scroll'], - 'be-latin1' : [N_('keyboard|Belgian (be-latin1)'), 'be', 'pc105', '', ''], - 'ben' : [N_('keyboard|Bengali (Inscript)'), 'us,in', 'pc105', 'ben', 'grp:shifts_toggle,grp_led:scroll'], - 'ben-probhat' : [N_('keyboard|Bengali (Probhat)'), 'us,in', 'pc105', 'ben_probhat', 'grp:shifts_toggle,grp_led:scroll'], - 'bg_bds-utf8' : [N_('keyboard|Bulgarian'), 'us,bg', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'bg_pho-utf8' : [N_('keyboard|Bulgarian (Phonetic)'), 'us,bg', 'pc105', ',phonetic', 'grp:shifts_toggle,grp_led:scroll'], - 'br-abnt2' : [N_('keyboard|Brazilian (ABNT2)'), 'br', 'abnt2', '', ''], - 'cf' : [N_('keyboard|French Canadian'), 'ca(fr)', 'pc105', '', ''], - 'croat' : [N_('keyboard|Croatian'), 'hr', 'pc105', '', '' ], - 'cz-us-qwertz' : [N_('keyboard|Czech'), 'us,cz', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'cz-lat2' : [N_('keyboard|Czech (qwerty)'), 'cz', 'pc105', 'qwerty', ''], - 'de' : [N_('keyboard|German'), 'de', 'pc105', '', ''], - 'de-latin1' : [N_('keyboard|German (latin1)'), 'de', 'pc105', '', ''], - 'de-latin1-nodeadkeys' : [N_('keyboard|German (latin1 w/ no deadkeys)'), 'de', 'pc105', 'nodeadkeys', ''], - 'dev' : [N_('keyboard|Devanagari (Inscript)'), 'us,dev', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'dvorak' : [N_('keyboard|Dvorak'), 'us', 'pc105', 'dvorak', ''], - 'dk' : [N_('keyboard|Danish'), 'dk', 'pc105', '', ''], - 'dk-latin1' : [N_('keyboard|Danish (latin1)'), 'dk', 'pc105', '', ''], - 'es' : [N_('keyboard|Spanish'), 'es', 'pc105', '', ''], - 'et' : [N_('keyboard|Estonian'), 'ee', 'pc105', '', ''], - 'fi' : [N_('keyboard|Finnish'), 'fi', 'pc105', '', ''], - 'fi-latin1' : [N_('keyboard|Finnish (latin1)'), 'fi', 'pc105', '', ''], - 'fr' : [N_('keyboard|French'), 'fr', 'pc105', '', ''], - 'fr-latin9' : [N_('keyboard|French (latin9)'), 'fr', 'pc105', 'latin9', ''], - 'fr-latin1' : [N_('keyboard|French (latin1)'), 'fr', 'pc105', '', ''], - 'fr-pc' : [N_('keyboard|French (pc)'), 'fr', 'pc105', '', ''], - 'fr_CH' : [N_('keyboard|Swiss French'), 'fr_CH', 'pc105', '', ''], - 'fr_CH-latin1' : [N_('keyboard|Swiss French (latin1)'), 'ch', 'pc105', 'fr', ''], - 'gr' : [N_('keyboard|Greek'), 'us,gr', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'guj' : [N_('keyboard|Gujarati (Inscript)'), 'us,in', 'pc105', 'guj', 'grp:shifts_toggle,grp_led:scroll'], - 'gur' : [N_('keyboard|Punjabi (Inscript)'), 'us,gur', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'hu' : [N_('keyboard|Hungarian'), 'hu', 'pc105', '', ''], - 'hu101' : [N_('keyboard|Hungarian (101 key)'), 'hu', 'pc105', 'qwerty', ''], - 'is-latin1' : [N_('keyboard|Icelandic'), 'is', 'pc105', '', ''], - 'it' : [N_('keyboard|Italian'), 'it', 'pc105', '', ''], - 'it-ibm' : [N_('keyboard|Italian (IBM)'), 'it', 'pc105', '', ''], - 'it2' : [N_('keyboard|Italian (it2)'), 'it', 'pc105', '', ''], - 'jp106' : [N_('keyboard|Japanese'), 'jp', 'jp106', '', ''], - 'ko' : [N_('keyboard|Korean'), 'kr', 'pc105', '', ''], - 'la-latin1' : [N_('keyboard|Latin American'), 'latam', 'pc105', '', ''], - 'mk-utf' : [N_('keyboard|Macedonian'), 'us,mkd', 'pc105', '','grp:shifts_toggle,grp_led:scroll'], - 'nl' : [N_('keyboard|Dutch'), 'nl', 'pc105', '', ''], - 'no' : [N_('keyboard|Norwegian'), 'no', 'pc105', '', ''], - 'pl2' : [N_('keyboard|Polish'), 'pl', 'pc105', '', ''], - 'pt-latin1' : [N_('keyboard|Portuguese'), 'pt', 'pc105', '', ''], - 'ro_win' : [N_('keyboard|Romanian'), 'ro', 'pc105', '', ''], - 'ru' : [N_('keyboard|Russian'), 'us,ru', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'sr-cy' : [N_('keyboard|Serbian'), 'cs', 'pc105', '', ''], - 'sr-latin' : [N_('keyboard|Serbian (latin)'), 'cs', 'pc105', 'latin', ''], - 'sv-latin1' : [N_('keyboard|Swedish'), 'se', 'pc105', '', ''], - 'sg' : [N_('keyboard|Swiss German'), 'ch', 'pc105', 'de_nodeadkeys', ''], - 'sg-latin1' : [N_('keyboard|Swiss German (latin1)'), 'ch', 'pc105', 'de_nodeadkeys', ''], - 'sk-qwerty' : [N_('keyboard|Slovak (qwerty)'), 'sk', 'pc105', '', 'qwerty'], - 'slovene' : [N_('keyboard|Slovenian'), 'si', 'pc105', '', ''], - 'tml-inscript' : [N_('keyboard|Tamil (Inscript)'), 'us,in', 'pc105', 'tam', 'grp:shifts_toggle,grp_led:scroll'], - 'tml-uni' : [N_('keyboard|Tamil (Typewriter)'), 'us,in', 'pc105', 'tam_TAB', 'grp:shifts_toggle,grp_led:scroll'], - 'trq' : [N_('keyboard|Turkish'), 'tr', 'pc105', '', ''], - 'uk' : [N_('keyboard|United Kingdom'), 'gb', 'pc105', '', ''], - 'ua-utf' : [N_('keyboard|Ukrainian'), 'us,ua', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], - 'us-acentos' : [N_('keyboard|U.S. International'), 'us', 'pc105', 'intl', ''], - 'us' : [N_('keyboard|U.S. English'), 'us+inet', 'pc105', '', ''], - } - - def getAllModels(self): - ret = [] - for model in self._modelDict.values(): - ret.append(gkn(_(model[0]))) - return ret - -class Keyboard: - def __init__(self, installer): - self.installer = installer - - self.models = KeyboardModels() - - def getKeymap(self): - return gkn(self.models._modelDict["us"][0]) # XXX - - def setKeymap(self, keymap): - self.installer.log.debug("Set keymap to \"%s\"" % keymap) - - -class KeyboardWindow: - def __call__(self, installer): - #if flags.virtpconsole: - # return INSTALL_NOOP - - keyboard = installer.ds.console.keyboard - - keyboards = keyboard.models.getAllModels() - keyboards.sort() - - default = keyboard.getKeymap() - - (button, choice) = ListboxChoiceWindow(installer.intf.screen, - _("Keyboard Selection"), - _("Which model keyboard is attached to this computer?"), - keyboards, buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], - width = 30, scroll = 1, height = 8, default = default) - - if button == TEXT_BACK_CHECK: - return INSTALL_BACK - - keyboard.setKeymap(keyboards[choice]) - #keyboard.activate() - - return INSTALL_OK diff --git a/pkgs/core/pomona/src/lang-table b/pkgs/core/pomona/src/lang-table deleted file mode 100644 index a4f15fd89..000000000 --- a/pkgs/core/pomona/src/lang-table +++ /dev/null @@ -1,3 +0,0 @@ -English en LatArCyrHeb-16 en_US.UTF-8 us America/New_York -German de LatArCyrHeb-16 de_DE.UTF-8 de-latin1-nodeadkeys Europe/Berlin -Danish da LatArCyrHeb-16 da_DK.UTF-8 dk Europe/Copenhagen diff --git a/pkgs/core/pomona/src/language.py b/pkgs/core/pomona/src/language.py deleted file mode 100644 index bdbe5d4b1..000000000 --- a/pkgs/core/pomona/src/language.py +++ /dev/null @@ -1,109 +0,0 @@ -#/usr/bin/python - -import os -import locale -import string - -from snack import ListboxChoiceWindow - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -from constants import * - -# Converts a single language into a "language search path". For example, -# de_DE.utf8@euro would become "de_DE.utf8@euro de_DE.utf8 de_DE de" -def expandLangs(astring): - langs = [astring] - charset = None - # remove charset ... - if '.' in astring: - langs.append(string.split(astring, '.')[0]) - - if '@' in astring: - charset = string.split(astring, '@')[1] - - # also add 2 character language code ... - if len(astring) > 2: - if charset: - langs.append("%s@%s" %(astring[:2], charset)) - - langs.append(astring[:2]) - - return langs - -class Language: - def __init__(self, installer): - self.installer = installer - - self.languages = {} - - # nick -> (name, short name, font, keyboard, timezone) mapping - search = ('lang-table', '../lang-table', '/usr/lib/pomona/lang-table', '/etc/lang-table') - for path in search: - if os.access(path, os.R_OK): - f = open(path, "r") - break - - for line in f.readlines(): - line = line.strip() #string.strip(line) - l = line.split("\t") #.split(line, '\t') - - # throw out invalid lines - if len(l) < 6: - continue - - (name, short, font, locale, keyboard, timezone) = l - self.languages[short] = (name, _(name), font, locale, timezone) - - f.close() - - def getAllLanguages(self): - ret = [] - for (name, name2, font, locale, timezone) in self.languages.values(): - ret.append(name2) - return ret - - def getLanguage(self): - return "English" # XXX - - def setLanguage(self, lang): - self.installer.log.debug("Set language to \"%s\"" % lang) - os.environ["LC_NUMERIC"] = 'C' - #XXX os.environ["LANG"] = "de_DE.utf8" - - try: - locale.setlocale(locale.LC_ALL, "") - except locale.Error: - pass - - -class LanguageWindow: - def __call__(self, installer): - language = installer.ds.console.language - - languages = language.getAllLanguages() - languages.sort() - - current = language.getLanguage() - - (button, choice) = ListboxChoiceWindow(installer.intf.screen, - _("Language Selection"), - _("What language would you like to use during the " - "installation process?"), languages, - buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], - width = 30, default = _(current), scroll = 1, - height = min((8, len(languages)))) - - if button == TEXT_BACK_CHECK: - return INSTALL_BACK - - language.setLanguage(languages[choice]) - #installer.ds.timezone.setTimezoneInfo(id.console.getDefaultTimeZone()) - - return INSTALL_OK - - -if __name__ == "__main__": - language = Language(None) - print language.getAllLanguages() diff --git a/pkgs/core/pomona/src/log.py b/pkgs/core/pomona/src/log.py deleted file mode 100644 index aee3e5d5f..000000000 --- a/pkgs/core/pomona/src/log.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/python - -import time - -from constants import * - -class Logger: - def __init__(self): - self.logfile = open(LOGFILE, "w+") - - self.logline = "%s %8s: %s\n" # time, group, message - - def critical(self, msg): - self.logfile.write(self.logline % (self.time(), "CRITICAL", msg,)) - self.flush() - - def info(self, msg): - self.logfile.write(self.logline % (self.time(), "INFO", msg,)) - self.flush() - - def debug(self, msg): - self.logfile.write(self.logline % (self.time(), "DEBUG", msg,)) - self.flush() - - def error(self, msg): - self.logfile.write(self.logline % (self.time(), "ERROR", msg,)) - self.flush() - - def warning(self, msg): - self.logfile.write(self.logline % (self.time(), "WARNING", msg,)) - self.flush() - - def stdout(self, msg): - self.logfile.write(self.logline % (self.time(), "STDOUT", msg,)) - self.flush() - print msg - - def time(self): - return time.strftime("%d %b %Y %H:%M:%S") - - def __del__(self): - self.logfile.close() - - def flush(self): - self.logfile.flush() diff --git a/pkgs/core/pomona/src/partition.py b/pkgs/core/pomona/src/partition.py deleted file mode 100644 index 3acd670ab..000000000 --- a/pkgs/core/pomona/src/partition.py +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/python - -from snack import * - -from storage.deviceaction import * -import storage -import storage.formats as formats -from storage.devicelibs.lvm import safeLvmName - -from constants import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -def logicalVolumeGroupList(installer): - storage = installer.ds.storage - - vgs = [] - for vg in storage.vgs: - vgs.append(vg.name) - (button, choice) = ListboxChoiceWindow(installer.intf.screen, - _("Volume Group Selection"), - _("What language would you like to use during the " - "installation process?"), vgs, - buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], - width = 30, scroll = 1, - height = min((8, len(vgs)))) - if button == TEXT_BACK_CHECK: - return - - for vg in storage.vgs: - if choice == vg.name: - return vg - return - -class PartitionWindow(object): - def populate(self): - self.lb.clear() - - for vg in self.storage.vgs: - self.lb.append([vg.name, "", "", "",], vg) - - freespace = vg.freeSpace - if freespace: - self.lb.append([" %s" % _("Free Space"), "", "", "%dM" % freespace,], - None, [LEFT, LEFT, LEFT, RIGHT]) - - for disk in self.storage.disks: - self.lb.append([disk.path, "", "", "",], None) - for part in self.storage.partitions: - if disk == part.disk: - mountpoint = type = "" - if part.format: - type = part.format.name - try: - if part.format.mountpoint: - mountpoint = part.format.mountpoint - except AttributeError: - pass - self.lb.append([" %s" % part.name, - mountpoint, - type, - "%dM" % part.size,], - part, - [LEFT, LEFT, LEFT, RIGHT]) - - def makeFileSystemList(self, device): - grid = Grid(1, 2) - - label = Label(_("File System type:")) - grid.setField(label, 0, 0) - - fstype = Listbox(height=4, scroll=1) - for fs in sorted(formats.device_formats.values()): - if not fs.supported: - continue - if fs.formattable: - fstype.append(fs._type, fs) - # XXX select default - #current = formats.device_formats[formats.get_default_filesystem_type()] - #print current - #fstype.setCurrent(current) - ### XXX Callback - grid.setField(fstype, 0, 1) - return (grid, fstype) - - def makeDriveList(self, device): - grid = Grid(1, 2) - - label = Label(_("Allowable Drives:")) - grid.setField(label, 0, 0) - - drivelist = CheckboxTree(height=4, scroll=1) - for disk in self.storage.disks: - drivelist.append(disk.name) - grid.setField(drivelist, 0, 1) - return (grid, drivelist) - - def makeMountPoint(self, device): - grid = Grid(2, 1) - label = Label(_("Mount Point:")) - grid.setField(label, 0, 0, (0,0,0,0), anchorLeft = 1) - - try: - mountpoint = device.format.mountpoint - except AttributeError: - mountpoint = "" - mount = Entry(20, mountpoint) - - grid.setField(mount, 1, 0, anchorRight = 1, growx = 1) - - return (grid, mount) - - def makeVGName(self, device): - grid = Grid(2, 1) - label = Label(_("VG Name:")) - grid.setField(label, 0, 0, (0,0,0,0), anchorLeft = 1) - name = Entry(20, device.name) - grid.setField(name, 1, 0, anchorRight = 1, growx = 1) - return (grid, name) - - def newCb(self): - choices = [_("Partition"), _("RAID"), _("Logical Volume Group")] - - if self.storage.vgs: - choices.append(_("Logical Volume Device")) - - (button, choice) = ListboxChoiceWindow(self.installer.intf.screen, - _("New device"), - _("Which type of device do you want to create?\n\n"), - choices, buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], - width = 35, height = len(choices)) - - if button == TEXT_BACK_CHECK: - return - - choice = choices[choice] - if choice == _("Partition"): - self.newPart() - elif choice == _("RAID"): - pass # XXX self.newRaid() - elif choice == _("Logical Volume Group"): - self.newVG() - elif choice == _("Logical Volume Device"): - self.newLV() - - def newPart(self): - disks = [] - for disk in self.storage.disks: - disks.append(("%s - %s" % (disk.name, disk.model,), disk,)) - - (button, disk) = ListboxChoiceWindow(self.installer.intf.screen, - _("Disk Selection"), - _("Choose the disk you want create the new " - "partition on."), - disks, buttons = [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON], - height=len(disks)) - if button == TEXT_CANCEL_CHECK: - return - - device = self.storage.newPartition(parents=disk) - self.editPart(device=device) - - def newVG(self): - device = self.storage.newVG() - self.storage.createDevice(device) - self.editVG(device=device) - - def newLV(self): - vg = logicalVolumeGroupList(self.installer) - if vg: - device = self.storage.newLV(vg=vg) - self.editLV(device=device) - - def editPart(self, device): - if not device: - return - - row = 0 - actions = [] - - if not device.exists: - tstr = _("Add Partition") - else: - tstr = _("Edit Partition") - grid = GridForm(self.screen, tstr, 1, 6) - - if device.exists: - if device.format.exists and getattr(device.format, "label", None): - lbl = Label("%s %s" % (_("Original File System Label:"), device.format.label)) - grid.add(lbl, 0, row) - row += 1 - - (mountgrid, mountpoint) = self.makeMountPoint(device) - grid.add(mountgrid, 0, row) - row += 1 - - if not device.exists: - subgrid1 = Grid(2, 1) - - (fsgrid, fstype) = self.makeFileSystemList(device) - subgrid1.setField(fsgrid, 0, 0) - - #(devgrid, drivelist) = self.makeDriveList(device) - #subgrid1.setField(devgrid, 0, 0) - - #(fsgrid, fstype) = self.makeFileSystemList(device) - #subgrid1.setField(fsgrid, 1, 0, (1,0,0,0), growx=1) - - grid.add(subgrid1, 0, row, (0,1,0,0), growx=1) - row += 1 - else: - pass - - bb = ButtonBar(self.screen, (TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON)) - grid.add(bb, 0, row, (0,1,0,0), growx = 1) - row += 1 - - while 1: - rc = grid.run() - button = bb.buttonPressed(rc) - - if button == TEXT_CANCEL_CHECK: - break - - if mountpoint.value() and not mountpoint.value().startswith("/"): - self.installer.intf.messageWindow(_("Error"), - _("Mountpoint must be an absolute path.")) - continue - - if device.format: - device.format.mountpoint = mountpoint.value() - - if not device.exists: - actions.append(ActionCreateDevice(self.installer, device)) - - break - - self.screen.popWindow() - return actions - - def editVG(self, device): - if not device.exists: - tstr = _("Add Logical Volume Group") - else: - tstr = _("Edit Logical Volume Group") - grid = GridForm(self.screen, tstr, 1, 6) - row = 0 - - (namegrid, name) = self.makeVGName(device) - grid.add(namegrid, 0, row) - row += 1 - - # XXX size? - - bb = ButtonBar(self.screen, (TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON)) - grid.add(bb, 0, row, (0,1,0,0), growx = 1) - row += 1 - - while 1: - rc = grid.run() - button = bb.buttonPressed(rc) - - if button == TEXT_CANCEL_CHECK: - break - - if not name.value(): - self.installer.intf.messageWindow(_("Error"), - _("You must enter a name for the " - "Logical Volume Group.")) - continue - device.name = safeLvmName(name.value()) - - break - - self.screen.popWindow() - - editLV = editPart - - def editCb(self): - device = self.lb.current() - if not device: - self.installer.intf.messageWindow(_("Unable To Edit"), - _("You must first select a partition to edit.")) - return - - reason = self.storage.deviceImmutable(device) - if reason: - self.installer.intf.messageWindow(_("Unable To Edit"), - _("You cannot edit this device:\n\n%s") - % reason,) - return - - actions = None - if device.type == "mdarray": - pass #self.editRaidArray(device) - elif device.type == "lvmvg": - actions = self.editVG(device) - elif device.type == "lvmlv": - actions = self.editLV(device) - elif isinstance(device, storage.devices.PartitionDevice): - actions = self.editPart(device) - - for action in actions: - self.storage.devicetree.registerAction(action) - - def deleteCb(self): - device = self.lb.current() - - if not device: - self.installer.intf.messageWindow(_("Unable To Delete"), - _("You must first select a partition to delete.")) - return - - if device.type == "lvmvg": - text = _("Do you really want to delete the selected Logical Volume Group and " - "all its Logical Volumes?") - else: - text = _("Do you really want to delete the selected partition?") - - if not self.installer.intf.messageWindow(_("Confirm Delete"), text, type="yesno"): - return - - self.storage.destroyDevice(device) - - def __call__(self, installer): - self.installer = installer - self.screen = self.installer.intf.screen - self.storage = self.installer.ds.storage - - self.installer.intf.setHelpline(_("F2-New F3-Edit F4-Delete F5-Reset F12-OK")) - - self.g = GridForm(self.screen, _("Partitioning"), 1, 5) - self.lb = CListbox(height=10, cols=4, - col_widths=[22,14,14,10], - scroll=1, returnExit = 1, - width=70, col_pad=2, - col_labels=[_('Device'), _('Mount Point'), _("Filesystem"), _('Size') ], - col_label_align=[LEFT, LEFT, LEFT, CENTER]) - self.g.add(self.lb, 0, 1) - - self.bb = ButtonBar(self.screen, ((_("New"), "new", "F2"), - (_("Edit"), "edit", "F3"), - (_("Delete"), "delete", "F4"), - TEXT_OK_BUTTON, TEXT_BACK_BUTTON)) - - self.g.add(self.bb, 0, 2, (0, 1, 0, 0)) - self.g.addHotKey("F5") - - while 1: - self.populate() - rc = self.g.run() - button = self.bb.buttonPressed(rc) - - if button == "new": - self.newCb() - elif button == "edit" or rc == self.lb.listbox: # XXX better way? - self.editCb() - elif button == "delete": - self.deleteCb() - elif button == "reset" or rc == "F5": - self.storage.reset() - elif button == TEXT_BACK_CHECK: - self.storage.reset() - - self.screen.popHelpLine() - self.screen.popWindow() - return INSTALL_BACK - else: - #if not self.partitions.getRequestByMountPoint("/"): - # self.intf.messageWindow(_("No Root Partition"), - # _("Installation requires a / partition.")) - # continue - - #(errors, warnings) = self.partitions.sanityCheckAllRequests(self.diskset) - #rc = partitionSanityErrors(self.intf, errors) - #if rc != 1: - # continue - - #rc = partitionSanityWarnings(self.intf, warnings) - #if rc != 1: - # continue - - #warnings = getPreExistFormatWarnings(self.partitions, - # self.diskset) - #rc = partitionPreExistFormatWarnings(self.intf, warnings) - #if rc != 1: - # continue - - self.screen.popHelpLine() - self.screen.popWindow() - return INSTALL_OK - - return INSTALL_OK diff --git a/pkgs/core/pomona/src/po/Makefile b/pkgs/core/pomona/src/po/Makefile deleted file mode 100644 index f33dfe642..000000000 --- a/pkgs/core/pomona/src/po/Makefile +++ /dev/null @@ -1,58 +0,0 @@ - -include ../Makefile.inc - -POTFILES = ../*.py -NONPOTFILES = ../lang-table - -POS = $(wildcard *.po) -FMTCATALOGS = $(patsubst %.po,%.mo,$(POS)) - -MSGMERGE = msgmerge -v - -all: $(FMTCATALOGS) report - -$(PSNAME).pot: $(POTFILES) $(NONPOTFILES) - xgettext --from-code=UTF-8 --default-domain=pomona \ - --keyword=_ --keyword=N_ $(POTFILES) - cat ../lang-table | cut -f1 | while read line; do echo -e "\n#. generated from lang-table\nmsgid \"$$line\"\nmsgstr \"\""; done >> pomona.po - if cmp -s pomona.po pomona.pot; then \ - rm -f pomona.po; \ - else \ - mv pomona.po pomona.pot; \ - fi - -refresh-po: - for cat in $(POS); do \ - lang=`basename $$cat .po`; \ - if $(MSGMERGE) $$lang.po pomona.pot > $$lang.pot ; then \ - mv -f $$lang.pot $$lang.po ; \ - echo "$(MSGMERGE) of $$lang succeeded" ; \ - else \ - echo "$(MSGMERGE) of $$lang failed" ; \ - rm -f $$lang.pot ; \ - fi \ - done - -update-po: $(PSNAME).pot refresh-po - -install: all - mkdir -p $(INSTALLNLSDIR) - for n in $(FMTCATALOGS); do \ - l=`basename $$n .mo`; \ - $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l; \ - $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l/LC_MESSAGES; \ - $(INSTALL) -m 644 $$n \ - $(INSTALLNLSDIR)/$$l/LC_MESSAGES/pomona.mo; \ - done - -%.mo: %.po - msgfmt --check -o $@ $< - -report: - @for cat in $(POS); do \ - echo -n "$$cat: "; \ - msgfmt -v --statistics -o /dev/null $$cat; \ - done - -clean: - rm -f *.mo missing diff --git a/pkgs/core/pomona/src/po/da.po b/pkgs/core/pomona/src/po/da.po deleted file mode 100644 index 49920d7b0..000000000 --- a/pkgs/core/pomona/src/po/da.po +++ /dev/null @@ -1,2422 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-29 01:02+0100\n" -"PO-Revision-Date: \n" -"Last-Translator: Henrik Bro Larsen \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../autopart.py:751 -#, python-format -msgid "" -"Could not allocate cylinder-based partitions as primary partitions.\n" -"\n" -"%s" -msgstr "" -"Kunne ikke allokere cylinder-baserede partitioner som primære partitioner.\n" -"\n" -"%s" - -#: ../autopart.py:756 -#, python-format -msgid "" -"Could not allocate partitions as primary partitions.\n" -"\n" -"%s" -msgstr "" -"Kunne ikke allokere partitioner som primære partitioner.\n" -"\n" -"%s" - -#: ../autopart.py:761 -#, python-format -msgid "" -"Could not allocate cylinder-based partitions.\n" -"\n" -"%s" -msgstr "" -"Kunne ikke allokere cylinder-baserede partitioner.\n" -"\n" -"%s" - -#: ../autopart.py:800 -#, python-format -msgid "" -"Boot partition %s doesn't belong to a BSD disk label. SRM won't be able to " -"boot from this partition. Use a partition belonging to a BSD disk label or " -"change this device disk label to BSD." -msgstr "" -"Opstartspartitionen %s tilhører ikke en BSD-disk-etikette. SRM vil ikke " -"kunne starte fra denne partition. Brug en partition som tilhører en BSD-disk-" -"etikette eller ændr denne enhedsdisk-etikette til BSD." - -#: ../autopart.py:802 -#, python-format -msgid "" -"Boot partition %s doesn't belong to a disk with enough free space at its " -"beginning for the bootloader to live on. Make sure that there's at least 5MB " -"of free space at the beginning of the disk that contains /boot" -msgstr "" -"Startpartitionen %s tilhører ikke en disk med tilstrækkeligt meget ledigt " -"plads ved dets begyndelse som startprogrammet kan være på. Forsikr dig om at " -"der findes 5 MB ledigt plads ved begyndelsen af disken som indeholder /boot" - -#: ../autopart.py:804 -#, python-format -msgid "" -"Boot partition %s isn't a VFAT partition. EFI won't be able to boot from " -"this partition." -msgstr "" -"Startpartitionen %s er ikke en VFAT-partition. EFI vil ikke kunne starte fra " -"denne partition." - -#: ../autopart.py:806 -msgid "" -"The boot partition must entirely be in the first 4GB of the disk. " -"OpenFirmware won't be able to boot this installation." -msgstr "" -"Startpartitionen skal være placeret fuldtud inden for de første 4 GB på " -"disken. OpenFirmware vil ikke kunne opstarte denne installation." - -#: ../autopart.py:813 -#, python-format -msgid "" -"Boot partition %s may not meet booting constraints for your architecture." -msgstr "" -"Opstartspartition %s opfylder muligvis ikke opstartsbegrænsningene for din " -"maskinarkitektur. " - -#: ../autopart.py:951 -msgid "Requested Partition Does Not Exist" -msgstr "Forespurgt partition eksisterer ikke" - -#: ../autopart.py:952 -#, python-format -msgid "" -"Unable to locate partition %s to use for %s.\n" -"\n" -"Press 'OK' to reboot your system." -msgstr "" -"Kan ikke finde partition %s som skal bruges til %s.\n" -"\n" -"Tryk O.k. for at genstarte systemet." - -#: ../autopart.py:997 ../autopart.py:1029 -msgid "Automatic Partitioning Errors" -msgstr "Fejl ved automatisk partitionering" - -#: ../autopart.py:998 -#, python-format -msgid "" -"The following errors occurred with your partitioning:\n" -"\n" -"%s\n" -"\n" -"Press 'OK' to reboot your system." -msgstr "" -"Følgende fejl opstod under din partitionering:\n" -"\n" -"%s\n" -"\n" -"Tryk O.k. for at genstarte systemet." - -#: ../autopart.py:1007 -msgid "Warnings During Automatic Partitioning" -msgstr "Advarsler under automatisk partitionering" - -#: ../autopart.py:1008 -#, python-format -msgid "" -"Following warnings occurred during automatic partitioning:\n" -"\n" -"%s" -msgstr "" -"Følgende advarsler opstod under automatisk partitionering:\n" -"\n" -"%s" - -#: ../autopart.py:1016 ../tui_partition.py:177 -msgid "Error Partitioning" -msgstr "Fejl under partitionering" - -#: ../autopart.py:1017 -#, python-format -msgid "" -"Could not allocate requested partitions: \n" -"\n" -"%s." -msgstr "" -"Kunne ikke allokere forespurgte partitioner: \n" -"\n" -"%s." - -#: ../autopart.py:1027 -msgid "" -"\n" -"\n" -"Press 'OK' to choose a different partitioning option." -msgstr "" -"\n" -"\n" -"Tryk 'O.k.' for at vælge en anden partitioneringsoption." - -#: ../autopart.py:1030 -#, python-format -msgid "" -"The following errors occurred with your partitioning:\n" -"\n" -"%s\n" -"\n" -"This can happen if there is not enough space on your hard drive(s) for the " -"installation. %s" -msgstr "" -"De følgende fejl opstod med din partitionering:\n" -"\n" -"%s\n" -"\n" -"Dette kan ske hvis der ikke findes tilstrækkeligt med plads til " -"installationen på dine diske. %s" - -#: ../autopart.py:1105 ../bootloader.py:745 ../partedUtils.py:230 -#: ../partedUtils.py:531 ../partedUtils.py:568 ../tui_bootloader.py:119 -#: ../tui_bootloader.py:439 ../tui_partition.py:182 -msgid "Warning" -msgstr "Advarsel" - -#: ../autopart.py:1126 -msgid "" -"Automatic Partitioning sets partitions based on the selected installation " -"type. You also can customize the partitions once they have been created.\n" -"\n" -"The manual disk partitioning tool, Disk Druid, allows you to create " -"partitions in an interactive environment. You can set the file system types, " -"mount points, partition sizes, and more." -msgstr "" -"Automatisk partitionering opsætter partitioner baseret på den valgte " -"installationstype. Du kan også tilpasse partitionerne efter at de er blevet " -"oprettet.\n" -"\n" -"Værktøjet for manuel partitionering, Disk Druid, lader dig opsætte dine " -"partitioner i et interaktivt miljø. Du kan sætte filsystemtyper, " -"monteringspunkter, størrelse på partitioner med mere." - -#: ../autopart.py:1137 -msgid "" -"Before automatic partitioning can be set up by the installation program, you " -"must choose how to use the space on your hard drives." -msgstr "" -"Før automatisk partitionering kan sættes op af installationsprogrammet skal " -"du vælge hvordan pladsen på harddiskene skal bruges." - -#: ../autopart.py:1142 -msgid "Remove all partitions on this system" -msgstr "Fjern alle partitioner på dette system" - -#: ../autopart.py:1144 -#, python-format -msgid "" -"You have chosen to remove all partitions (ALL DATA) on the following drives:%" -"s\n" -"Are you sure you want to do this?" -msgstr "" -"Du har valgt at fjerne alle partitioner (ALLE DATA) på de følgende drev:%s\n" -"Er du sikker på at du vil gøre dette?" - -#: ../bootloader.py:696 -msgid "Bootloader" -msgstr "Opstartsindlæser" - -#: ../bootloader.py:696 -msgid "Installing bootloader..." -msgstr "Installerer bootloader..." - -#: ../bootloader.py:746 -msgid "" -"No kernel packages were installed on your system. Your boot loader " -"configuration will not be changed." -msgstr "" -"Ingen kernel pakker blev installeret på dit system. Konfigurationen af din " -"boot loader vil ikke blive ændret." - -#: ../constants.py:41 -#, python-format -msgid "" -"An unhandled exception has occurred. This is most likely a bug. Please " -"save a copy of the detailed exception and file a bug report against pomona " -"at %s" -msgstr "" -"En ubehandlet hændelse er sket. Dette er sandsynligvis en fejl. Kopiér den " -"fulde tekst fra denne undtagelse, og udfyld så en fejlrapport om pomona på %s" - -#: ../constants.py:83 ../installer.py:93 ../tui_confirm.py:28 -#: ../tui_network.py:65 ../tui_network.py:74 ../tui.py:224 ../tui.py:390 -msgid "OK" -msgstr "O.k." - -#: ../constants.py:87 ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 -#: ../tui_bootloader.py:194 ../tui.py:103 ../tui.py:104 ../tui.py:393 -msgid "Cancel" -msgstr "Annullér" - -#: ../constants.py:91 ../tui_confirm.py:28 ../tui_confirm.py:30 -msgid "Back" -msgstr "Tilbage" - -#: ../constants.py:95 ../tui_bootloader.py:67 ../tui.py:388 -msgid "Yes" -msgstr "Ja" - -#: ../constants.py:99 ../tui_bootloader.py:67 ../tui.py:389 -msgid "No" -msgstr "Nej" - -#: ../constants.py:103 ../tui_bootloader.py:270 ../tui_partition.py:849 -msgid "Edit" -msgstr "Redigér" - -#: ../fsset.py:422 -msgid "Checking" -msgstr "" - -#: ../fsset.py:423 -#, fuzzy, python-format -msgid "Checking filesystem on %s..." -msgstr "Kontrollerer for dårlige blokke på /dev/%s..." - -#: ../fsset.py:434 -msgid "Resizing" -msgstr "" - -#: ../fsset.py:435 -#, fuzzy, python-format -msgid "Resizing filesystem on %s..." -msgstr "Formaterer %s-filsystem..." - -#: ../fsset.py:578 ../fsset.py:1112 ../fsset.py:1143 ../fsset.py:1205 -#: ../fsset.py:1216 ../fsset.py:1270 ../fsset.py:1281 ../fsset.py:1303 -#: ../fsset.py:1352 ../fsset.py:1433 ../partIntfHelpers.py:289 -msgid "Error" -msgstr "Fejl" - -#: ../fsset.py:579 -#, python-format -msgid "" -"An error occurred migrating %s to ext3. It is possible to continue without " -"migrating this file system if desired.\n" -"\n" -"Would you like to continue without migrating %s?" -msgstr "" -"En fejl opstod under migrering af %s til ext3. Det er muligt at fortsætte om " -"ønsket uden at migrere filsystemet.\n" -"\n" -"Ønsker du at fortsætte uden at migrere %s?" - -#: ../fsset.py:1046 -msgid "First sector of boot partition" -msgstr "Første sektor på opstartspartitionen" - -#: ../fsset.py:1047 -msgid "Master Boot Record (MBR)" -msgstr "Master Boot Record (MBR)" - -#: ../fsset.py:1113 -#, python-format -msgid "" -"An error occurred trying to initialize swap on device %s. This problem is " -"serious, and the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" -"En fejl opstod under forsøg på at initiere swap på enhed %s. Dette problem " -"er alvorligt, og installationen kan ikke fortsætte.\n" -"\n" -"Tryk for at starte systemet igen." - -#: ../fsset.py:1142 -msgid "Skip" -msgstr "Overspring" - -#: ../fsset.py:1142 ../tui_complete.py:40 -msgid "Reboot" -msgstr "Genstart" - -#: ../fsset.py:1163 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"is a version 0 Linux swap partition. If you want to use this device, you " -"must reformat as a version 1 Linux swap partition. If you skip it, the " -"installer will ignore it during the installation." -msgstr "" -"Swapenheden:\n" -"\n" -" /dev/%s\n" -"\n" -"er en Linuxswappartition af typen version 0. Hvis du vil bruge denne enhed " -"skal du omformatere den til en Linuxswappartition af typen version 1. Hvis " -"du springer over det vil installationsprogrammet overspringe det under " -"installationen." - -#: ../fsset.py:1170 -msgid "Reformat" -msgstr "Omformatér" - -#: ../fsset.py:1174 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"in your /etc/fstab file is currently in use as a software suspend partition, " -"which means your system is hibernating. To perform an upgrade, please shut " -"down your system rather than hibernating it." -msgstr "" -"Swapenheden:\n" -"\n" -" /dev/%s\n" -"\n" -"i din /etc/fstab-fil bruges i øjeblikket som en partition for " -"programsuspendering, hvilket betyder at dit system er i hviletilstand. For " -"at lave en opgradering bør du lukke dit system ned i stedet for at sætte det " -"i hviletilstand." - -#: ../fsset.py:1182 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"in your /etc/fstab file is currently in use as a software suspend partition, " -"which means your system is hibernating. If you are performing a new install, " -"make sure the installer is set to format all swap partitions." -msgstr "" -"Swapenheden:\n" -"\n" -" /dev/%s\n" -"\n" -"i din /etc/fstab-fil bruges i øjeblikket som en partition for " -"programsuspendering, det vil sige at dit system er i hviletilstand. Hvis du " -"er i gang med en ny installation bør du se til at installationsprogrammet er " -"sat op til at formatere alle swappartitioner." - -#: ../fsset.py:1192 -msgid "" -"\n" -"\n" -"Choose Skip if you want the installer to ignore this partition during the " -"upgrade. Choose Format to reformat the partition as swap space. Choose " -"Reboot to restart the system." -msgstr "" -"\n" -"\n" -"Vælg overspring hvis du ønsker at installationsprogrammet skal ignorere " -"denne partition under opgraderingen. Vælg Formatér for at genformatere " -"partitionen som swapplads. Vælg Genstart for at genstarte systemet." - -#: ../fsset.py:1198 -msgid "Format" -msgstr "Formatér" - -#: ../fsset.py:1206 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"The /etc/fstab on your upgrade partition does not reference a valid swap " -"partition.\n" -"\n" -"Press OK to reboot your system." -msgstr "" -"Fejl under aktivering af swap-enhed %s: %s\n" -"\n" -"Filen /etc/fstab på din opgraderingspartition henviser ikke til en gyldig " -"swap-partition.\n" -"\n" -"Tryk O.k. for at genstarte systemet." - -#: ../fsset.py:1217 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"This most likely means this swap partition has not been initialized.\n" -"\n" -"Press OK to reboot your system." -msgstr "" -"Fejl under aktivering af swap-enhed %s: %s\n" -"\n" -"Dette betyder sandsynligvis at swap-partitionen ikke er initieret.\n" -"\n" -"Tryk O.k. for at genstarte systemet." - -#: ../fsset.py:1271 -#, python-format -msgid "" -"Bad blocks have been detected on device /dev/%s. We do not recommend you use " -"this device.\n" -"\n" -"Press to reboot your system" -msgstr "" -"Der er fundet dårlige blokke på enhed /dev/%s. Vi anbefaler ikke at du " -"bruger denne enhed.\n" -"\n" -"Tryk for genstarte systemet." - -#: ../fsset.py:1282 -#, python-format -msgid "" -"An error occurred searching for bad blocks on %s. This problem is serious, " -"and the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" -"En fejl opstod under søgning efter dårlige blokke på %s. Dette problem er " -"alvorligt, og installationen kan ikke fortsætte.\n" -"\n" -"Tryk for at genstarte systemet." - -#: ../fsset.py:1304 -#, python-format -msgid "" -"An error occurred trying to format %s. This problem is serious, and the " -"install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" -"Der opstod en fejl ved forsøg på formatering af %s. Dette problem er så " -"alvorligt, at installationen ikke kan fortsætte.\n" -"\n" -"Tryk på return for at genstarte systemet." - -#: ../fsset.py:1353 -#, python-format -msgid "" -"An error occurred trying to migrate %s. This problem is serious, and the " -"install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" -"Der opstod en fejl ved migrering af %s. Dette problem er så alvorligt, at " -"installationen ikke kan fortsætte.\n" -"\n" -"Tryk på return for at genstarte systemet." - -#: ../fsset.py:1380 ../fsset.py:1389 -msgid "Invalid mount point" -msgstr "Ugyldigt monteringspunkt" - -#: ../fsset.py:1381 -#, python-format -msgid "" -"An error occurred when trying to create %s. Some element of this path is " -"not a directory. This is a fatal error and the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" -"Der opstod en fejl ved forsøg på oprettelse af %s. Elementer af denne sti er " -"ikke et katalog. Dette problem er så alvorligt, at installationen ikke kan " -"fortsætte.\n" -"\n" -"Tryk på return for at genstarte systemet." - -#: ../fsset.py:1390 -#, python-format -msgid "" -"An error occurred when trying to create %s: %s. This is a fatal error and " -"the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" -"Der opstod en fejl ved forsøg på oprettelse af %s: %s. Dette problem er så " -"alvorligt, at installationen ikke kan fortsætte.\n" -"\n" -"Tryk på return for at genstarte systemet." - -#: ../fsset.py:1403 -msgid "Unable to mount filesystem" -msgstr "Kan ikke montere filsystem" - -#: ../fsset.py:1404 -#, python-format -msgid "" -"An error occurred mounting device %s as %s. You may continue installation, " -"but there may be problems." -msgstr "" -"Et fejl skete ved montering af enhed %s som %s. Du kan fortsætte " -"installationen men det kan opstå problemer." - -#: ../fsset.py:1411 ../fsset.py:1820 ../fsset.py:1827 ../packages.py:131 -#: ../partedUtils.py:578 ../tui_confirm.py:37 -msgid "_Reboot" -msgstr "_Genstart" - -#: ../fsset.py:1411 ../partedUtils.py:578 -msgid "_Continue" -msgstr "_Fortsæt" - -#: ../fsset.py:1419 -#, python-format -msgid "" -"Error mounting device %s as %s: %s\n" -"\n" -"Devices in /etc/fstab should be specified by label, not by device name.\n" -"\n" -"Press OK to reboot your system." -msgstr "" -"Fejl ved montering af enhed %s som %s: %s\n" -"\n" -"Enheder i /etc/fstab bør angives ved label, ikke ved enhedsnavn.\n" -"\n" -"Tryk O.k. for at genstarte, dit system." - -#: ../fsset.py:1426 -#, python-format -msgid "" -"Error mounting device %s as %s: %s\n" -"\n" -"This most likely means this partition has not been formatted.\n" -"\n" -"Press OK to reboot your system." -msgstr "" -"Fejl ved montering af enhed %s som %s: %s\n" -"\n" -"Dette betyder højst sandsynligt at denne partition ikke er blevet " -"formateret.\n" -"\n" -"Tryk O.k. for at genstarte dit system." - -#: ../fsset.py:1812 -msgid "Duplicate Labels" -msgstr "Doppelte etiketter" - -#: ../fsset.py:1813 -#, python-format -msgid "" -"Multiple devices on your system are labelled %s. Labels across devices must " -"be unique for your system to function properly.\n" -"\n" -"Please fix this problem and restart the installation process." -msgstr "" -"Flere enheder på dit system er benævnt %s. Etiketter skal være unikke for " -"hver enhed på dit system for at fungere rigtigt.\n" -"\n" -"Ret dette problem og genstart installationsprocessen." - -#: ../fsset.py:1822 -msgid "Invalid Label" -msgstr "Ugyldig etikette" - -#: ../fsset.py:1823 -#, python-format -msgid "" -"An invalid label was found on device %s. Please fix this problem and " -"restart the installation process." -msgstr "" -"En ugyldig etikette blev fundet på enhed %s. Ret dette problem og genstart " -"installationsprocessen." - -#: ../fsset.py:2049 -msgid "Formatting" -msgstr "Formaterer" - -#: ../fsset.py:2050 -#, python-format -msgid "Formatting %s file system..." -msgstr "Formaterer %s-filsystem..." - -#: ../installer.py:88 -msgid "Fatal Error" -msgstr "Alvorlig fejl" - -#: ../installer.py:89 -#, python-format -msgid "" -"You do not have enough RAM to install %s on this machine.\n" -"\n" -"Press to reboot your system.\n" -msgstr "" -"Du har ikke RAM nok til at installere %s på denne maskine.\n" -"Tast for at genstarte systemet.\n" - -#: ../installer.py:173 -msgid "Starting text installation..." -msgstr "Starter text-baseret installation..." - -#: ../keyboard_models.py:48 -msgid "keyboard|Arabic (azerty)" -msgstr "tastatur|Arabisk (azerty)" - -#: ../keyboard_models.py:51 -msgid "keyboard|Arabic (azerty/digits)" -msgstr "tastatur|Arabisk (azerty/numerisk tastatur)" - -#: ../keyboard_models.py:54 -msgid "keyboard|Arabic (digits)" -msgstr "tastatur|Arabisk (numerisk tastatur)" - -#: ../keyboard_models.py:57 -msgid "keyboard|Arabic (qwerty)" -msgstr "tastatur|Arabisk (qwerty)" - -#: ../keyboard_models.py:60 -msgid "keyboard|Arabic (qwerty/digits)" -msgstr "tastatur|arabisk (qwerty/numerisk tastatur)" - -#: ../keyboard_models.py:63 -msgid "keyboard|Belgian (be-latin1)" -msgstr "tastatur|Belgisk (be-latin1)" - -#: ../keyboard_models.py:66 -msgid "keyboard|Bengali (Inscript)" -msgstr "tastatur|Bengalsk (Inscript)" - -#: ../keyboard_models.py:69 -msgid "keyboard|Bengali (Probhat)" -msgstr "tastatur|Bengalsk (Probhat)" - -#: ../keyboard_models.py:72 -msgid "keyboard|Bulgarian" -msgstr "tastatur|Bulgarsk" - -#: ../keyboard_models.py:75 -msgid "keyboard|Bulgarian (Phonetic)" -msgstr "tastatur|Bulgarsk (phonetisk)" - -#: ../keyboard_models.py:78 -msgid "keyboard|Brazilian (ABNT2)" -msgstr "tastatur|Brasiliansk (ABNT2)" - -#: ../keyboard_models.py:81 -msgid "keyboard|French Canadian" -msgstr "tastatur|fransk kanadisk" - -#: ../keyboard_models.py:84 -msgid "keyboard|Croatian" -msgstr "tastatur|Kroatisk" - -#: ../keyboard_models.py:87 -msgid "keyboard|Czech" -msgstr "tastatur|Tjekkisk" - -#: ../keyboard_models.py:90 -msgid "keyboard|Czech (qwerty)" -msgstr "tastatur|Tjekkisk (qwerty)" - -#: ../keyboard_models.py:93 -msgid "keyboard|German" -msgstr "tastatur|Tysk" - -#: ../keyboard_models.py:96 -msgid "keyboard|German (latin1)" -msgstr "tastatur|Tysk (latin1)" - -#: ../keyboard_models.py:99 -msgid "keyboard|German (latin1 w/ no deadkeys)" -msgstr "tastatur|Tysk (latin1 uden døde taster)" - -#: ../keyboard_models.py:102 -msgid "keyboard|Devanagari (Inscript)" -msgstr "tastatur|Devanagarisk (Inscript)" - -#: ../keyboard_models.py:105 -msgid "keyboard|Dvorak" -msgstr "tastatur|Dvorak" - -#: ../keyboard_models.py:108 -msgid "keyboard|Danish" -msgstr "tastatur|Dansk" - -#: ../keyboard_models.py:111 -msgid "keyboard|Danish (latin1)" -msgstr "tastatur|Dansk (latin1)" - -#: ../keyboard_models.py:114 -msgid "keyboard|Spanish" -msgstr "tastatur|Spansk" - -#: ../keyboard_models.py:117 -msgid "keyboard|Estonian" -msgstr "tastatur|Estisk" - -#: ../keyboard_models.py:120 -msgid "keyboard|Finnish" -msgstr "tastatur|Finsk" - -#: ../keyboard_models.py:123 -msgid "keyboard|Finnish (latin1)" -msgstr "tastatur|Finsk (latin1)" - -#: ../keyboard_models.py:126 -msgid "keyboard|French" -msgstr "tastatur|Fransk" - -#: ../keyboard_models.py:129 -msgid "keyboard|French (latin9)" -msgstr "tastatur|Fransk (latin9)" - -#: ../keyboard_models.py:132 -msgid "keyboard|French (latin1)" -msgstr "tastatur|Fransk (latin1)" - -#: ../keyboard_models.py:135 -msgid "keyboard|French (pc)" -msgstr "tastatur|Fransk (pc)" - -#: ../keyboard_models.py:138 -msgid "keyboard|Swiss French" -msgstr "tastatur|Svejtsisk-fransk" - -#: ../keyboard_models.py:141 -msgid "keyboard|Swiss French (latin1)" -msgstr "tastatur|Svejtsisk-fransk (latin1)" - -#: ../keyboard_models.py:144 -msgid "keyboard|Greek" -msgstr "tastatur|græsk" - -#: ../keyboard_models.py:147 -#, fuzzy -msgid "keyboard|Gujarati (Inscript)" -msgstr "tastatur|Punjabi (Inscript)" - -#: ../keyboard_models.py:150 -msgid "keyboard|Punjabi (Inscript)" -msgstr "tastatur|Punjabi (Inscript)" - -#: ../keyboard_models.py:153 -msgid "keyboard|Hungarian" -msgstr "tastatur|Ungarsk" - -#: ../keyboard_models.py:156 -msgid "keyboard|Hungarian (101 key)" -msgstr "tastatur|Ungarsk (101 taster)" - -#: ../keyboard_models.py:159 -msgid "keyboard|Icelandic" -msgstr "tastatur|Islandsk" - -#: ../keyboard_models.py:162 -msgid "keyboard|Italian" -msgstr "tastatur|Italiensk" - -#: ../keyboard_models.py:165 -msgid "keyboard|Italian (IBM)" -msgstr "tastatur|Italiensk (IBM)" - -#: ../keyboard_models.py:168 -msgid "keyboard|Italian (it2)" -msgstr "tastatur|Italiensk (it2)" - -#: ../keyboard_models.py:171 -msgid "keyboard|Japanese" -msgstr "tastatur|Japansk" - -#: ../keyboard_models.py:174 -msgid "keyboard|Korean" -msgstr "tastatur|Koreansk" - -#: ../keyboard_models.py:177 -msgid "keyboard|Latin American" -msgstr "tastatur|latinamerika" - -#: ../keyboard_models.py:180 -msgid "keyboard|Macedonian" -msgstr "tastatur|Makedonsk" - -#: ../keyboard_models.py:183 -msgid "keyboard|Dutch" -msgstr "tastatur|Hollandsk" - -#: ../keyboard_models.py:186 -msgid "keyboard|Norwegian" -msgstr "tastatur|Norsk" - -#: ../keyboard_models.py:189 -msgid "keyboard|Polish" -msgstr "tastatur|Polsk" - -#: ../keyboard_models.py:192 -msgid "keyboard|Portuguese" -msgstr "tastatur|Portugisisk" - -#: ../keyboard_models.py:195 -msgid "keyboard|Romanian" -msgstr "tastatur|Rumænsk" - -#: ../keyboard_models.py:198 -msgid "keyboard|Russian" -msgstr "tastatur|Russisk" - -#: ../keyboard_models.py:201 -msgid "keyboard|Serbian" -msgstr "tastatur|Serbisk" - -#: ../keyboard_models.py:204 -msgid "keyboard|Serbian (latin)" -msgstr "tastatur|Serbisk (Latinsk)" - -#: ../keyboard_models.py:207 -msgid "keyboard|Swedish" -msgstr "tastatur|Svensk" - -#: ../keyboard_models.py:210 -msgid "keyboard|Swiss German" -msgstr "tastatur|Svejtsisk-tysk" - -#: ../keyboard_models.py:213 -msgid "keyboard|Swiss German (latin1)" -msgstr "tastatur|Svejtsisk-tysk (latin1)" - -#: ../keyboard_models.py:216 -msgid "keyboard|Slovak (qwerty)" -msgstr "tastatur|Slovakisk (qwerty)" - -#: ../keyboard_models.py:219 -msgid "keyboard|Slovenian" -msgstr "tastatur||Slovensk" - -#: ../keyboard_models.py:222 -msgid "keyboard|Tamil (Inscript)" -msgstr "tastatur|Tamilsk (Inscript)" - -#: ../keyboard_models.py:225 -msgid "keyboard|Tamil (Typewriter)" -msgstr "tastatur|tamil (typewriter)" - -#: ../keyboard_models.py:228 -msgid "keyboard|Turkish" -msgstr "tastatur|tyrkisk" - -#: ../keyboard_models.py:231 -msgid "keyboard|United Kingdom" -msgstr "tastatur|United Kingdom" - -#: ../keyboard_models.py:234 -msgid "keyboard|Ukrainian" -msgstr "tastatur|Ukrainsk" - -#: ../keyboard_models.py:237 -msgid "keyboard|U.S. International" -msgstr "tastatur|U.S. international" - -#: ../keyboard_models.py:240 -msgid "keyboard|U.S. English" -msgstr "tastatur|U.S. Engelsk" - -#: ../network.py:31 -msgid "IP address is missing." -msgstr "" - -#: ../network.py:35 -msgid "" -"IPv4 addresses must contain four numbers between 0 and 255, separated by " -"periods." -msgstr "" - -#: ../network.py:38 -#, python-format -msgid "'%s' is not a valid IPv6 address." -msgstr "" - -#: ../network.py:40 -#, python-format -msgid "'%s' is an invalid IP address." -msgstr "" - -#: ../network.py:52 -msgid "Hostname must be 255 or fewer characters in length." -msgstr "" - -#: ../network.py:58 -msgid "" -"Hostname must start with a valid character in the ranges 'a-z', 'A-Z', or '0-" -"9'" -msgstr "" - -#: ../network.py:63 -msgid "" -"Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'" -msgstr "" - -#: ../packages.py:113 -msgid "Warning! This is pre-release software!" -msgstr "Advarsel! Dette er ikke færdigaftestet programmel!" - -#: ../packages.py:114 -#, python-format -msgid "" -"Thank you for downloading this pre-release of %s.\n" -"\n" -"This is not a final release and is not intended for use on production " -"systems. The purpose of this release is to collect feedback from testers, " -"and it is not suitable for day to day usage.\n" -"\n" -"To report feedback, please visit:\n" -"\n" -" %s\n" -"\n" -"and file a report against '%s'.\n" -msgstr "" -"Tak for at du har hentet denne tidlige udgave af %s.\n" -"\n" -"Dette er ikke den endelige udgave og den er ikke ment til brug på systemer i " -"produktion. Formålet med denne udgave er at indsamle tilbagemeldinger fra " -"testere, og den er ikke velegnet til daglig brug.\n" -"\n" -"For at indsende tilbagemeldinger skal du besøge:\n" -"\n" -" %s\n" -"\n" -"og udfylde en fejlrapport om '%s'.\n" - -#: ../packages.py:127 -msgid "_Exit" -msgstr "_Afslut" - -#: ../packages.py:127 -msgid "_Install anyway" -msgstr "_Installér alligevel" - -#: ../packages.py:130 -msgid "Your system will now be rebooted..." -msgstr "Dit system vil nu blive genstartet.." - -#: ../packages.py:131 ../tui_confirm.py:37 -msgid "_Back" -msgstr "_Tilbage" - -#: ../packages.py:132 -msgid "Rebooting System" -msgstr "Genstarter system" - -#: ../pakfireinstall.py:47 -#, python-format -msgid "%s MB" -msgstr "%s MB" - -#: ../pakfireinstall.py:50 -#, python-format -msgid "%s KB" -msgstr "%s kB" - -#: ../pakfireinstall.py:53 -#, python-format -msgid "%s Byte" -msgstr "%s byte" - -#: ../pakfireinstall.py:55 -#, python-format -msgid "%s Bytes" -msgstr "%s byte" - -#: ../pakfireinstall.py:134 -msgid "Base system" -msgstr "Basis system" - -#: ../pakfireinstall.py:134 -msgid "Installing base system..." -msgstr "Installerer basis systemet..." - -#: ../pakfireinstall.py:171 -msgid "Install Starting" -msgstr "Installationen starter" - -#: ../pakfireinstall.py:172 -msgid "Starting install process. This may take several minutes..." -msgstr "Starter installationsproces. Dette kan tage op til flere minutter..." - -#: ../pakfireinstall.py:183 -msgid "Post Install" -msgstr "Efter installation" - -#: ../pakfireinstall.py:184 -msgid "Performing post install configuration..." -msgstr "Konfigurerer systemet efter installation..." - -#: ../pakfireinstall.py:215 -msgid "Symmetric multiprocessing" -msgstr "Symmetrisk multiprocessing" - -#: ../pakfireinstall.py:216 -msgid "Xen guest" -msgstr "Xen gæst" - -#: ../pakfireinstall.py:226 -msgid "Normal Boot" -msgstr "Normal opstart" - -#: ../pakfireinstall.py:233 -msgid "Installation Progress" -msgstr "Installationsfremskridt" - -#: ../partedUtils.py:191 ../tui_partition.py:408 -msgid "Foreign" -msgstr "Fremmed" - -#: ../partedUtils.py:231 -#, python-format -msgid "" -"/dev/%s currently has a %s partition layout. To use this drive for the " -"installation of %s, it must be re-initialized, causing the loss of ALL DATA " -"on this drive.\n" -"\n" -"Would you like to re-initialize this drive?" -msgstr "" -"/dev/%s har i øjeblikket et %s partitions layout. For at bruge dette " -"diskdrev til installationen af %s, skal den først re-initialiseres, hvilket " -"medfører tab af ALLE DATA på dette diskdrev.\n" -"\n" -"Ønsker du at re-initiere dette diskdrev?" - -#: ../partedUtils.py:239 -msgid "_Ignore drive" -msgstr "Ignorér drev" - -#: ../partedUtils.py:240 -msgid "_Re-initialize drive" -msgstr "_Re-initialisér diskdrev" - -#: ../partedUtils.py:532 -#, python-format -msgid "" -"The partition table on device %s was unreadable. To create new partitions it " -"must be initialized, causing the loss of ALL DATA on this drive.\n" -"\n" -"This operation will override any previous installation choices about which " -"drives to ignore.\n" -"\n" -"Would you like to initialize this drive, erasing ALL DATA?" -msgstr "" -"Partitionstabellen på enhed %s er ulæselig. For at oprette nye partitioner " -"skal den initieres, hvilket vil ødelægge ALLE DATA på denne enhed.\n" -"\n" -"Denne handling vil tilsidesætte alle tidligere valg under installationen om " -"hvilke enheder der skal ignoreres.\n" -"\n" -"Vil du initiere denne enhed og fjerne ALLE DATA?" - -#: ../partedUtils.py:569 -#, python-format -msgid "" -"The drive /dev/%s has more than 15 partitions on it. The SCSI subsystem in " -"the Linux kernel does not allow for more than 15 partitons at this time. " -"You will not be able to make changes to the partitioning of this disk or use " -"any partitions beyond /dev/%s15 in %s" -msgstr "" -"Diskdrevet /dev/%s indeholder mere end 15 partitioner. SCSI-undersystemet i " -"Linux-kernen tillader i øjeblikket ikke mere end 15 partitoner. Du vil " -"ikke kunne lave ændringer af partitioneringen af dette diskdrev eller bruge " -"nogen partitioner ud over /dev/%s15 i %s" - -#: ../partedUtils.py:659 -msgid "No Drives Found" -msgstr "Ingen drev fundet" - -#: ../partedUtils.py:660 -msgid "" -"An error has occurred - no valid devices were found on which to create new " -"file systems. Please check your hardware for the cause of this problem." -msgstr "" -"En fejl er opstået - ingen gyldige enheder blev fundet på hvilke nye " -"filsystemer kunne oprettes. Tjek venligst din maskine for at finde grunden " -"til dette problem." - -#: ../partIntfHelpers.py:50 -#, python-format -msgid "" -"The mount point %s is invalid. Mount points must start with '/' and cannot " -"end with '/', and must contain printable characters and no spaces." -msgstr "" -"Monteringspunktet %s er ugyldigt. Monteringspunkter skal begynde med '/', " -"kan ikke slutte med '/', og skal indeholde udskrivbare tegn og ingen blanke." - -#: ../partIntfHelpers.py:57 -msgid "Please specify a mount point for this partition." -msgstr "Specificér et monteringspunkt for denne partition." - -#: ../partIntfHelpers.py:74 ../partIntfHelpers.py:80 ../partIntfHelpers.py:90 -#: ../partIntfHelpers.py:111 -msgid "Unable To Delete" -msgstr "Kan ikke fjerne" - -#: ../partIntfHelpers.py:75 -msgid "You must first select a partition to delete." -msgstr "Du skal først vælge en partition som skal fjernes." - -#: ../partIntfHelpers.py:81 -msgid "You cannot delete free space." -msgstr "Du kan ikke fjerne ledig plads." - -#: ../partIntfHelpers.py:91 -#, python-format -msgid "" -"You cannot delete this partition, as it is an extended partition which " -"contains %s" -msgstr "" -"Du kan ikke slette denne partition, da den er en udvidet partition som " -"indeholder %s" - -#: ../partIntfHelpers.py:106 -msgid "This partition is holding the data for the hard drive install." -msgstr "Denne partition indeholder data for harddiskinstallationen." - -#: ../partIntfHelpers.py:112 -msgid "" -"You cannot delete this partition:\n" -"\n" -msgstr "" -"Du kan ikke slette denne partition:\n" -"\n" - -#: ../partIntfHelpers.py:146 ../partIntfHelpers.py:391 -msgid "Confirm Delete" -msgstr "Bekræft sletning" - -#: ../partIntfHelpers.py:147 -#, python-format -msgid "You are about to delete all partitions on the device '/dev/%s'." -msgstr "Du er i færd med at slette alle partitioner på enheden /dev/%s." - -#: ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 -msgid "_Delete" -msgstr "_Slet" - -#: ../partIntfHelpers.py:206 -msgid "Notice" -msgstr "Bemærk" - -#: ../partIntfHelpers.py:207 -#, python-format -msgid "" -"The following partitions were not deleted because they are in use:\n" -"\n" -"%s" -msgstr "" -"Følgende partitioner blev ikke fjernet da de er i brug:\n" -"\n" -"%s" - -#: ../partIntfHelpers.py:222 ../partIntfHelpers.py:238 -#: ../partIntfHelpers.py:249 -msgid "Unable To Edit" -msgstr "Kan ikke redigere" - -#: ../partIntfHelpers.py:223 -msgid "You must select a partition to edit" -msgstr "Du skal vælge en partition for redigering" - -#: ../partIntfHelpers.py:239 -#, python-format -msgid "" -"You cannot edit this partition, as it is an extended partition which " -"contains %s" -msgstr "" -"Du kan ikke redigere denne partition, da den er en udvidet partition som " -"indeholder %s" - -#: ../partIntfHelpers.py:250 -msgid "" -"You cannot edit this partition:\n" -"\n" -msgstr "" -"Du kan ikke redigere denne partition:\n" -"\n" - -#: ../partIntfHelpers.py:272 -msgid "Format as Swap?" -msgstr "Formatér som swap?" - -#: ../partIntfHelpers.py:273 -#, python-format -msgid "" -"/dev/%s has a partition type of 0x82 (Linux swap) but does not appear to be " -"formatted as a Linux swap partition.\n" -"\n" -"Would you like to format this partition as a swap partition?" -msgstr "" -"/dev/%s har partitionstype 0x82 (Linux swap), men ser ikke ud til at være " -"formateret som en swappartition.\n" -"\n" -"Ønsker du at formatere denne partition som en swappartition?" - -#: ../partIntfHelpers.py:288 -#, python-format -msgid "You need to select at least one hard drive to install %s." -msgstr "Du skal vælge mindst et drev, som du skal installere %s på." - -#: ../partIntfHelpers.py:293 -msgid "" -"You have chosen to use a pre-existing partition for this installation " -"without formatting it. We recommend that you format this partition to make " -"sure files from a previous operating system installation do not cause " -"problems with this installation of Linux. However, if this partition " -"contains files that you need to keep, such as home directories, then " -"continue without formatting this partition." -msgstr "" -"Du har valgt at bruge en allerede eksisterende partition for denne " -"installation uden at formatere den. Vi anbefaler at du formaterer denne " -"partition for at forsikre dig om at filer fra en tidligere " -"operativsystemsinstallation ikke forårsager problemer med denne installation " -"af Linux. Hvis denne partition indeholder filer som du vil beholde, som fx " -"hjemmekataloger, bør du dog fortsætte uden at formatere denne partition." - -#: ../partIntfHelpers.py:301 -msgid "Format?" -msgstr "Formatér?" - -#: ../partIntfHelpers.py:302 -msgid "_Modify Partition" -msgstr "_Ændre partition" - -#: ../partIntfHelpers.py:302 -msgid "Do _Not Format" -msgstr "Formater _ikke" - -#: ../partIntfHelpers.py:311 -msgid "Error with Partitioning" -msgstr "Fejl under partitionering" - -#: ../partIntfHelpers.py:312 -#, python-format -msgid "" -"The following critical errors exist with your requested partitioning scheme. " -"These errors must be corrected prior to continuing with your install of %s.\n" -"\n" -"%s" -msgstr "" -"Følgende kritiske fejl opstod med dit forespurgte partitionsskema. Disse " -"fejl skal der rettes op på før du fortsætter med installationen af %s.\n" -"\n" -"%s" - -#: ../partIntfHelpers.py:326 -msgid "Partitioning Warning" -msgstr "Advarsel fra partitionering" - -#: ../partIntfHelpers.py:327 -#, python-format -msgid "" -"The following warnings exist with your requested partition scheme.\n" -"\n" -"%s\n" -"\n" -"Would you like to continue with your requested partitioning scheme?" -msgstr "" -"Følgende advarsler opstod med dit partitioneringsoplæg.\n" -"\n" -"%s\n" -"\n" -"Vil du fortsætte med det forespurgte partitioneringsoplæg?" - -#: ../partIntfHelpers.py:340 -msgid "" -"The following pre-existing partitions have been selected to be formatted, " -"destroying all data." -msgstr "" -"Disse eksisterende partitioner er mærket for formatering, som vil ødelægge " -"alle data." - -#: ../partIntfHelpers.py:342 -msgid "" -"Select 'Yes' to continue and format these partitions, or 'No' to go back and " -"change these settings." -msgstr "" -"Vælg 'Ja' for at fortsætte med formatering af disse partitioner, eller 'Nej' " -"for at gå tilbage og ændre disse indstillinger." - -#: ../partIntfHelpers.py:348 -msgid "Format Warning" -msgstr "Formateringsadvarsel" - -#: ../partIntfHelpers.py:387 -#, python-format -msgid "You are about to delete the /dev/%s partition." -msgstr "Du er i færd med at slette partitionen /dev/%s." - -#: ../partIntfHelpers.py:389 -msgid "The partition you selected will be deleted." -msgstr "Partitionen du markerede vil blive fjernet." - -#: ../partIntfHelpers.py:398 -msgid "Confirm Reset" -msgstr "Bekræft nulstilling" - -#: ../partIntfHelpers.py:399 -msgid "" -"Are you sure you want to reset the partition table to its original state?" -msgstr "" -"Er du sikker på at du vil nulstille partitionstabellen til oprindelig " -"tilstand?" - -#: ../partitioning.py:36 -msgid "Installation cannot continue." -msgstr "Installation kan ikke fortsætte." - -#: ../partitioning.py:37 -msgid "" -"The partitioning options you have chosen have already been activated. You " -"can no longer return to the disk editing screen. Would you like to continue " -"with the installation process?" -msgstr "" -"Partitionerings optionerne du har valgt er allerede aktiveret. Du vil ikke " -"kunne gå tilbage til skærmen for redigering af diske. Vil du fortsætte " -"installationsprocessen?" - -#: ../partitioning.py:65 -msgid "Low Memory" -msgstr "Lav hukommelse" - -#: ../partitioning.py:66 -msgid "" -"As you don't have much memory in this machine, we need to turn on swap space " -"immediately. To do this we'll have to write your new partition table to the " -"disk immediately. Is that OK?" -msgstr "" -"Da du ikke har ret megen hukommelse på denne maskine, bliver vi nødt til at " -"starte swap med det samme. For at gøre det er vi nødt at skrive den nye " -"partitionstabel på disken. Er det i orden?" - -#: ../partitions.py:311 -#, python-format -msgid "" -"You have not defined a root partition (/), which is required for " -"installation of %s to continue." -msgstr "" -"Du har ikke defineret en rod-partition (/). Dette skal gøres før " -"installationen af %s kan fortsætte." - -#: ../partitions.py:316 -#, python-format -msgid "" -"Your root partition is less than 250 megabytes which is usually too small to " -"install %s." -msgstr "" -"Din rod-partition er mindre end 250 megabyte og dette er normalt for lidt " -"til at installere %s." - -#: ../partitions.py:333 -msgid "" -"Your boot partition isn't on one of the first four partitions and thus won't " -"be bootable." -msgstr "" -"Din opstarts-partition er ikke en af de fire første partitioner og vil " -"derfor ikke være startbar." - -#: ../partitions.py:342 -#, python-format -msgid "" -"Your %s partition is less than %s megabytes which is lower than recommended " -"for a normal %s install." -msgstr "" -"Din %s-partition er mindre end %s megabyte og dette er lavere end anbefalet " -"for en almindelig installation af %s." - -#: ../partitions.py:374 -msgid "" -"Installing on a USB device. This may or may not produce a working system." -msgstr "" -"Installerer på en USB-enhed. Dette kan give et fungerende system, men det er " -"ikke sikkert." - -#: ../partitions.py:378 -msgid "" -"Installing on a FireWire device. This may or may not produce a working " -"system." -msgstr "" -"Installerer på en FireWire-enhed. Dette kan give et fungerende system, men " -"det er ikke sikkert." - -#: ../partitions.py:391 -msgid "" -"You have not specified a swap partition. Although not strictly required in " -"all cases, it will significantly improve performance for most installations." -msgstr "" -"Du har ikke specificeret en swap-partition. Selv om det ikke er et strengt " -"krav om dette i alle tilfælle, så vil det øge ydelsen for de fleste " -"installationer." - -#: ../partitions.py:398 -#, python-format -msgid "" -"You have specified more than 32 swap devices. The kernel for %s only " -"supports 32 swap devices." -msgstr "" - -#: ../partitions.py:409 -#, python-format -msgid "" -"You have allocated less swap space (%dM) than available RAM (%dM) on your " -"system. This could negatively impact performance." -msgstr "" -"Du har allokeret mindre swap-område (%dM) end tilgængelig RAM (%dM) i dit " -"system. Dette kan have negativ indvirkning på ydelsen." - -#: ../partitions.py:485 -msgid "the partition in use by the installer." -msgstr "partitionen er i brug af installationsprogrammet." - -#: ../partRequests.py:182 -#, python-format -msgid "" -"This mount point is invalid. The %s directory must be on the / file system." -msgstr "" -"Dette monteringspunkt er ugyldigt. Kataloget %s skal ligge på rodfilsystemet." - -#: ../partRequests.py:185 -#, python-format -msgid "" -"The mount point %s cannot be used. It must be a symbolic link for proper " -"system operation. Please select a different mount point." -msgstr "" -"Monteringspunktet %s kan ikke bruges. Det skal være et symbolsk link for at " -"systemet kan fungere korrekt. Vælg et andet monteringspunkt." - -#: ../partRequests.py:192 -msgid "This mount point must be on a linux file system." -msgstr "Dette monteringspunkt skal være på et linux-filsystem." - -#: ../partRequests.py:212 -#, python-format -msgid "" -"The mount point \"%s\" is already in use, please choose a different mount " -"point." -msgstr "" -"Monteringspunktet \"%s\" er allerede i brug. Vælg venligst et andet " -"monteringspunkt." - -#: ../partRequests.py:226 -#, python-format -msgid "" -"The size of the %s partition (%10.2f MB) exceeds the maximum size of %10.2f " -"MB." -msgstr "" -"Størrelsen på %s-partitionen (%10.2f Mb) overskrider maksimal størrelse på %" -"10.2f Mb." - -#: ../partRequests.py:414 -#, python-format -msgid "" -"The size of the requested partition (size = %s MB) exceeds the maximum size " -"of %s MB." -msgstr "" -"Størrelsen på forespurgt partition (størrelse = %s MB) overskrider maksimal " -"størrelse på %s Mb. " - -#: ../partRequests.py:419 -#, python-format -msgid "The size of the requested partition is negative! (size = %s MB)" -msgstr "Størrelsen på forespurgte partition er negativ! (størrelse = %s Mb)" - -#: ../partRequests.py:423 -msgid "Partitions can't start below the first cylinder." -msgstr "Partitioner kan ikke starte før første cylinder." - -#: ../partRequests.py:426 -msgid "Partitions can't end on a negative cylinder." -msgstr "Partitioner kan ikke slutte på en negativ cylinder." - -#: ../tui_bootloader.py:27 -msgid "Which boot loader would you like to use?" -msgstr "Hvilken boot loader ønsker du at bruge?" - -#: ../tui_bootloader.py:37 -msgid "Use GRUB Boot Loader" -msgstr "Brug GRUB opstartsindlæser" - -#: ../tui_bootloader.py:38 -msgid "No Boot Loader" -msgstr "Ingen boot loader" - -#: ../tui_bootloader.py:41 ../tui_bootloader.py:103 ../tui_bootloader.py:161 -#: ../tui_bootloader.py:278 ../tui_bootloader.py:383 -msgid "Boot Loader Configuration" -msgstr "Konfiguration af boot loader" - -#: ../tui_bootloader.py:58 -msgid "Skip Boot Loader" -msgstr "Overspring boot loader" - -#: ../tui_bootloader.py:59 -msgid "" -"You have elected not to install any boot loader, which is not recommended " -"unless you have an advanced need. Booting your system into Linux directly " -"from the hard drive almost always requires a boot loader.\n" -"\n" -"Are you sure you want to skip boot loader installation?" -msgstr "" -"Du har valgt ikke at installere nogen boot loader, hvilket ikke er " -"anbefalet, medmindre du har avancerede behov. En boot loader er næsten altid " -"påkrævet for at genstarte dit system med Linux direkte fra harddisken.\n" -"\n" -"Er du sikker på, at du vil springe installationen af boot loaderen over?" - -#: ../tui_bootloader.py:88 -msgid "" -"A few systems need to pass special options to the kernel at boot time to " -"function properly. If you need to pass boot options to the kernel, enter " -"them now. If you don't need any or aren't sure, leave this blank." -msgstr "" -"Nogle få systemer har brug for angive særlige parametre til kernen under " -"opstarten for at systemet kan fungere ordentligt. Hvis du har brug for at " -"overføre opstartsparametre til kernen, så indtast dem nu. Hvis du ikke " -"behøver det eller er i tvivl, så lad dette felt stå tomt." - -#: ../tui_bootloader.py:97 -msgid "Force use of LBA32 (not normally required)" -msgstr "Tvungen brug af LBA32 (ikke nødvendig normalt)" - -#: ../tui_bootloader.py:120 -msgid "" -"If LBA32 is not supported by your system's BIOS, forcing its use can prevent " -"your machine from booting.\n" -"\n" -"Would you like to continue and force LBA32 mode?" -msgstr "" -"Hvis LBA32 ikke er understøttet af BIOS, kan gennemtvingning af brug af " -"dette forhindre at maskinen starter op.\n" -"\n" -"Vil du fortsætte med tvungen brug af LBA32-tilstand?" - -#: ../tui_bootloader.py:162 -msgid "Where do you want to install the boot loader?" -msgstr "Hvor vil du installere boot loaderen?" - -#: ../tui_bootloader.py:188 ../tui_bootloader.py:255 ../tui_partition.py:844 -msgid "Device" -msgstr "Enhed" - -#: ../tui_bootloader.py:189 ../tui_bootloader.py:255 -msgid "Boot label" -msgstr "Opstartsnavn" - -#: ../tui_bootloader.py:193 -msgid "Clear" -msgstr "Ryd" - -#: ../tui_bootloader.py:201 -#, fuzzy -msgid "Edit Boot Label" -msgstr "ugyldigt opstartsnavn" - -#: ../tui_bootloader.py:219 ../tui_bootloader.py:224 -msgid "Invalid Boot Label" -msgstr "ugyldigt opstartsnavn" - -#: ../tui_bootloader.py:220 -msgid "Boot label may not be empty." -msgstr "Opstartsnavn må ikke være tomt." - -#: ../tui_bootloader.py:225 -msgid "Boot label contains illegal characters." -msgstr "Opstartsnavn indeholder ugyldige tegn." - -#: ../tui_bootloader.py:255 -msgid "Default" -msgstr "Standard" - -#: ../tui_bootloader.py:273 -#, python-format -msgid "" -"The boot manager %s uses can boot other operating systems as well. Please " -"tell me what partitions you would like to be able to boot and what label you " -"want to use for each of them." -msgstr "" -"Opstartsprogrammet, som bruges af %s, kan også starte andre " -"operativsystemer. Angiv hvilke partitioner du gerne vil kunne starte samt " -"hvilket navn du vil bruge for hvert af dem." - -#: ../tui_bootloader.py:286 -msgid "" -" select | select default | delete | next screen>" -msgstr " vælg | vælg standard | slet | næste skærm>" - -#: ../tui_bootloader.py:335 -msgid "Cannot Delete" -msgstr "Kan ikke slette" - -#: ../tui_bootloader.py:336 -#, python-format -msgid "" -"This boot target cannot be deleted because it is for the %s system you are " -"about to install." -msgstr "" -"Dette opstartsmål kan ikke fjernes da det er beregnet til det %s-system du " -"er ved at installere." - -#: ../tui_bootloader.py:378 -msgid "" -"A boot loader password prevents users from passing arbitrary options to the " -"kernel. For highest security, you should set a password, but a password is " -"not necessary for more casual users." -msgstr "" -"En adgangskode for boot loaderen hindrer brugere i at give tilfældige " -"optioner til kernen. For at få højest mulig sikkerhed bør du sætte en " -"adgangskode, men dette er ikke nødvendig for brugere med mindre krav til " -"sikkerhed." - -#: ../tui_bootloader.py:386 -msgid "Use a GRUB Password" -msgstr "Brug adgangskode for GRUB" - -#: ../tui_bootloader.py:399 -msgid "Boot Loader Password:" -msgstr "Adgangskode for boot loaderen:" - -#: ../tui_bootloader.py:400 -msgid "Confirm:" -msgstr "Bekræft:" - -#: ../tui_bootloader.py:429 -msgid "Passwords Do Not Match" -msgstr "Adgangskoder er ikke ens." - -#: ../tui_bootloader.py:430 -msgid "Passwords do not match" -msgstr "Adgangskoder er ikke ens." - -#: ../tui_bootloader.py:434 -msgid "Password Too Short" -msgstr "Adgangskoden er for kort." - -#: ../tui_bootloader.py:435 -msgid "Boot loader password is too short" -msgstr "Boot loader adgangskoden er for kort." - -#: ../tui_bootloader.py:440 -msgid "" -"Your boot loader password is shorter than six characters. We recommend a " -"longer boot loader password.\n" -"\n" -"Would you like to continue with this password?" -msgstr "" -"Adgangskoden for boot loaderen er kortere end seks tegn. Vi anbefaler en " -"længere adgangskode for boot loaderen.\n" -"\n" -"Vil du fortsætte med denne adgangskode?" - -#: ../tui_complete.py:25 -msgid "" -"Press to end the installation process.\n" -"\n" -msgstr "" -"Tryk for at afslutte installationsprocessen.\n" -"\n" - -#: ../tui_complete.py:26 -msgid " to exit" -msgstr " for at afslutte" - -#: ../tui_complete.py:30 -#, python-format -msgid "" -"Congratulations, your %s installation is complete.\n" -"\n" -"%s%s" -msgstr "" -"Tillykke, din installation af %s er færdig.\n" -"\n" -"%s%s" - -#: ../tui_complete.py:33 -#, python-format -msgid "" -"For information on errata (updates and bug fixes), visit %s.\n" -"\n" -"Information on using your system is available in the %s wiki at %s." -msgstr "" -"For information om errata (opdateringer og fejlrettelser), besøg %s.\n" -"\n" -"Information om brug af systemet er tilgængelig i %s wiki på %s." - -#: ../tui_complete.py:39 -msgid "Complete" -msgstr "Færdig" - -#: ../tui_confirm.py:23 -msgid "Installation to begin" -msgstr "Installation begynder" - -#: ../tui_confirm.py:24 -msgid "" -"Now, we got all information we need for installation. If there is something " -"you want change you can still go back. If not choose OK to start." -msgstr "" -"Nu har vi alle informationerne vi har brug for installationen. Hvis der er " -"noget du vil ændre kan du stadigvæk gå tilbage. Hvis ikke så klick OK for at " -"starte." - -#: ../tui_confirm.py:34 -msgid "Reboot?" -msgstr "Genstart?" - -#: ../tui_confirm.py:35 -msgid "The system will be rebooted now." -msgstr "Systemet vil nu blive genstartet." - -#: ../tui_keyboard.py:36 -msgid "Keyboard Selection" -msgstr "Tastaturvalg" - -#: ../tui_keyboard.py:37 -msgid "Which model keyboard is attached to this computer?" -msgstr "Hvilken tastaturtype er forbundet til denne maskine?" - -#: ../tui_language.py:39 -msgid "Language Selection" -msgstr "Sprogvalg" - -#: ../tui_language.py:40 -msgid "What language would you like to use during the installation process?" -msgstr "Hvilket sprog ønsker du at benytte under installationsprocessen?" - -#: ../tui_network.py:39 -#, fuzzy -msgid "Hostname" -msgstr "Værtsnavn" - -#: ../tui_network.py:42 -msgid "" -"Please name this computer. The hostname identifies the computer on a " -"network." -msgstr "" - -#: ../tui_network.py:63 ../tui_network.py:70 -#, fuzzy -msgid "Invalid Hostname" -msgstr "ugyldigt opstartsnavn" - -#: ../tui_network.py:64 -msgid "You have not specified a hostname." -msgstr "" - -#: ../tui_network.py:71 -#, python-format -msgid "" -"The hostname \"%s\" is not valid for the following reason:\n" -"\n" -"%s" -msgstr "" - -#: ../tui_partition.py:41 -msgid "Must specify a value" -msgstr "Værdi skal specificeres" - -#: ../tui_partition.py:44 -msgid "Requested value is not an integer" -msgstr "Forespurgt værdi er ikke et heltal" - -#: ../tui_partition.py:46 -msgid "Requested value is too large" -msgstr "Forespurgt værdi er for stor" - -#: ../tui_partition.py:95 ../tui_partition.py:132 -msgid "Free space" -msgstr "Ledig plads" - -#: ../tui_partition.py:97 -msgid "Extended" -msgstr "Udvidet" - -#: ../tui_partition.py:111 -msgid "None" -msgstr "Intet" - -#: ../tui_partition.py:178 -#, python-format -msgid "Could not allocate requested partitions: %s." -msgstr "Kunne ikke allokere forespurgte partitioner: %s." - -#: ../tui_partition.py:182 -#, python-format -msgid "Warning: %s" -msgstr "Advarsel: %s" - -#: ../tui_partition.py:183 -msgid "Modify Partition" -msgstr "Ændre partition" - -#: ../tui_partition.py:183 -msgid "Add anyway" -msgstr "Tilføj alligevel" - -#: ../tui_partition.py:201 ../tui_partition.py:203 ../tui_partition.py:205 -#: ../tui_partition.py:230 -msgid "" -msgstr "" - -#: ../tui_partition.py:220 -msgid "Mount Point:" -msgstr "Monteringspunkt:" - -#: ../tui_partition.py:239 -msgid "File System type:" -msgstr "Filsystemtype:" - -#: ../tui_partition.py:270 -msgid "Allowable Drives:" -msgstr "Tilladte drev:" - -#: ../tui_partition.py:292 ../tui_partition.py:371 ../tui_partition.py:419 -msgid "Size (MB):" -msgstr "Størrelse (Mb):" - -#: ../tui_partition.py:324 -msgid "Fixed Size:" -msgstr "Fast størrelse:" - -#: ../tui_partition.py:326 -msgid "Fill maximum size of (MB):" -msgstr "Fyld maksimal størrelse på (Mb):" - -#: ../tui_partition.py:330 -msgid "Fill all available space:" -msgstr "Fyld al tilgængelig plads:" - -#: ../tui_partition.py:351 -msgid "Start Cylinder:" -msgstr "Startcylinder:" - -#: ../tui_partition.py:364 -msgid "End Cylinder:" -msgstr "Slutcylinder:" - -#: ../tui_partition.py:386 -msgid "Number of spares?" -msgstr "Antal reservediske?" - -#: ../tui_partition.py:400 -msgid "File System Type:" -msgstr "Filsystemtype:" - -#: ../tui_partition.py:413 -msgid "File System Label:" -msgstr "Filsystemetiket:" - -#: ../tui_partition.py:424 -msgid "File System Option:" -msgstr "Alternativ for filsystem:" - -#: ../tui_partition.py:427 ../tui_partition.py:652 -#, python-format -msgid "Format as %s" -msgstr "Formatér som %s" - -#: ../tui_partition.py:429 ../tui_partition.py:654 -#, python-format -msgid "Migrate to %s" -msgstr "Migrér til %s" - -#: ../tui_partition.py:431 ../tui_partition.py:656 -msgid "Leave unchanged" -msgstr "Forlad uforandret" - -#: ../tui_partition.py:446 ../tui_partition.py:629 -msgid "File System Options" -msgstr "Filsystemsvalgmuligheder" - -#: ../tui_partition.py:449 -msgid "" -"Please choose how you would like to prepare the file system on this " -"partition." -msgstr "" -"Venligst vælg hvordan du ønsker at forberede filsystemet på denne partition." - -#: ../tui_partition.py:457 ../tui_partition.py:607 -msgid "Check for bad blocks" -msgstr "Se efter beskadigede blokke" - -#: ../tui_partition.py:461 -msgid "Leave unchanged (preserve data)" -msgstr "Forlad uforandret (behold data)" - -#: ../tui_partition.py:470 -msgid "Format as:" -msgstr "Formatér som:" - -#: ../tui_partition.py:489 -msgid "Migrate to:" -msgstr "Migrér til:" - -#: ../tui_partition.py:559 -msgid "Add Partition" -msgstr "Tilføj partition" - -#: ../tui_partition.py:601 -msgid "Force to be a primary partition" -msgstr "Tving til at være en primærpartition" - -#: ../tui_partition.py:684 ../tui_partition.py:738 -msgid "Invalid Entry for Partition Size" -msgstr "Ugyldig værdi for partitionsstørrelse" - -#: ../tui_partition.py:696 -msgid "Invalid Entry for Maximum Size" -msgstr "Ugyldig opføring for maksimum størrelse" - -#: ../tui_partition.py:716 -msgid "Invalid Entry for Starting Cylinder" -msgstr "Ugyldig værdi for startcylinder" - -#: ../tui_partition.py:730 -msgid "Invalid Entry for End Cylinder" -msgstr "Ugyldig værdi for slutcylinder" - -#: ../tui_partition.py:748 ../tui_partition.py:769 -msgid "Error With Request" -msgstr "Fejl med forespørgsel" - -#: ../tui_partition.py:838 -msgid "Partitioning" -msgstr "Partitionering" - -#: ../tui_partition.py:844 -msgid "Start" -msgstr "Start" - -#: ../tui_partition.py:844 -msgid "End" -msgstr "Slut" - -#: ../tui_partition.py:844 -msgid "Size" -msgstr "Størrelse" - -#: ../tui_partition.py:844 -msgid "Type" -msgstr "Type" - -#: ../tui_partition.py:844 -msgid "Mount Point" -msgstr "Monteringspunkt" - -#: ../tui_partition.py:848 -msgid "New" -msgstr "Ny" - -#: ../tui_partition.py:850 -msgid "Delete" -msgstr "Slet" - -#: ../tui_partition.py:853 -msgid "" -" F1-Help F2-New F3-Edit F4-Delete F5-Reset F12-OK " -msgstr "" -" F1-Hjælp F2-Ny F3-Redigér F4-Fjern F5-Nulstil F12-O.k. " - -#: ../tui_partition.py:883 -msgid "No Root Partition" -msgstr "Ingen rodpartition" - -#: ../tui_partition.py:884 -msgid "Installation requires a / partition." -msgstr "Installationen kræver en / partition." - -#: ../tui_partition.py:923 -msgid "Partitioning Type" -msgstr "Partitionstype" - -#: ../tui_partition.py:925 -msgid "" -"Installation requires partitioning of your hard drive. The default layout " -"is reasonable for most users. You can either choose to use this or create " -"your own." -msgstr "" -"Installation kræver partitionering af din disk. Standard-opdelingen er " -"fornuftig for de fleste brugere. Du kan enten vælge denne, eller lave din " -"egen opdeling. " - -#: ../tui_partition.py:932 -msgid "Remove all partitions on selected drives and create default layout" -msgstr "" -"Fjern alle partitioner på valgte partitioner og opret standardudlægning" - -#: ../tui_partition.py:933 -msgid "Create custom layout" -msgstr "Opret selvdefineret layout" - -#: ../tui_partition.py:947 -msgid "Which drive(s) do you want to use for this installation?" -msgstr "Hvilke drev vil du bruge til denne installation?" - -#: ../tui_partition.py:960 -msgid ",<+>,<-> selection | Add drive | next screen" -msgstr "" -",<+>,<-> valg | Tilføj drev | næste skærm" - -#: ../tui_partition.py:1029 -msgid "Review Partition Layout" -msgstr "Vis igen de partitioner som oprettes" - -#: ../tui_partition.py:1030 -msgid "Review and modify partitioning layout?" -msgstr "Vis igen (og ændr om det behøves) de partitioner som oprettes?" - -#: ../tui_progress.py:52 -msgid "File Installation" -msgstr "Fil-installation" - -#: ../tui.py:118 -msgid "Exception Occurred" -msgstr "Undtagelse hændte" - -#: ../tui.py:189 -msgid "Error!" -msgstr "Fejl!" - -#: ../tui.py:190 -#, python-format -msgid "" -"An error occurred when attempting to load an pomona interface component.\n" -"\n" -"className = %s\n" -"\n" -"Error: %s" -msgstr "" -"Et fejl skete ved forsøg at indlæse en pomona interface komponent.\n" -"\n" -"className = %s\n" -"\n" -"Error: %s" - -#: ../tui.py:195 ../tui.py:197 -msgid "Exit" -msgstr "Afslut" - -#: ../tui.py:195 ../tui.py:391 -msgid "Retry" -msgstr "Prøv igen" - -#: ../tui.py:220 -msgid "Cancelled" -msgstr "Annulleret" - -#: ../tui.py:221 -msgid "I can't go to the previous step from here. You will have to try again." -msgstr "Jeg kan ikke gå til forrige trin herfra. Du skal prøve igen." - -#: ../tui.py:235 -#, python-format -msgid "Welcome to %s" -msgstr "Velkommen til %s" - -#: ../tui.py:238 -msgid "" -" for help | between elements | selects | next screen" -msgstr "" -" for hjælp | imellem punkter | vælg | næste side" - -#: ../tui.py:240 -msgid "" -" / between elements | selects | next " -"screen" -msgstr "" -" / imellem punkter | vælger | næste side" - -#: ../tui.py:285 -msgid "Help not available" -msgstr "Ingen hjælp tilgængelig" - -#: ../tui.py:286 -msgid "No help is available for this step of the install." -msgstr "Ingen hjælp er tilgængelig for dette trin af installationen." - -#: ../tui.py:387 -msgid "Fix" -msgstr "Reparér" - -#: ../tui.py:392 -msgid "Ignore" -msgstr "Ignorér" - -#: ../tui_timezone.py:63 -msgid "In which time zone are you located?" -msgstr "Hvilken tidszone befinder du dig i?" - -#: ../tui_timezone.py:78 -msgid "System clock uses UTC" -msgstr "System-ur bruger UTC" - -#: ../tui_timezone.py:81 -msgid "Time Zone Selection" -msgstr "Tidszone valg" - -#: ../tui_userauth.py:29 -msgid "Root Password" -msgstr "'root'-adgangskode" - -#: ../tui_userauth.py:31 -#, fuzzy -msgid "" -"Pick a root password. You must type it twice to ensure you know it and do " -"not make a typing mistake. Remember that the root password isa critical part " -"of system security!" -msgstr "" -"Vælg en 'root'-adgangskode. Du skal skrive den to gange for at sikre at du " -"ved hvad det er og ikke får tastet forkert. Husk at 'root'-adgangskoden er " -"en afgørende del af systemets sikkerhed!" - -#: ../tui_userauth.py:41 -msgid "Password:" -msgstr "Adgangskode:" - -#: ../tui_userauth.py:42 -msgid "Password (confirm):" -msgstr "Adgangskode (bekræft):" - -#: ../tui_userauth.py:59 -msgid "Password Length" -msgstr "Adgangskodelængde" - -#: ../tui_userauth.py:60 -msgid "The root password must be at least 6 characters long." -msgstr "'root'-adgangskoden skal være på mindst 6 tegn." - -#: ../tui_userauth.py:63 -msgid "Password Mismatch" -msgstr "Adgangskode stemmer ikke" - -#: ../tui_userauth.py:64 -msgid "The passwords you entered were different. Please try again." -msgstr "De to adgangskoder du indtastede var ikke ens. Prøv igen." - -#: ../tui_userauth.py:67 -msgid "Error with Password" -msgstr "Fejl med adgangskode" - -#: ../tui_userauth.py:68 -msgid "" -"Requested password contains non-ASCII characters, which are not allowed." -msgstr "" -"Den udbedte adgangskode indeholder ikke-ascii tegn som ikke er tilladt." - -#: ../tui_welcome.py:12 -#, python-format -msgid "%s" -msgstr "%s" - -#: ../tui_welcome.py:13 -#, python-format -msgid "" -"Welcome to %s!\n" -"\n" -msgstr "" -"Velkommen til %s!\n" -"\n" - -#. generated from lang-table -msgid "English" -msgstr "Engelsk" - -#. generated from lang-table -msgid "German" -msgstr "Tysk" - -#. generated from lang-table -msgid "Danish" -msgstr "Dansk" - -#~ msgid "Checking for Bad Blocks" -#~ msgstr "Kontrollerer for dårlige blokke" - -#~ msgid "" -#~ "An error occurred unmounting the disc. Please make sure you're not " -#~ "accessing the disk from the shell on tty2 and then click OK to retry." -#~ msgstr "" -#~ "En fejl skete ved afmontering af cd-en. Forsikr dig venligst om at du " -#~ "ikke bruger %s fra skallen, og klik så O.k. for at prøve igen." - -#~ msgid "" -#~ "The file %s cannot be opened. This is due to a missing file or perhaps a " -#~ "corrupt package. Please verify your installation images and that you " -#~ "have all the required media.\n" -#~ "\n" -#~ "If you reboot, your system will be left in an inconsistent state that " -#~ "will likely require reinstallation.\n" -#~ "\n" -#~ msgstr "" -#~ "Filen %s kan ikke åbnes. Dette beror på en manglende fil eller måske en " -#~ "beskadiget pakke. Kontrollér dine installationsmedier og at du har alle " -#~ "de nødvendige medier.\n" -#~ "\n" -#~ "Hvis du genstarter vil dit system være i en inkonsistent tilstand, som " -#~ "sandsynligvis vil kræve geninstallation.\n" -#~ "\n" - -#, fuzzy -#~ msgid "Probing CDROM" -#~ msgstr "Forkert cd-rom" - -#~ msgid "Searching for a valid disc on /dev/%s..." -#~ msgstr "Kontrollerer for dårlige blokke på /dev/%s..." - -#~ msgid "Wrong CDROM" -#~ msgstr "Forkert cd-rom" - -#~ msgid "That's not the correct %s CDROM in /dev/%s." -#~ msgstr "Dette er ikke den korrekte %s-cd-rom på /dev/%s." - -#~ msgid "Insert CDROM" -#~ msgstr "skift cd-rom" - -#~ msgid "Please insert the %s disc to continue." -#~ msgstr "Indsæt venligst %s disk for at fortsætte." - -#~ msgid "Install on System" -#~ msgstr "Installér på system" - -#~ msgid "IPFire" -#~ msgstr "IPFire" - -#~ msgid "Disk Partitioning Setup" -#~ msgstr "Opsætning af diskpartitioner" - -#~ msgid "Autopartition" -#~ msgstr "Auto-partition" - -#~ msgid "Disk Druid" -#~ msgstr "Diskdruid" - -#~ msgid "Missing ISO 9660 Image" -#~ msgstr "Mangler ISO 9660-image" - -#~ msgid "" -#~ "The installer has tried to mount image #%s, but cannot find it on the " -#~ "hard drive.\n" -#~ "\n" -#~ "Please copy this image to the drive and click Retry. Click Reboot to " -#~ "abort the installation." -#~ msgstr "" -#~ "Installeringsprogrammet har forsøgt at montere image #%s, men kan ikke " -#~ "finde det på disken.\n" -#~ "\n" -#~ "Kopiér venligst dette image til drevet og klik forsøg igen. Klik genstart " -#~ "for at afbryde installationen." - -#~ msgid "Re_try" -#~ msgstr "_Prøv igen" - -#~ msgid "Couldn't Mount ISO Source" -#~ msgstr "Kunne ikke montere ISO-kilde" - -#~ msgid "" -#~ "An error occurred mounting the source device %s. This may happen if your " -#~ "ISO images are located on an advanced storage device like LVM or RAID, or " -#~ "if there was a problem mounting a partition. Click reboot to abort the " -#~ "installation." -#~ msgstr "" -#~ "Der skete en fejl ved montering af kildeenheden %s. Dette kan ske hvis " -#~ "dine ISO-image ligger på et avancerede lagringsmedier som LVM eller RAID, " -#~ "eller hvis der var et problem med at montere en partition. Klik genstart " -#~ "for at afbryde installationen. " - -#~ msgid "Source Type" -#~ msgstr "Kildetype:" - -#~ msgid "" -#~ "In installation you have to choose a source for the installation files. " -#~ "Mostly you will choose the disc here, but you are also able to install by " -#~ "HTTP, FTP hard disk or usb-key." -#~ msgstr "" -#~ "I installationen skal du vælge en kilde for installationsfilerne. Typisk " -#~ "vil du vælge en harddisk, men du vil også kunne installere fra HTTP, FTP " -#~ "harddisk eller usb-nøgle." - -#~ msgid "Install Disc" -#~ msgstr "Installationsdisk" - -#~ msgid "Internet Source" -#~ msgstr "Internet kilde" - -#~ msgid "External Drive" -#~ msgstr "Eksternt drev" - -#~ msgid "No CDROM found" -#~ msgstr "Ingen Cd fundet" - -#~ msgid "" -#~ "You choosed to install from an installtion disc, but there was no cdrom " -#~ "drive found on the system. Please choose another installation method." -#~ msgstr "" -#~ "Du valgte at installere fra installations-disken, men der blev ikke " -#~ "fundet noget cdrom-drev på dette system. Vælg en anden " -#~ "installationsmethode." - -#~ msgid "Source URL" -#~ msgstr "Kilde URL:" - -#~ msgid "" -#~ "Enter a host you get the files from.You also must enter a path where the " -#~ "installer finds the files in." -#~ msgstr "" -#~ "Angiv en host som du modtager filerne fra. Du skal også angive en sti " -#~ "hvor instalationsprogrammet kan finde filerne." - -#~ msgid "Path:" -#~ msgstr "Sti:" - -#~ msgid "Wrong Protocol" -#~ msgstr "Forkert protokol" - -#~ msgid "" -#~ "You entered a protocol that is not supported by Pomona. There are only " -#~ "http:// and ftp:// available." -#~ msgstr "" -#~ "Du har angivet et protokol som ikke er understøttet af Pomona. Der står " -#~ "kun http:// og ftp:// til rådighed." - -#~ msgid "Syntax Error" -#~ msgstr "Syntaksfejl" - -#~ msgid "The path of the URL must end with a /." -#~ msgstr "Stien af denne URL skal afslutte med et /." - -#~ msgid "" -#~ "When we tested your given URL there was an error.\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Der opstod en fejl da vi testede din angivne URL.\n" -#~ "\n" -#~ "%s" - -#~ msgid "Downloading" -#~ msgstr "Indlæser" - -#~ msgid "Connecting..." -#~ msgstr "Tilslutter..." - -#~ msgid "Retrieving %s" -#~ msgstr "Modtager %s" - -#~ msgid "" -#~ "The file %s cannot be opened. This is due to a missing file or perhaps a " -#~ "corrupt package. Please verify your mirror contains all required " -#~ "packages, and try using a different one.\n" -#~ "\n" -#~ "If you reboot, your system will be left in an inconsistent state that " -#~ "will likely require reinstallation.\n" -#~ "\n" -#~ msgstr "" -#~ "Filen %s kan ikke åbnes. Dette beror på en manglende fil eller måske en " -#~ "beskadiget pakke. Kontrollér at din mirror indeholder alle de nødvendige " -#~ "pakker, eller prøv at bruge en anden mirror.\n" -#~ "\n" -#~ "Hvis du genstarter vil dit system være i en inkonsistent tilstand, som " -#~ "sandsynligvis vil kræve geninstallation.\n" -#~ "\n" - -#~ msgid "" -#~ "An error occurred unmounting the disc. Please make sure you're not " -#~ "accessing %s from the shell on tty2 and then click OK to retry." -#~ msgstr "" -#~ "En fejl skete ved afmontering af cd-en. Forsikr dig venligst om at du " -#~ "ikke bruger %s fra skallen, og klik så O.k. for at prøve igen." diff --git a/pkgs/core/pomona/src/po/de.po b/pkgs/core/pomona/src/po/de.po deleted file mode 100644 index c03b39837..000000000 --- a/pkgs/core/pomona/src/po/de.po +++ /dev/null @@ -1,2177 +0,0 @@ -# German translation of Pomona -# Copyright (C) 2007 The IPFire Team -# This file is distributed under the same license as IPFire. -# Michael Tremer , 2007. -# -msgid "" -msgstr "" -"Project-Id-Version: Pomona\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-29 01:02+0100\n" -"PO-Revision-Date: 2009-01-29 01:26+0100\n" -"Last-Translator: Michael Tremer \n" -"Language-Team: German\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../autopart.py:751 -#, python-format -msgid "" -"Could not allocate cylinder-based partitions as primary partitions.\n" -"\n" -"%s" -msgstr "" - -#: ../autopart.py:756 -#, python-format -msgid "" -"Could not allocate partitions as primary partitions.\n" -"\n" -"%s" -msgstr "" - -#: ../autopart.py:761 -#, python-format -msgid "" -"Could not allocate cylinder-based partitions.\n" -"\n" -"%s" -msgstr "" - -#: ../autopart.py:800 -#, python-format -msgid "" -"Boot partition %s doesn't belong to a BSD disk label. SRM won't be able to " -"boot from this partition. Use a partition belonging to a BSD disk label or " -"change this device disk label to BSD." -msgstr "" - -#: ../autopart.py:802 -#, python-format -msgid "" -"Boot partition %s doesn't belong to a disk with enough free space at its " -"beginning for the bootloader to live on. Make sure that there's at least 5MB " -"of free space at the beginning of the disk that contains /boot" -msgstr "" - -#: ../autopart.py:804 -#, python-format -msgid "" -"Boot partition %s isn't a VFAT partition. EFI won't be able to boot from " -"this partition." -msgstr "" - -#: ../autopart.py:806 -msgid "" -"The boot partition must entirely be in the first 4GB of the disk. " -"OpenFirmware won't be able to boot this installation." -msgstr "" - -#: ../autopart.py:813 -#, python-format -msgid "" -"Boot partition %s may not meet booting constraints for your architecture." -msgstr "" - -#: ../autopart.py:951 -msgid "Requested Partition Does Not Exist" -msgstr "Die angegebene Partition existiert nicht" - -#: ../autopart.py:952 -#, python-format -msgid "" -"Unable to locate partition %s to use for %s.\n" -"\n" -"Press 'OK' to reboot your system." -msgstr "" - -#: ../autopart.py:997 ../autopart.py:1029 -msgid "Automatic Partitioning Errors" -msgstr "" - -#: ../autopart.py:998 -#, python-format -msgid "" -"The following errors occurred with your partitioning:\n" -"\n" -"%s\n" -"\n" -"Press 'OK' to reboot your system." -msgstr "" - -#: ../autopart.py:1007 -msgid "Warnings During Automatic Partitioning" -msgstr "" - -#: ../autopart.py:1008 -#, python-format -msgid "" -"Following warnings occurred during automatic partitioning:\n" -"\n" -"%s" -msgstr "" - -#: ../autopart.py:1016 ../tui_partition.py:177 -msgid "Error Partitioning" -msgstr "Partitionierungsfehler" - -#: ../autopart.py:1017 -#, python-format -msgid "" -"Could not allocate requested partitions: \n" -"\n" -"%s." -msgstr "" - -#: ../autopart.py:1027 -msgid "" -"\n" -"\n" -"Press 'OK' to choose a different partitioning option." -msgstr "" -"\n" -"\n" -"Drücken Sie 'OK' um eine andere Partitionierungsoption zu wählen." - -#: ../autopart.py:1030 -#, python-format -msgid "" -"The following errors occurred with your partitioning:\n" -"\n" -"%s\n" -"\n" -"This can happen if there is not enough space on your hard drive(s) for the " -"installation. %s" -msgstr "" - -#: ../autopart.py:1105 ../bootloader.py:745 ../partedUtils.py:230 -#: ../partedUtils.py:531 ../partedUtils.py:568 ../tui_bootloader.py:119 -#: ../tui_bootloader.py:439 ../tui_partition.py:182 -msgid "Warning" -msgstr "Warnung" - -#: ../autopart.py:1126 -msgid "" -"Automatic Partitioning sets partitions based on the selected installation " -"type. You also can customize the partitions once they have been created.\n" -"\n" -"The manual disk partitioning tool, Disk Druid, allows you to create " -"partitions in an interactive environment. You can set the file system types, " -"mount points, partition sizes, and more." -msgstr "" - -#: ../autopart.py:1137 -msgid "" -"Before automatic partitioning can be set up by the installation program, you " -"must choose how to use the space on your hard drives." -msgstr "" - -#: ../autopart.py:1142 -msgid "Remove all partitions on this system" -msgstr "Entferne alle Partitionen auf diesem System" - -#: ../autopart.py:1144 -#, python-format -msgid "" -"You have chosen to remove all partitions (ALL DATA) on the following drives:%" -"s\n" -"Are you sure you want to do this?" -msgstr "" -"Sie haben sich entschlossen alle Partitionen (einschließlich aller Daten) " -"auf den folgenden Datenträgern zu entfernen: %s\n" -"Sind Sie sich sicher?" - -#: ../bootloader.py:696 -msgid "Bootloader" -msgstr "Bootloader" - -#: ../bootloader.py:696 -msgid "Installing bootloader..." -msgstr "Installiere Bootloader..." - -#: ../bootloader.py:746 -msgid "" -"No kernel packages were installed on your system. Your boot loader " -"configuration will not be changed." -msgstr "" - -#: ../constants.py:41 -#, python-format -msgid "" -"An unhandled exception has occurred. This is most likely a bug. Please " -"save a copy of the detailed exception and file a bug report against pomona " -"at %s" -msgstr "" -"Ein unerwarteter Fehler ist aufgetreten. Meistens handelt es sich um einen " -"Bug, wenn Sie diese Meldung sehen. Bitte sichern Sie eine detaillierte Kopie " -"dieses Fehlers und senden Sie diese an den Bugtracker %s." - -#: ../constants.py:83 ../installer.py:93 ../tui_confirm.py:28 -#: ../tui_network.py:65 ../tui_network.py:74 ../tui.py:224 ../tui.py:390 -msgid "OK" -msgstr "OK" - -#: ../constants.py:87 ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 -#: ../tui_bootloader.py:194 ../tui.py:103 ../tui.py:104 ../tui.py:393 -msgid "Cancel" -msgstr "Abbrechen" - -#: ../constants.py:91 ../tui_confirm.py:28 ../tui_confirm.py:30 -msgid "Back" -msgstr "Zurück" - -#: ../constants.py:95 ../tui_bootloader.py:67 ../tui.py:388 -msgid "Yes" -msgstr "Ja" - -#: ../constants.py:99 ../tui_bootloader.py:67 ../tui.py:389 -msgid "No" -msgstr "Nein" - -#: ../constants.py:103 ../tui_bootloader.py:270 ../tui_partition.py:849 -msgid "Edit" -msgstr "Bearbeiten" - -#: ../fsset.py:422 -msgid "Checking" -msgstr "Überprüfe" - -#: ../fsset.py:423 -#, python-format -msgid "Checking filesystem on %s..." -msgstr "Untersuche Dateisystem %s..." - -#: ../fsset.py:434 -msgid "Resizing" -msgstr "" - -#: ../fsset.py:435 -#, python-format -msgid "Resizing filesystem on %s..." -msgstr "Verändere Dateisystemgröße auf %s..." - -#: ../fsset.py:578 ../fsset.py:1112 ../fsset.py:1143 ../fsset.py:1205 -#: ../fsset.py:1216 ../fsset.py:1270 ../fsset.py:1281 ../fsset.py:1303 -#: ../fsset.py:1352 ../fsset.py:1433 ../partIntfHelpers.py:289 -msgid "Error" -msgstr "Fehler" - -#: ../fsset.py:579 -#, python-format -msgid "" -"An error occurred migrating %s to ext3. It is possible to continue without " -"migrating this file system if desired.\n" -"\n" -"Would you like to continue without migrating %s?" -msgstr "" -"Bei der Migration von %s zu ext3 trat ein Fehler auf. Es ist möglich " -"fortzufahren ohne die Migration zu vollziehen.\n" -"\n" -"Möchten Sie ohne Migration von %s fortfahren?" - -#: ../fsset.py:1046 -msgid "First sector of boot partition" -msgstr "Erster Sektor der Boot-Partition" - -#: ../fsset.py:1047 -msgid "Master Boot Record (MBR)" -msgstr "Boot-Sektor (MBR)" - -#: ../fsset.py:1113 -#, python-format -msgid "" -"An error occurred trying to initialize swap on device %s. This problem is " -"serious, and the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" - -#: ../fsset.py:1142 -msgid "Skip" -msgstr "Überspringen" - -#: ../fsset.py:1142 ../tui_complete.py:40 -msgid "Reboot" -msgstr "Neustarten" - -#: ../fsset.py:1163 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"is a version 0 Linux swap partition. If you want to use this device, you " -"must reformat as a version 1 Linux swap partition. If you skip it, the " -"installer will ignore it during the installation." -msgstr "" - -#: ../fsset.py:1170 -msgid "Reformat" -msgstr "Neu formatieren" - -#: ../fsset.py:1174 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"in your /etc/fstab file is currently in use as a software suspend partition, " -"which means your system is hibernating. To perform an upgrade, please shut " -"down your system rather than hibernating it." -msgstr "" - -#: ../fsset.py:1182 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"in your /etc/fstab file is currently in use as a software suspend partition, " -"which means your system is hibernating. If you are performing a new install, " -"make sure the installer is set to format all swap partitions." -msgstr "" - -#: ../fsset.py:1192 -msgid "" -"\n" -"\n" -"Choose Skip if you want the installer to ignore this partition during the " -"upgrade. Choose Format to reformat the partition as swap space. Choose " -"Reboot to restart the system." -msgstr "" - -#: ../fsset.py:1198 -msgid "Format" -msgstr "Formatieren" - -#: ../fsset.py:1206 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"The /etc/fstab on your upgrade partition does not reference a valid swap " -"partition.\n" -"\n" -"Press OK to reboot your system." -msgstr "" - -#: ../fsset.py:1217 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"This most likely means this swap partition has not been initialized.\n" -"\n" -"Press OK to reboot your system." -msgstr "" - -#: ../fsset.py:1271 -#, python-format -msgid "" -"Bad blocks have been detected on device /dev/%s. We do not recommend you use " -"this device.\n" -"\n" -"Press to reboot your system" -msgstr "" - -#: ../fsset.py:1282 -#, python-format -msgid "" -"An error occurred searching for bad blocks on %s. This problem is serious, " -"and the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" - -#: ../fsset.py:1304 -#, python-format -msgid "" -"An error occurred trying to format %s. This problem is serious, and the " -"install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" - -#: ../fsset.py:1353 -#, python-format -msgid "" -"An error occurred trying to migrate %s. This problem is serious, and the " -"install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" - -#: ../fsset.py:1380 ../fsset.py:1389 -msgid "Invalid mount point" -msgstr "Ungültiger Mount-Point" - -#: ../fsset.py:1381 -#, python-format -msgid "" -"An error occurred when trying to create %s. Some element of this path is " -"not a directory. This is a fatal error and the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" - -#: ../fsset.py:1390 -#, python-format -msgid "" -"An error occurred when trying to create %s: %s. This is a fatal error and " -"the install cannot continue.\n" -"\n" -"Press to reboot your system." -msgstr "" - -#: ../fsset.py:1403 -msgid "Unable to mount filesystem" -msgstr "Konnte das Dateisystem nicht mounten" - -#: ../fsset.py:1404 -#, python-format -msgid "" -"An error occurred mounting device %s as %s. You may continue installation, " -"but there may be problems." -msgstr "" - -#: ../fsset.py:1411 ../fsset.py:1820 ../fsset.py:1827 ../packages.py:131 -#: ../partedUtils.py:578 ../tui_confirm.py:37 -msgid "_Reboot" -msgstr "_Neustart" - -#: ../fsset.py:1411 ../partedUtils.py:578 -msgid "_Continue" -msgstr "_Fortfahren" - -#: ../fsset.py:1419 -#, python-format -msgid "" -"Error mounting device %s as %s: %s\n" -"\n" -"Devices in /etc/fstab should be specified by label, not by device name.\n" -"\n" -"Press OK to reboot your system." -msgstr "" - -#: ../fsset.py:1426 -#, python-format -msgid "" -"Error mounting device %s as %s: %s\n" -"\n" -"This most likely means this partition has not been formatted.\n" -"\n" -"Press OK to reboot your system." -msgstr "" - -#: ../fsset.py:1812 -msgid "Duplicate Labels" -msgstr "Doppelte Labels" - -#: ../fsset.py:1813 -#, python-format -msgid "" -"Multiple devices on your system are labelled %s. Labels across devices must " -"be unique for your system to function properly.\n" -"\n" -"Please fix this problem and restart the installation process." -msgstr "" - -#: ../fsset.py:1822 -msgid "Invalid Label" -msgstr "Ungültiges Label" - -#: ../fsset.py:1823 -#, python-format -msgid "" -"An invalid label was found on device %s. Please fix this problem and " -"restart the installation process." -msgstr "" - -#: ../fsset.py:2049 -msgid "Formatting" -msgstr "Formatiere" - -#: ../fsset.py:2050 -#, python-format -msgid "Formatting %s file system..." -msgstr "Formatiere %s..." - -#: ../installer.py:88 -msgid "Fatal Error" -msgstr "Fehler" - -#: ../installer.py:89 -#, python-format -msgid "" -"You do not have enough RAM to install %s on this machine.\n" -"\n" -"Press to reboot your system.\n" -msgstr "" -"Sie haben nicht genug Arbeitsspeicher um %s auf diesem System zu " -"installieren.\n" -"\n" -"Drücken Sie um das System neu zu starten.\n" - -#: ../installer.py:173 -msgid "Starting text installation..." -msgstr "Starte Textinstallation..." - -#: ../keyboard_models.py:48 -msgid "keyboard|Arabic (azerty)" -msgstr "" - -#: ../keyboard_models.py:51 -msgid "keyboard|Arabic (azerty/digits)" -msgstr "" - -#: ../keyboard_models.py:54 -msgid "keyboard|Arabic (digits)" -msgstr "" - -#: ../keyboard_models.py:57 -msgid "keyboard|Arabic (qwerty)" -msgstr "" - -#: ../keyboard_models.py:60 -msgid "keyboard|Arabic (qwerty/digits)" -msgstr "" - -#: ../keyboard_models.py:63 -msgid "keyboard|Belgian (be-latin1)" -msgstr "" - -#: ../keyboard_models.py:66 -msgid "keyboard|Bengali (Inscript)" -msgstr "" - -#: ../keyboard_models.py:69 -msgid "keyboard|Bengali (Probhat)" -msgstr "" - -#: ../keyboard_models.py:72 -msgid "keyboard|Bulgarian" -msgstr "" - -#: ../keyboard_models.py:75 -msgid "keyboard|Bulgarian (Phonetic)" -msgstr "" - -#: ../keyboard_models.py:78 -msgid "keyboard|Brazilian (ABNT2)" -msgstr "" - -#: ../keyboard_models.py:81 -msgid "keyboard|French Canadian" -msgstr "" - -#: ../keyboard_models.py:84 -msgid "keyboard|Croatian" -msgstr "" - -#: ../keyboard_models.py:87 -msgid "keyboard|Czech" -msgstr "" - -#: ../keyboard_models.py:90 -msgid "keyboard|Czech (qwerty)" -msgstr "" - -#: ../keyboard_models.py:93 -msgid "keyboard|German" -msgstr "" - -#: ../keyboard_models.py:96 -msgid "keyboard|German (latin1)" -msgstr "" - -#: ../keyboard_models.py:99 -msgid "keyboard|German (latin1 w/ no deadkeys)" -msgstr "" - -#: ../keyboard_models.py:102 -msgid "keyboard|Devanagari (Inscript)" -msgstr "" - -#: ../keyboard_models.py:105 -msgid "keyboard|Dvorak" -msgstr "" - -#: ../keyboard_models.py:108 -msgid "keyboard|Danish" -msgstr "" - -#: ../keyboard_models.py:111 -msgid "keyboard|Danish (latin1)" -msgstr "" - -#: ../keyboard_models.py:114 -msgid "keyboard|Spanish" -msgstr "" - -#: ../keyboard_models.py:117 -msgid "keyboard|Estonian" -msgstr "" - -#: ../keyboard_models.py:120 -msgid "keyboard|Finnish" -msgstr "" - -#: ../keyboard_models.py:123 -msgid "keyboard|Finnish (latin1)" -msgstr "" - -#: ../keyboard_models.py:126 -msgid "keyboard|French" -msgstr "" - -#: ../keyboard_models.py:129 -msgid "keyboard|French (latin9)" -msgstr "" - -#: ../keyboard_models.py:132 -msgid "keyboard|French (latin1)" -msgstr "" - -#: ../keyboard_models.py:135 -msgid "keyboard|French (pc)" -msgstr "" - -#: ../keyboard_models.py:138 -msgid "keyboard|Swiss French" -msgstr "" - -#: ../keyboard_models.py:141 -msgid "keyboard|Swiss French (latin1)" -msgstr "" - -#: ../keyboard_models.py:144 -msgid "keyboard|Greek" -msgstr "" - -#: ../keyboard_models.py:147 -msgid "keyboard|Gujarati (Inscript)" -msgstr "" - -#: ../keyboard_models.py:150 -msgid "keyboard|Punjabi (Inscript)" -msgstr "" - -#: ../keyboard_models.py:153 -msgid "keyboard|Hungarian" -msgstr "" - -#: ../keyboard_models.py:156 -msgid "keyboard|Hungarian (101 key)" -msgstr "" - -#: ../keyboard_models.py:159 -msgid "keyboard|Icelandic" -msgstr "" - -#: ../keyboard_models.py:162 -msgid "keyboard|Italian" -msgstr "" - -#: ../keyboard_models.py:165 -msgid "keyboard|Italian (IBM)" -msgstr "" - -#: ../keyboard_models.py:168 -msgid "keyboard|Italian (it2)" -msgstr "" - -#: ../keyboard_models.py:171 -msgid "keyboard|Japanese" -msgstr "" - -#: ../keyboard_models.py:174 -msgid "keyboard|Korean" -msgstr "" - -#: ../keyboard_models.py:177 -msgid "keyboard|Latin American" -msgstr "" - -#: ../keyboard_models.py:180 -msgid "keyboard|Macedonian" -msgstr "" - -#: ../keyboard_models.py:183 -msgid "keyboard|Dutch" -msgstr "" - -#: ../keyboard_models.py:186 -msgid "keyboard|Norwegian" -msgstr "" - -#: ../keyboard_models.py:189 -msgid "keyboard|Polish" -msgstr "" - -#: ../keyboard_models.py:192 -msgid "keyboard|Portuguese" -msgstr "" - -#: ../keyboard_models.py:195 -msgid "keyboard|Romanian" -msgstr "" - -#: ../keyboard_models.py:198 -msgid "keyboard|Russian" -msgstr "" - -#: ../keyboard_models.py:201 -msgid "keyboard|Serbian" -msgstr "" - -#: ../keyboard_models.py:204 -msgid "keyboard|Serbian (latin)" -msgstr "" - -#: ../keyboard_models.py:207 -msgid "keyboard|Swedish" -msgstr "" - -#: ../keyboard_models.py:210 -msgid "keyboard|Swiss German" -msgstr "" - -#: ../keyboard_models.py:213 -msgid "keyboard|Swiss German (latin1)" -msgstr "" - -#: ../keyboard_models.py:216 -msgid "keyboard|Slovak (qwerty)" -msgstr "" - -#: ../keyboard_models.py:219 -msgid "keyboard|Slovenian" -msgstr "" - -#: ../keyboard_models.py:222 -msgid "keyboard|Tamil (Inscript)" -msgstr "" - -#: ../keyboard_models.py:225 -msgid "keyboard|Tamil (Typewriter)" -msgstr "" - -#: ../keyboard_models.py:228 -msgid "keyboard|Turkish" -msgstr "" - -#: ../keyboard_models.py:231 -msgid "keyboard|United Kingdom" -msgstr "" - -#: ../keyboard_models.py:234 -msgid "keyboard|Ukrainian" -msgstr "" - -#: ../keyboard_models.py:237 -msgid "keyboard|U.S. International" -msgstr "" - -#: ../keyboard_models.py:240 -msgid "keyboard|U.S. English" -msgstr "" - -#: ../network.py:31 -msgid "IP address is missing." -msgstr "IP-Adresse fehlt." - -#: ../network.py:35 -msgid "" -"IPv4 addresses must contain four numbers between 0 and 255, separated by " -"periods." -msgstr "" -"IPv4-Adressen müssen vier Oktets mit Zahlen zwischen 0 und 255 enthalten. " -"Getrennt von Punkten." - -#: ../network.py:38 -#, python-format -msgid "'%s' is not a valid IPv6 address." -msgstr "'%s' ist keine gültige IPv6-Adresse." - -#: ../network.py:40 -#, python-format -msgid "'%s' is an invalid IP address." -msgstr "'%s' ist eine ungültige IP-Adresse." - -#: ../network.py:52 -msgid "Hostname must be 255 or fewer characters in length." -msgstr "Hostname muss 255 oder weniger Zeichen enthalten." - -#: ../network.py:58 -msgid "" -"Hostname must start with a valid character in the ranges 'a-z', 'A-Z', or '0-" -"9'" -msgstr "" -"Der Hostname muss mit mit einem gültigen Zeichen beginnen. Das sind 'a-z', " -"'A-Z' oder '0-9'." - -#: ../network.py:63 -msgid "" -"Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'" -msgstr "" - -#: ../packages.py:113 -msgid "Warning! This is pre-release software!" -msgstr "Warnung! Dies ist noch nicht veröffentlichte Software!" - -#: ../packages.py:114 -#, python-format -msgid "" -"Thank you for downloading this pre-release of %s.\n" -"\n" -"This is not a final release and is not intended for use on production " -"systems. The purpose of this release is to collect feedback from testers, " -"and it is not suitable for day to day usage.\n" -"\n" -"To report feedback, please visit:\n" -"\n" -" %s\n" -"\n" -"and file a report against '%s'.\n" -msgstr "" -"Danke, für das probieren dieser noch nicht veröffentlichten Version von %s.\n" -"\n" -"Diese Software ist noch kein finales Release und nicht für den produktiven " -"Einsatz gedacht. Der Zweck liegt darin Fehler zu finden und Feedback von " -"Testern zu bekommen.\n" -"\n" -"Um Feedback zu geben besuchen Sie\n" -"\n" -" %s\n" -"\n" -"und senden einen Report über '%s'.\n" - -#: ../packages.py:127 -msgid "_Exit" -msgstr "Ende" - -#: ../packages.py:127 -msgid "_Install anyway" -msgstr "_Trotzdem installieren" - -#: ../packages.py:130 -msgid "Your system will now be rebooted..." -msgstr "Ihr System wird jetzt neu gestartet..." - -#: ../packages.py:131 ../tui_confirm.py:37 -msgid "_Back" -msgstr "Zurück" - -#: ../packages.py:132 -msgid "Rebooting System" -msgstr "Starte das System neu" - -#: ../pakfireinstall.py:47 -#, python-format -msgid "%s MB" -msgstr "%s MB" - -#: ../pakfireinstall.py:50 -#, python-format -msgid "%s KB" -msgstr "%s KB" - -#: ../pakfireinstall.py:53 -#, python-format -msgid "%s Byte" -msgstr "%s Byte" - -#: ../pakfireinstall.py:55 -#, python-format -msgid "%s Bytes" -msgstr "%s Bytes" - -#: ../pakfireinstall.py:134 -msgid "Base system" -msgstr "Grundsystem" - -#: ../pakfireinstall.py:134 -msgid "Installing base system..." -msgstr "Installiere Basissystem..." - -#: ../pakfireinstall.py:171 -msgid "Install Starting" -msgstr "Starte Installation" - -#: ../pakfireinstall.py:172 -msgid "Starting install process. This may take several minutes..." -msgstr "" -"Der Installationsprozess wird gestartet. Haben Sie einen Augenblick Geduld..." - -#: ../pakfireinstall.py:183 -msgid "Post Install" -msgstr "" - -#: ../pakfireinstall.py:184 -msgid "Performing post install configuration..." -msgstr "" - -#: ../pakfireinstall.py:215 -msgid "Symmetric multiprocessing" -msgstr "" - -#: ../pakfireinstall.py:216 -msgid "Xen guest" -msgstr "Xen-Gast" - -#: ../pakfireinstall.py:226 -msgid "Normal Boot" -msgstr "Normaler Boot" - -#: ../pakfireinstall.py:233 -msgid "Installation Progress" -msgstr "Installationsprozess" - -#: ../partedUtils.py:191 ../tui_partition.py:408 -msgid "Foreign" -msgstr "" - -#: ../partedUtils.py:231 -#, python-format -msgid "" -"/dev/%s currently has a %s partition layout. To use this drive for the " -"installation of %s, it must be re-initialized, causing the loss of ALL DATA " -"on this drive.\n" -"\n" -"Would you like to re-initialize this drive?" -msgstr "" -"/dev/%s hat momentan ein %s Partitionslayout. Um dieses Laufwerk für eine %s-" -"Installation zu nutzen muss es reinitialisiert werden, was ALLE DATEN auf " -"diesem Laufwerk vernichten wird.\n" -"\n" -"Möchten Sie das Laufwerk reinitialisieren?" - -#: ../partedUtils.py:239 -msgid "_Ignore drive" -msgstr "_Ignoriere Laufwerk" - -#: ../partedUtils.py:240 -msgid "_Re-initialize drive" -msgstr "_Reinitialisiere Laufwerk" - -#: ../partedUtils.py:532 -#, python-format -msgid "" -"The partition table on device %s was unreadable. To create new partitions it " -"must be initialized, causing the loss of ALL DATA on this drive.\n" -"\n" -"This operation will override any previous installation choices about which " -"drives to ignore.\n" -"\n" -"Would you like to initialize this drive, erasing ALL DATA?" -msgstr "" -"Die Partitionstabelle auf %s war nicht lesbar. Um neue Partitionen zu " -"erstellen muss diese initialisiert werden, was ALLE DATEN auf diesem " -"Laufwerk vernichten wird.\n" -"\n" -"Diese Operation wird alle vorhergegangen Entscheidungen über auszulassende " -"Laufwerke verwerfen.\n" -"\n" -"Möchten Sie dieses Laufwerk initialisieren, was ALLE DATEN vernichten wird?" - -#: ../partedUtils.py:569 -#, python-format -msgid "" -"The drive /dev/%s has more than 15 partitions on it. The SCSI subsystem in " -"the Linux kernel does not allow for more than 15 partitons at this time. " -"You will not be able to make changes to the partitioning of this disk or use " -"any partitions beyond /dev/%s15 in %s" -msgstr "" -"Das Laufwerk /dev/%s hat mehr als 15 Partitionen. Das SCSI-Subsystem des " -"Linux-Kernel erlaubt im Augenblick nicht mehr als 15 Partitionen. Sie werden " -"keine Partitionsänderungen vornehmen und auf keine Partitionen nach /dev/%" -"s15 auf %s zugreifen können." - -#: ../partedUtils.py:659 -msgid "No Drives Found" -msgstr "Keine Laufwerke gefunden" - -#: ../partedUtils.py:660 -msgid "" -"An error has occurred - no valid devices were found on which to create new " -"file systems. Please check your hardware for the cause of this problem." -msgstr "" -"Ein Fehler trat auf. - Es wurden keine Laufwerke gefunden, auf welche das " -"Dateisystem erstellt werden könnte. Bitte überprüfen Sie ihre Hardware für " -"die Ursache des Problems." - -#: ../partIntfHelpers.py:50 -#, python-format -msgid "" -"The mount point %s is invalid. Mount points must start with '/' and cannot " -"end with '/', and must contain printable characters and no spaces." -msgstr "" -"Der Einhängepunkt %s ist ungültig. Einhängepunkte müssen mit einem '/' " -"beginnen und dürfen nicht mit einem '/' enden. Ebenso dürfen sie nur " -"druckbare Zeichen enthalten, jedoch keine Leerzeichen." - -#: ../partIntfHelpers.py:57 -msgid "Please specify a mount point for this partition." -msgstr "Geben Sie einen Einhängepunkt für diese Partition an." - -#: ../partIntfHelpers.py:74 ../partIntfHelpers.py:80 ../partIntfHelpers.py:90 -#: ../partIntfHelpers.py:111 -msgid "Unable To Delete" -msgstr "" - -#: ../partIntfHelpers.py:75 -msgid "You must first select a partition to delete." -msgstr "Sie müssen zuerste eine Partition auswählen um diese zu entfernen." - -#: ../partIntfHelpers.py:81 -msgid "You cannot delete free space." -msgstr "Sie können keinen freien Platz löschen." - -#: ../partIntfHelpers.py:91 -#, python-format -msgid "" -"You cannot delete this partition, as it is an extended partition which " -"contains %s" -msgstr "" -"Sie können diese Partition nicht löschen, da sie eine erweiterte Partition " -"ist, welche %s enthält." - -#: ../partIntfHelpers.py:106 -msgid "This partition is holding the data for the hard drive install." -msgstr "Diese Partition beinhaltet die Daten für die Festplatten-Installation." - -#: ../partIntfHelpers.py:112 -msgid "" -"You cannot delete this partition:\n" -"\n" -msgstr "" -"Sie können diese Partition nicht löschen:\n" -"\n" - -#: ../partIntfHelpers.py:146 ../partIntfHelpers.py:391 -msgid "Confirm Delete" -msgstr "Löschen bestätigen" - -#: ../partIntfHelpers.py:147 -#, python-format -msgid "You are about to delete all partitions on the device '/dev/%s'." -msgstr "" -"Sie sind im Begriff alle Partitionen auf dem Laufwerk '/dev/%s' zu löschen." - -#: ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 -msgid "_Delete" -msgstr "_Löschen" - -#: ../partIntfHelpers.py:206 -msgid "Notice" -msgstr "Hinweis" - -#: ../partIntfHelpers.py:207 -#, python-format -msgid "" -"The following partitions were not deleted because they are in use:\n" -"\n" -"%s" -msgstr "" -"Die folgenden Partitionen wurden nicht entfert, weil sie in Verwendung " -"sind:\n" -"\n" -"%s" - -#: ../partIntfHelpers.py:222 ../partIntfHelpers.py:238 -#: ../partIntfHelpers.py:249 -msgid "Unable To Edit" -msgstr "" - -#: ../partIntfHelpers.py:223 -msgid "You must select a partition to edit" -msgstr "Sie müssen eine Partition auswählen um diese zu editieren" - -#: ../partIntfHelpers.py:239 -#, python-format -msgid "" -"You cannot edit this partition, as it is an extended partition which " -"contains %s" -msgstr "" - -#: ../partIntfHelpers.py:250 -msgid "" -"You cannot edit this partition:\n" -"\n" -msgstr "" - -#: ../partIntfHelpers.py:272 -msgid "Format as Swap?" -msgstr "Als Swap formatieren?" - -#: ../partIntfHelpers.py:273 -#, python-format -msgid "" -"/dev/%s has a partition type of 0x82 (Linux swap) but does not appear to be " -"formatted as a Linux swap partition.\n" -"\n" -"Would you like to format this partition as a swap partition?" -msgstr "" - -#: ../partIntfHelpers.py:288 -#, python-format -msgid "You need to select at least one hard drive to install %s." -msgstr "" - -#: ../partIntfHelpers.py:293 -msgid "" -"You have chosen to use a pre-existing partition for this installation " -"without formatting it. We recommend that you format this partition to make " -"sure files from a previous operating system installation do not cause " -"problems with this installation of Linux. However, if this partition " -"contains files that you need to keep, such as home directories, then " -"continue without formatting this partition." -msgstr "" - -#: ../partIntfHelpers.py:301 -msgid "Format?" -msgstr "Formatieren?" - -#: ../partIntfHelpers.py:302 -msgid "_Modify Partition" -msgstr "_Bearbeite Partition" - -#: ../partIntfHelpers.py:302 -msgid "Do _Not Format" -msgstr "_Nicht formatieren" - -#: ../partIntfHelpers.py:311 -msgid "Error with Partitioning" -msgstr "" - -#: ../partIntfHelpers.py:312 -#, python-format -msgid "" -"The following critical errors exist with your requested partitioning scheme. " -"These errors must be corrected prior to continuing with your install of %s.\n" -"\n" -"%s" -msgstr "" - -#: ../partIntfHelpers.py:326 -msgid "Partitioning Warning" -msgstr "Partitionierungswarnung" - -#: ../partIntfHelpers.py:327 -#, python-format -msgid "" -"The following warnings exist with your requested partition scheme.\n" -"\n" -"%s\n" -"\n" -"Would you like to continue with your requested partitioning scheme?" -msgstr "" - -#: ../partIntfHelpers.py:340 -msgid "" -"The following pre-existing partitions have been selected to be formatted, " -"destroying all data." -msgstr "" - -#: ../partIntfHelpers.py:342 -msgid "" -"Select 'Yes' to continue and format these partitions, or 'No' to go back and " -"change these settings." -msgstr "" - -#: ../partIntfHelpers.py:348 -msgid "Format Warning" -msgstr "Formatierungswarnung" - -#: ../partIntfHelpers.py:387 -#, python-format -msgid "You are about to delete the /dev/%s partition." -msgstr "Sie sind dabei die Partition /dev/%s zu löschen." - -#: ../partIntfHelpers.py:389 -msgid "The partition you selected will be deleted." -msgstr "Die ausgewählte Partition wird gelöscht." - -#: ../partIntfHelpers.py:398 -msgid "Confirm Reset" -msgstr "" - -#: ../partIntfHelpers.py:399 -msgid "" -"Are you sure you want to reset the partition table to its original state?" -msgstr "" - -#: ../partitioning.py:36 -msgid "Installation cannot continue." -msgstr "" - -#: ../partitioning.py:37 -msgid "" -"The partitioning options you have chosen have already been activated. You " -"can no longer return to the disk editing screen. Would you like to continue " -"with the installation process?" -msgstr "" - -#: ../partitioning.py:65 -msgid "Low Memory" -msgstr "Wenig Arbeitsspeicher" - -#: ../partitioning.py:66 -msgid "" -"As you don't have much memory in this machine, we need to turn on swap space " -"immediately. To do this we'll have to write your new partition table to the " -"disk immediately. Is that OK?" -msgstr "" -"Da sich in dem System nicht ausreichend Arbeitsspeicher befindet ist es " -"nötig den Swap sofort zu aktivieren. Dazu muss die neue Partitionstabelle " -"jetzt geschrieben werden. Ist das OK?" - -#: ../partitions.py:311 -#, python-format -msgid "" -"You have not defined a root partition (/), which is required for " -"installation of %s to continue." -msgstr "" -"Sie haben keine Root-Partition (/) angegeben, welche jedoch für die " -"Installation von %s notwendig ist." - -#: ../partitions.py:316 -#, python-format -msgid "" -"Your root partition is less than 250 megabytes which is usually too small to " -"install %s." -msgstr "" - -#: ../partitions.py:333 -msgid "" -"Your boot partition isn't on one of the first four partitions and thus won't " -"be bootable." -msgstr "" -"Ihre Boot-Partition ist nicht eine der ersten vier Partitionen auf dem " -"Datenträger und wird daher nicht bootbar sein." - -#: ../partitions.py:342 -#, python-format -msgid "" -"Your %s partition is less than %s megabytes which is lower than recommended " -"for a normal %s install." -msgstr "" -"Ihre %s-Partition ist kleiner als %s Megabytes, was für eine normale " -"Installation von %s nicht empfohlen ist." - -#: ../partitions.py:374 -msgid "" -"Installing on a USB device. This may or may not produce a working system." -msgstr "" -"Sie installieren auf einem USB-Laufwerk, was kein funktionierendes System " -"produzieren könnte." - -#: ../partitions.py:378 -msgid "" -"Installing on a FireWire device. This may or may not produce a working " -"system." -msgstr "" -"Sie installieren auf einem Firewire-Laufwerk, was kein funktionierendes " -"System produzieren könnte." - -#: ../partitions.py:391 -msgid "" -"You have not specified a swap partition. Although not strictly required in " -"all cases, it will significantly improve performance for most installations." -msgstr "Sie haben keine Swap-Partition angelegt." - -#: ../partitions.py:398 -#, python-format -msgid "" -"You have specified more than 32 swap devices. The kernel for %s only " -"supports 32 swap devices." -msgstr "" - -#: ../partitions.py:409 -#, python-format -msgid "" -"You have allocated less swap space (%dM) than available RAM (%dM) on your " -"system. This could negatively impact performance." -msgstr "" - -#: ../partitions.py:485 -msgid "the partition in use by the installer." -msgstr "" - -#: ../partRequests.py:182 -#, python-format -msgid "" -"This mount point is invalid. The %s directory must be on the / file system." -msgstr "" - -#: ../partRequests.py:185 -#, python-format -msgid "" -"The mount point %s cannot be used. It must be a symbolic link for proper " -"system operation. Please select a different mount point." -msgstr "" - -#: ../partRequests.py:192 -msgid "This mount point must be on a linux file system." -msgstr "" - -#: ../partRequests.py:212 -#, python-format -msgid "" -"The mount point \"%s\" is already in use, please choose a different mount " -"point." -msgstr "" - -#: ../partRequests.py:226 -#, python-format -msgid "" -"The size of the %s partition (%10.2f MB) exceeds the maximum size of %10.2f " -"MB." -msgstr "" - -#: ../partRequests.py:414 -#, python-format -msgid "" -"The size of the requested partition (size = %s MB) exceeds the maximum size " -"of %s MB." -msgstr "" - -#: ../partRequests.py:419 -#, python-format -msgid "The size of the requested partition is negative! (size = %s MB)" -msgstr "" - -#: ../partRequests.py:423 -msgid "Partitions can't start below the first cylinder." -msgstr "" - -#: ../partRequests.py:426 -msgid "Partitions can't end on a negative cylinder." -msgstr "" - -#: ../tui_bootloader.py:27 -msgid "Which boot loader would you like to use?" -msgstr "" - -#: ../tui_bootloader.py:37 -msgid "Use GRUB Boot Loader" -msgstr "" - -#: ../tui_bootloader.py:38 -msgid "No Boot Loader" -msgstr "" - -#: ../tui_bootloader.py:41 ../tui_bootloader.py:103 ../tui_bootloader.py:161 -#: ../tui_bootloader.py:278 ../tui_bootloader.py:383 -msgid "Boot Loader Configuration" -msgstr "" - -#: ../tui_bootloader.py:58 -msgid "Skip Boot Loader" -msgstr "" - -#: ../tui_bootloader.py:59 -msgid "" -"You have elected not to install any boot loader, which is not recommended " -"unless you have an advanced need. Booting your system into Linux directly " -"from the hard drive almost always requires a boot loader.\n" -"\n" -"Are you sure you want to skip boot loader installation?" -msgstr "" - -#: ../tui_bootloader.py:88 -msgid "" -"A few systems need to pass special options to the kernel at boot time to " -"function properly. If you need to pass boot options to the kernel, enter " -"them now. If you don't need any or aren't sure, leave this blank." -msgstr "" - -#: ../tui_bootloader.py:97 -msgid "Force use of LBA32 (not normally required)" -msgstr "" - -#: ../tui_bootloader.py:120 -msgid "" -"If LBA32 is not supported by your system's BIOS, forcing its use can prevent " -"your machine from booting.\n" -"\n" -"Would you like to continue and force LBA32 mode?" -msgstr "" - -#: ../tui_bootloader.py:162 -msgid "Where do you want to install the boot loader?" -msgstr "Wo möchten Sie den Bootloader installieren?" - -#: ../tui_bootloader.py:188 ../tui_bootloader.py:255 ../tui_partition.py:844 -msgid "Device" -msgstr "Partition" - -#: ../tui_bootloader.py:189 ../tui_bootloader.py:255 -msgid "Boot label" -msgstr "" - -#: ../tui_bootloader.py:193 -msgid "Clear" -msgstr "" - -#: ../tui_bootloader.py:201 -msgid "Edit Boot Label" -msgstr "" - -#: ../tui_bootloader.py:219 ../tui_bootloader.py:224 -msgid "Invalid Boot Label" -msgstr "Ungültiges Label" - -#: ../tui_bootloader.py:220 -msgid "Boot label may not be empty." -msgstr "" - -#: ../tui_bootloader.py:225 -msgid "Boot label contains illegal characters." -msgstr "" - -#: ../tui_bootloader.py:255 -msgid "Default" -msgstr "Standard" - -#: ../tui_bootloader.py:273 -#, python-format -msgid "" -"The boot manager %s uses can boot other operating systems as well. Please " -"tell me what partitions you would like to be able to boot and what label you " -"want to use for each of them." -msgstr "" - -#: ../tui_bootloader.py:286 -msgid "" -" select | select default | delete | next screen>" -msgstr ",<+>,<-> Auswahl | Laufwerk hinzufügen | Weiter" - -#: ../tui_bootloader.py:335 -msgid "Cannot Delete" -msgstr "Kann nicht löschen" - -#: ../tui_bootloader.py:336 -#, python-format -msgid "" -"This boot target cannot be deleted because it is for the %s system you are " -"about to install." -msgstr "" - -#: ../tui_bootloader.py:378 -msgid "" -"A boot loader password prevents users from passing arbitrary options to the " -"kernel. For highest security, you should set a password, but a password is " -"not necessary for more casual users." -msgstr "" - -#: ../tui_bootloader.py:386 -msgid "Use a GRUB Password" -msgstr "Benutze ein GRUB-Passwort" - -#: ../tui_bootloader.py:399 -msgid "Boot Loader Password:" -msgstr "Bootloader-Passwort:" - -#: ../tui_bootloader.py:400 -msgid "Confirm:" -msgstr "Bestätigen:" - -#: ../tui_bootloader.py:429 -msgid "Passwords Do Not Match" -msgstr "Passwörter stimmen nicht überein" - -#: ../tui_bootloader.py:430 -msgid "Passwords do not match" -msgstr "Die Passwörter stimmen nicht überein" - -#: ../tui_bootloader.py:434 -msgid "Password Too Short" -msgstr "Das Passwort ist zu kurz" - -#: ../tui_bootloader.py:435 -msgid "Boot loader password is too short" -msgstr "Das Bootloader-Passwort ist zu kurz" - -#: ../tui_bootloader.py:440 -msgid "" -"Your boot loader password is shorter than six characters. We recommend a " -"longer boot loader password.\n" -"\n" -"Would you like to continue with this password?" -msgstr "" -"Ihr Bootloader-Passwort ist kürzer als 6 Zeichen. Wir empfehlen einen " -"längeren Schlüssel zu nehmen.\n" -"\n" -"Möchten Sie trotzdem mit dem eingegebenen Passwort fortfahren?" - -#: ../tui_complete.py:25 -msgid "" -"Press to end the installation process.\n" -"\n" -msgstr "" -"Drücken Sie um den Installationprozess zu beenden.\n" -"\n" - -#: ../tui_complete.py:26 -msgid " to exit" -msgstr " zum Beenden" - -#: ../tui_complete.py:30 -#, python-format -msgid "" -"Congratulations, your %s installation is complete.\n" -"\n" -"%s%s" -msgstr "" -"Herzlichen Glückwunsch, die Installation von %s wurde erfolgreich beendet.\n" -"\n" -"%s%s" - -#: ../tui_complete.py:33 -#, python-format -msgid "" -"For information on errata (updates and bug fixes), visit %s.\n" -"\n" -"Information on using your system is available in the %s wiki at %s." -msgstr "" -"Für weitere Informationen über Bugfixes besuchen Sie %s.\n" -"\n" -"Informationen über das System erhalten Sie im %s-Wiki auf %s." - -#: ../tui_complete.py:39 -msgid "Complete" -msgstr "Fertig" - -#: ../tui_confirm.py:23 -msgid "Installation to begin" -msgstr "" - -#: ../tui_confirm.py:24 -msgid "" -"Now, we got all information we need for installation. If there is something " -"you want change you can still go back. If not choose OK to start." -msgstr "" - -#: ../tui_confirm.py:34 -msgid "Reboot?" -msgstr "Neustarten?" - -#: ../tui_confirm.py:35 -msgid "The system will be rebooted now." -msgstr "Ihr System wird jetzt neu gestartet." - -#: ../tui_keyboard.py:36 -msgid "Keyboard Selection" -msgstr "Tastaturauswahl" - -#: ../tui_keyboard.py:37 -msgid "Which model keyboard is attached to this computer?" -msgstr "Welches Tastaturmodell ist an den Computer angeschlossen?" - -#: ../tui_language.py:39 -msgid "Language Selection" -msgstr "Sprachauswahl" - -#: ../tui_language.py:40 -msgid "What language would you like to use during the installation process?" -msgstr "Welche Sprache möchten Sie für den Installationsprozess nutzen?" - -#: ../tui_network.py:39 -msgid "Hostname" -msgstr "Hostname" - -#: ../tui_network.py:42 -msgid "" -"Please name this computer. The hostname identifies the computer on a " -"network." -msgstr "" - -#: ../tui_network.py:63 ../tui_network.py:70 -msgid "Invalid Hostname" -msgstr "Ungültiger Hostname" - -#: ../tui_network.py:64 -msgid "You have not specified a hostname." -msgstr "Sie haben keinen Hostnamen eingegeben." - -#: ../tui_network.py:71 -#, python-format -msgid "" -"The hostname \"%s\" is not valid for the following reason:\n" -"\n" -"%s" -msgstr "" - -#: ../tui_partition.py:41 -msgid "Must specify a value" -msgstr "Bitte geben Sie einen Wert ein" - -#: ../tui_partition.py:44 -msgid "Requested value is not an integer" -msgstr "Der eingegebene Wert ist kein Integer" - -#: ../tui_partition.py:46 -msgid "Requested value is too large" -msgstr "Der eingegebene Wert ist zu groß" - -#: ../tui_partition.py:95 ../tui_partition.py:132 -msgid "Free space" -msgstr "Freier Platz" - -#: ../tui_partition.py:97 -msgid "Extended" -msgstr "Erweitert" - -#: ../tui_partition.py:111 -msgid "None" -msgstr "Keins" - -#: ../tui_partition.py:178 -#, python-format -msgid "Could not allocate requested partitions: %s." -msgstr "Konnte die Partition nicht finden: %s." - -#: ../tui_partition.py:182 -#, python-format -msgid "Warning: %s" -msgstr "Warnung: %s" - -#: ../tui_partition.py:183 -msgid "Modify Partition" -msgstr "Partition bearbeiten" - -#: ../tui_partition.py:183 -msgid "Add anyway" -msgstr "Trotzdem hinzufügen" - -#: ../tui_partition.py:201 ../tui_partition.py:203 ../tui_partition.py:205 -#: ../tui_partition.py:230 -msgid "" -msgstr "" - -#: ../tui_partition.py:220 -msgid "Mount Point:" -msgstr "Einhängepunkt:" - -#: ../tui_partition.py:239 -msgid "File System type:" -msgstr "Dateisystem-Typ:" - -#: ../tui_partition.py:270 -msgid "Allowable Drives:" -msgstr "" - -#: ../tui_partition.py:292 ../tui_partition.py:371 ../tui_partition.py:419 -msgid "Size (MB):" -msgstr "Größe (MB):" - -#: ../tui_partition.py:324 -msgid "Fixed Size:" -msgstr "Feste Größe:" - -#: ../tui_partition.py:326 -msgid "Fill maximum size of (MB):" -msgstr "Maximale Größe in MB:" - -#: ../tui_partition.py:330 -msgid "Fill all available space:" -msgstr "Verfügbaren Speicherplatz ausfüllen:" - -#: ../tui_partition.py:351 -msgid "Start Cylinder:" -msgstr "Startzylinder:" - -#: ../tui_partition.py:364 -msgid "End Cylinder:" -msgstr "Endzylinder:" - -#: ../tui_partition.py:386 -msgid "Number of spares?" -msgstr "" - -#: ../tui_partition.py:400 -msgid "File System Type:" -msgstr "Dateisystem:" - -#: ../tui_partition.py:413 -msgid "File System Label:" -msgstr "Dateisystemlabel:" - -#: ../tui_partition.py:424 -msgid "File System Option:" -msgstr "Dateisystemoption:" - -#: ../tui_partition.py:427 ../tui_partition.py:652 -#, python-format -msgid "Format as %s" -msgstr "Formatieren als %s" - -#: ../tui_partition.py:429 ../tui_partition.py:654 -#, python-format -msgid "Migrate to %s" -msgstr "Migrieren zu %s" - -#: ../tui_partition.py:431 ../tui_partition.py:656 -msgid "Leave unchanged" -msgstr "Beibehalten" - -#: ../tui_partition.py:446 ../tui_partition.py:629 -msgid "File System Options" -msgstr "Dateisystemoptionen" - -#: ../tui_partition.py:449 -msgid "" -"Please choose how you would like to prepare the file system on this " -"partition." -msgstr "" -"Bitte wählen Sie, wie sie das Dateisystem für diese Partition vorbereiten " -"wollen." - -#: ../tui_partition.py:457 ../tui_partition.py:607 -msgid "Check for bad blocks" -msgstr "Untersuche nach defekten Blöcken" - -#: ../tui_partition.py:461 -msgid "Leave unchanged (preserve data)" -msgstr "Beibehalten (erhält die Daten)" - -#: ../tui_partition.py:470 -msgid "Format as:" -msgstr "Formatieren als:" - -#: ../tui_partition.py:489 -msgid "Migrate to:" -msgstr "Migrieren nach:" - -#: ../tui_partition.py:559 -msgid "Add Partition" -msgstr "Partition hinzufügen" - -#: ../tui_partition.py:601 -msgid "Force to be a primary partition" -msgstr "Erzwinge primäre Partition" - -#: ../tui_partition.py:684 ../tui_partition.py:738 -msgid "Invalid Entry for Partition Size" -msgstr "Ungültige Eingabe für die Partitionsgröße" - -#: ../tui_partition.py:696 -msgid "Invalid Entry for Maximum Size" -msgstr "Ungültige Eingabe für die maximale Größe" - -#: ../tui_partition.py:716 -msgid "Invalid Entry for Starting Cylinder" -msgstr "Ungültige Eingabe für den Startzylinder" - -#: ../tui_partition.py:730 -msgid "Invalid Entry for End Cylinder" -msgstr "Ungültige Eingabe für den Endzylinder" - -#: ../tui_partition.py:748 ../tui_partition.py:769 -msgid "Error With Request" -msgstr "Fehler im Request" - -#: ../tui_partition.py:838 -msgid "Partitioning" -msgstr "Partitionierung" - -#: ../tui_partition.py:844 -msgid "Start" -msgstr "Startsektor" - -#: ../tui_partition.py:844 -msgid "End" -msgstr "Endsektor" - -#: ../tui_partition.py:844 -msgid "Size" -msgstr "Größe" - -#: ../tui_partition.py:844 -msgid "Type" -msgstr "Typ" - -#: ../tui_partition.py:844 -msgid "Mount Point" -msgstr "Mount-Point" - -#: ../tui_partition.py:848 -msgid "New" -msgstr "Neu" - -#: ../tui_partition.py:850 -msgid "Delete" -msgstr "Löschen" - -#: ../tui_partition.py:853 -msgid "" -" F1-Help F2-New F3-Edit F4-Delete F5-Reset F12-OK " -msgstr " F1-Hilfe F2-Neu F3-Bearbeiten F4-Löschen F5-Zurücksetzen F12-OK" - -#: ../tui_partition.py:883 -msgid "No Root Partition" -msgstr "Keine Root-Partition" - -#: ../tui_partition.py:884 -msgid "Installation requires a / partition." -msgstr "Die Installation erfordert die Konfiguration einer /-Partition." - -#: ../tui_partition.py:923 -msgid "Partitioning Type" -msgstr "Partitionstyp" - -#: ../tui_partition.py:925 -msgid "" -"Installation requires partitioning of your hard drive. The default layout " -"is reasonable for most users. You can either choose to use this or create " -"your own." -msgstr "" -"Für die Installation ist es nötig die Festplatten passend zu partitionieren. " -"Das Standardlayout genügt für die meisten Nutzer. Experten können eigene " -"Anpassungen vornehmen." - -#: ../tui_partition.py:932 -msgid "Remove all partitions on selected drives and create default layout" -msgstr "Alle Partitionen löschen und Standardlayout erstellen" - -#: ../tui_partition.py:933 -msgid "Create custom layout" -msgstr "Benutzerdefiniertes Layout erstellen" - -#: ../tui_partition.py:947 -msgid "Which drive(s) do you want to use for this installation?" -msgstr "Welche(s) Laufwerk(e) möchten Sie für die Installation nutzen?" - -#: ../tui_partition.py:960 -msgid ",<+>,<-> selection | Add drive | next screen" -msgstr ",<+>,<-> Auswahl | Laufwerk hinzufügen | Weiter" - -#: ../tui_partition.py:1029 -msgid "Review Partition Layout" -msgstr "Ansicht des Partitionslayout" - -#: ../tui_partition.py:1030 -msgid "Review and modify partitioning layout?" -msgstr "Möchten Sie das Partitionslayout ansehen oder bearbeiten?" - -#: ../tui_progress.py:52 -msgid "File Installation" -msgstr "Dateiinstallation" - -#: ../tui.py:118 -msgid "Exception Occurred" -msgstr "Fehler aufgetreten" - -#: ../tui.py:189 -msgid "Error!" -msgstr "Fehler!" - -#: ../tui.py:190 -#, python-format -msgid "" -"An error occurred when attempting to load an pomona interface component.\n" -"\n" -"className = %s\n" -"\n" -"Error: %s" -msgstr "" - -#: ../tui.py:195 ../tui.py:197 -msgid "Exit" -msgstr "Ende" - -#: ../tui.py:195 ../tui.py:391 -msgid "Retry" -msgstr "Wiederholen" - -#: ../tui.py:220 -msgid "Cancelled" -msgstr "Abgebrochen" - -#: ../tui.py:221 -msgid "I can't go to the previous step from here. You will have to try again." -msgstr "" -"Es konnte nicht zum vorhergeneden Installationsschritt gewechselt werden. " -"Bitte wiederholen Sie den Schritt." - -#: ../tui.py:235 -#, python-format -msgid "Welcome to %s" -msgstr "Willkommen bei %s" - -#: ../tui.py:238 -msgid "" -" for help | between elements | selects | next screen" -msgstr "" - -#: ../tui.py:240 -msgid "" -" / between elements | selects | next " -"screen" -msgstr "" - -#: ../tui.py:285 -msgid "Help not available" -msgstr "Keine Hilfe verfügbar" - -#: ../tui.py:286 -msgid "No help is available for this step of the install." -msgstr "Es ist keine Hilfe zu diesem Installationsschritt verfügbar." - -#: ../tui.py:387 -msgid "Fix" -msgstr "Korrigieren" - -#: ../tui.py:392 -msgid "Ignore" -msgstr "Ignorieren" - -#: ../tui_timezone.py:63 -msgid "In which time zone are you located?" -msgstr "In welcher Zeitzone befinden Sie sich?" - -#: ../tui_timezone.py:78 -msgid "System clock uses UTC" -msgstr "Die Systemuhr ist auf UTC eingestellt." - -#: ../tui_timezone.py:81 -msgid "Time Zone Selection" -msgstr "Zeitzonenauswahl" - -#: ../tui_userauth.py:29 -msgid "Root Password" -msgstr "Root-Passwort" - -#: ../tui_userauth.py:31 -msgid "" -"Pick a root password. You must type it twice to ensure you know it and do " -"not make a typing mistake. Remember that the root password isa critical part " -"of system security!" -msgstr "" -"Wählen Sie ein Root-Passwort. Es muss zweimal eingegeben werden um " -"Tippfehler zu vermeiden. Bedenken Sie: Das Root-Passwort ist ein kritischer " -"Teil der Systemsicherheit." - -#: ../tui_userauth.py:41 -msgid "Password:" -msgstr "Passwort:" - -#: ../tui_userauth.py:42 -msgid "Password (confirm):" -msgstr "Passwort (bestätigen):" - -#: ../tui_userauth.py:59 -msgid "Password Length" -msgstr "Passwortlänge" - -#: ../tui_userauth.py:60 -msgid "The root password must be at least 6 characters long." -msgstr "Das Root-Passwort muss mindestens 6 Zeichen lang sein." - -#: ../tui_userauth.py:63 -msgid "Password Mismatch" -msgstr "Passwort-Fehler" - -#: ../tui_userauth.py:64 -msgid "The passwords you entered were different. Please try again." -msgstr "Die eingegebenen Passwörter stimmen nicht überein." - -#: ../tui_userauth.py:67 -msgid "Error with Password" -msgstr "Fehler im Passwort" - -#: ../tui_userauth.py:68 -msgid "" -"Requested password contains non-ASCII characters, which are not allowed." -msgstr "" -"Das eingegebene Passwort enthält nicht-ASCII-Zeichen, welche nicht erlaubt " -"sind." - -#: ../tui_welcome.py:12 -#, python-format -msgid "%s" -msgstr "%s" - -#: ../tui_welcome.py:13 -#, python-format -msgid "" -"Welcome to %s!\n" -"\n" -msgstr "" -"Willkommen bei %s!\n" -"\n" - -#. generated from lang-table -msgid "English" -msgstr "Englisch" - -#. generated from lang-table -msgid "German" -msgstr "Deutsch" - -#. generated from lang-table -msgid "Danish" -msgstr "Dänisch" - -#~ msgid "Checking for Bad Blocks" -#~ msgstr "Untersuche nach defekten Blöcken" - -#~ msgid "Probing CDROM" -#~ msgstr "Suche CDROM" - -#~ msgid "Searching for a valid disc on /dev/%s..." -#~ msgstr "Suche nach einer gültigen CD in /dev/%s..." - -#~ msgid "Wrong CDROM" -#~ msgstr "Falsche CDROM" - -#~ msgid "That's not the correct %s CDROM in /dev/%s." -#~ msgstr "" -#~ "Bei der eingelegten CDROM in /dev/%s handelt es sich nicht um die " -#~ "richtige CDROM für %s." - -#~ msgid "Insert CDROM" -#~ msgstr "CDROM einlegen" - -#~ msgid "Please insert the %s disc to continue." -#~ msgstr "Bitte legen Sie die %s CD ein um fortzufahren." - -#~ msgid "IPFire" -#~ msgstr "IPFire" - -#~ msgid "Disk Partitioning Setup" -#~ msgstr "Plattenpartitionierungssetup" - -#~ msgid "Autopartition" -#~ msgstr "Autopartitionierung" - -#~ msgid "Disk Druid" -#~ msgstr "Disk Druid" - -#~ msgid "Dump Written" -#~ msgstr "Dump wurde geschrieben" - -#~ msgid "Dump Not Written" -#~ msgstr "Dump wurde nicht geschrieben" - -#~ msgid "Re_try" -#~ msgstr "Wiederholen" - -#~ msgid "Source Type" -#~ msgstr "Quelltyp" - -#~ msgid "" -#~ "In installation you have to choose a source for the installation files. " -#~ "Mostly you will choose the disc here, but you are also able to install by " -#~ "HTTP, FTP hard disk or usb-key." -#~ msgstr "" -#~ "Bei der Installation haben Sie die Auswahl zwischen verschiedenen " -#~ "Quellmedien. Die Meisten werden hier die CD auswählen, jedoch ist auch " -#~ "eine Installation über HTTP, FTP, Festplatte oder USB-Stick möglich." - -#~ msgid "Install Disc" -#~ msgstr "Installations-CD" - -#~ msgid "Internet Source" -#~ msgstr "Internet-Quelle" - -#~ msgid "External Drive" -#~ msgstr "Externes Laufwerk" - -#~ msgid "No CDROM found" -#~ msgstr "Keine Laufwerke gefunden" - -#~ msgid "" -#~ "You choosed to install from an installtion disc, but there was no cdrom " -#~ "drive found on the system. Please choose another installation method." -#~ msgstr "" -#~ "Sie haben eine Installation mit CD ausgewählt, jedoch wurde kein CDROM-" -#~ "Laufwerk im System gefunden. Bitte wählen Sie eine andere " -#~ "Installationsmethode." - -#~ msgid "Source URL" -#~ msgstr "Quell-URL" - -#~ msgid "" -#~ "Enter a host you get the files from.You also must enter a path where the " -#~ "installer finds the files in." -#~ msgstr "" -#~ "Bitte geben Sie einen Server ein, von dem Sie die Installationsdateien " -#~ "beziehen. Weiterhin müssen Sie einen Pfad eingeben, in dem der Installer " -#~ "die Dateien auf dem Server findet." - -#~ msgid "Path:" -#~ msgstr "Pfad:" - -#~ msgid "Wrong Protocol" -#~ msgstr "Ungültiges Protokoll" - -#~ msgid "" -#~ "You entered a protocol that is not supported by Pomona. There are only " -#~ "http:// and ftp:// available." -#~ msgstr "" -#~ "Sie haben einen Protokolltyp eingegeben, der nicht von Pomona unterstützt " -#~ "wird. Unterstützt werden http:// und ftp://." - -#, fuzzy -#~ msgid "Syntax Error" -#~ msgstr "Fehler" - -#~ msgid "The path of the URL must end with a /." -#~ msgstr "Der Pfad muss mit einem / enden." - -#~ msgid "" -#~ "When we tested your given URL there was an error.\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Bei einem Test der eingegebenen URL trat ein Fehler auf.\n" -#~ "\n" -#~ "%s" - -#~ msgid "Downloading" -#~ msgstr "Download" - -#~ msgid "Connecting..." -#~ msgstr "Verbinde..." - -#~ msgid "Retrieving %s" -#~ msgstr "Lade %s" - -#~ msgid "" -#~ "The file %s cannot be opened. This is due to a missing file or perhaps a " -#~ "corrupt package. Please verify your mirror contains all required " -#~ "packages, and try using a different one.\n" -#~ "\n" -#~ "If you reboot, your system will be left in an inconsistent state that " -#~ "will likely require reinstallation.\n" -#~ "\n" -#~ msgstr "" -#~ "Die Datei %s konnte nicht geöffnet werden. Es könnte sein, dass diese " -#~ "garnicht vorhanden oder beschädigt ist. Bitte überprüfen Sie ihren Server " -#~ "oder nutzen Sie einen anderen.\n" -#~ "\n" -#~ "Wenn Sie jetzt neustarten wird das System in einem inkonsistenten Zustand " -#~ "bleiben und eine Neuinstallation nötig sein.\n" -#~ "\n" - -#, fuzzy -#~ msgid "Preparing transaction from installation source..." -#~ msgstr "Starte Textinstallation..." - -#, fuzzy -#~ msgid "Re_boot" -#~ msgstr "Neustarten" - -#, fuzzy -#~ msgid "_Retry" -#~ msgstr "Wiederholen" - -#, fuzzy -#~ msgid "Loading %s" -#~ msgstr "Warnung" diff --git a/pkgs/core/pomona/src/po/pomona.pot b/pkgs/core/pomona/src/po/pomona.pot deleted file mode 100644 index d1757a55c..000000000 --- a/pkgs/core/pomona/src/po/pomona.pot +++ /dev/null @@ -1,2161 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-17 19:28+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../autopart.py:872 -#, python-format -msgid "" -"Error resizing partition %s.\n" -"\n" -"%s" -msgstr "" - -#: ../autopart.py:875 -#, python-format -msgid "Start of partition %s was moved when resizing" -msgstr "" - -#: ../autopart.py:967 -msgid "Could not allocate cylinder-based partitions as primary partitions.\n" -msgstr "" - -#: ../autopart.py:972 -msgid "Could not allocate partitions as primary partitions.\n" -msgstr "" - -#: ../autopart.py:977 -msgid "Could not allocate cylinder-based partitions.\n" -msgstr "" - -#: ../autopart.py:1042 -#, python-format -msgid "" -"Boot partition %s doesn't belong to a BSD disk label. SRM won't be able to " -"boot from this partition. Use a partition belonging to a BSD disk label or " -"change this device disk label to BSD." -msgstr "" - -#: ../autopart.py:1044 -#, python-format -msgid "" -"Boot partition %s doesn't belong to a disk with enough free space at its " -"beginning for the bootloader to live on. Make sure that there's at least 5MB " -"of free space at the beginning of the disk that contains /boot" -msgstr "" - -#: ../autopart.py:1046 -#, python-format -msgid "" -"Boot partition %s isn't a VFAT partition. EFI won't be able to boot from " -"this partition." -msgstr "" - -#: ../autopart.py:1048 -msgid "" -"The boot partition must entirely be in the first 4GB of the disk. " -"OpenFirmware won't be able to boot this installation." -msgstr "" - -#: ../autopart.py:1050 -#, python-format -msgid "" -"Boot partition %s is not a Linux filesystem, such as ext3. The system won't " -"be able to boot from this partition." -msgstr "" - -#: ../autopart.py:1053 -#, python-format -msgid "" -"Boot partition %s may not meet booting constraints for your architecture." -msgstr "" - -#: ../autopart.py:1078 -#, python-format -msgid "" -"Adding this partition would not leave enough disk space for already " -"allocated logical volumes in %s." -msgstr "" - -#: ../autopart.py:1231 -msgid "Requested Partition Does Not Exist" -msgstr "" - -#: ../autopart.py:1232 -#, python-format -msgid "" -"Unable to locate partition %s to use for %s.\n" -"\n" -"Press 'OK' to exit the installer." -msgstr "" - -#: ../autopart.py:1257 -msgid "Requested Raid Device Does Not Exist" -msgstr "" - -#: ../autopart.py:1258 -#, python-format -msgid "" -"Unable to locate raid device %s to use for %s.\n" -"\n" -"Press 'OK' to exit the installer." -msgstr "" - -#: ../autopart.py:1287 -msgid "Requested Volume Group Does Not Exist" -msgstr "" - -#: ../autopart.py:1288 -#, python-format -msgid "" -"Unable to locate volume group %s to use for %s.\n" -"\n" -"Press 'OK' to exit the installer." -msgstr "" - -#: ../autopart.py:1325 -msgid "Requested Logical Volume Does Not Exist" -msgstr "" - -#: ../autopart.py:1326 -#, python-format -msgid "" -"Unable to locate logical volume %s to use for %s.\n" -"\n" -"Press 'OK' to exit the installer." -msgstr "" - -#: ../autopart.py:1460 ../autopart.py:1507 -msgid "Automatic Partitioning Errors" -msgstr "" - -#: ../autopart.py:1461 -#, python-format -msgid "" -"The following errors occurred with your partitioning:\n" -"\n" -"%s\n" -"\n" -"Press 'OK' to exit the installer." -msgstr "" - -#: ../autopart.py:1471 -msgid "Warnings During Automatic Partitioning" -msgstr "" - -#: ../autopart.py:1472 -#, python-format -msgid "" -"Following warnings occurred during automatic partitioning:\n" -"\n" -"%s" -msgstr "" - -#: ../autopart.py:1486 ../autopart.py:1503 -msgid "" -"\n" -"\n" -"Press 'OK' to exit the installer." -msgstr "" - -#: ../autopart.py:1487 ../tui_partition.py:177 -msgid "Error Partitioning" -msgstr "" - -#: ../autopart.py:1488 -#, python-format -msgid "" -"Could not allocate requested partitions: \n" -"\n" -"%s.%s" -msgstr "" - -#: ../autopart.py:1505 -msgid "" -"\n" -"\n" -"Press 'OK' to choose a different partitioning option." -msgstr "" - -#: ../autopart.py:1508 -#, python-format -msgid "" -"The following errors occurred with your partitioning:\n" -"\n" -"%s\n" -"\n" -"This can happen if there is not enough space on your hard drive(s) for the " -"installation. %s" -msgstr "" - -#: ../autopart.py:1519 -msgid "Unrecoverable Error" -msgstr "" - -#: ../autopart.py:1520 -msgid "Your system will now be rebooted." -msgstr "" - -#: ../autopart.py:1623 -msgid "" -"Automatic Partitioning sets partitions based on the selected installation " -"type. You also can customize the partitions once they have been created.\n" -"\n" -"The manual disk partitioning tool, Disk Druid, allows you to create " -"partitions in an interactive environment. You can set the file system types, " -"mount points, partition sizes, and more." -msgstr "" - -#: ../autopart.py:1634 -msgid "" -"Before automatic partitioning can be set up by the installation program, you " -"must choose how to use the space on your hard drives." -msgstr "" - -#: ../autopart.py:1639 -msgid "Remove all partitions on this system" -msgstr "" - -#: ../autopart.py:1640 -msgid "Remove all Linux partitions on this system" -msgstr "" - -#: ../autopart.py:1641 -msgid "Keep all partitions and use existing free space" -msgstr "" - -#: ../bootloader.py:697 -msgid "Bootloader" -msgstr "" - -#: ../bootloader.py:697 -msgid "Installing bootloader..." -msgstr "" - -#: ../bootloader.py:746 ../partedUtils.py:328 ../partedUtils.py:851 -#: ../partedUtils.py:979 ../tui_bootloader.py:119 ../tui_bootloader.py:439 -#: ../tui_partition.py:182 -msgid "Warning" -msgstr "" - -#: ../bootloader.py:747 -msgid "" -"No kernel packages were installed on your system. Your boot loader " -"configuration will not be changed." -msgstr "" - -#: ../constants.py:61 -msgid "" -"An unhandled exception has occurred. This is most likely a bug. Please " -"save a copy of the detailed exception and file a bug report" -msgstr "" - -#: ../constants.py:67 -msgid " with the provider of this software." -msgstr "" - -#: ../constants.py:71 -#, python-format -msgid " against pomona at %s" -msgstr "" - -#: ../constants.py:89 ../installer.py:93 ../tui_confirm.py:28 -#: ../tui_network.py:65 ../tui_network.py:74 ../tui.py:224 ../tui.py:390 -msgid "OK" -msgstr "" - -#: ../constants.py:93 ../partIntfHelpers.py:245 ../partIntfHelpers.py:536 -#: ../tui_bootloader.py:194 ../tui.py:103 ../tui.py:104 ../tui.py:393 -msgid "Cancel" -msgstr "" - -#: ../constants.py:97 ../partitions.py:130 ../partitions.py:260 -#: ../tui_confirm.py:28 ../tui_confirm.py:30 -msgid "Back" -msgstr "" - -#: ../constants.py:101 ../tui_bootloader.py:67 ../tui.py:388 -msgid "Yes" -msgstr "" - -#: ../constants.py:105 ../tui_bootloader.py:67 ../tui.py:389 -msgid "No" -msgstr "" - -#: ../constants.py:109 ../tui_bootloader.py:270 ../tui_partition.py:849 -msgid "Edit" -msgstr "" - -#: ../fsset.py:497 -msgid "Checking" -msgstr "" - -#: ../fsset.py:498 -#, python-format -msgid "Checking filesystem on %s..." -msgstr "" - -#: ../fsset.py:509 ../fsset.py:944 -msgid "Resizing" -msgstr "" - -#: ../fsset.py:510 ../fsset.py:945 -#, python-format -msgid "Resizing filesystem on %s..." -msgstr "" - -#: ../fsset.py:653 ../fsset.py:1536 ../fsset.py:1567 ../fsset.py:1643 -#: ../fsset.py:1711 ../fsset.py:1761 ../fsset.py:1850 ../fsset.py:1863 -#: ../partIntfHelpers.py:413 -msgid "Error" -msgstr "" - -#: ../fsset.py:654 -#, python-format -msgid "" -"An error occurred migrating %s to ext3. It is possible to continue without " -"migrating this file system if desired.\n" -"\n" -"Would you like to continue without migrating %s?" -msgstr "" - -#: ../fsset.py:1413 -msgid "RAID Device" -msgstr "" - -#: ../fsset.py:1416 -msgid "First sector of boot partition" -msgstr "" - -#: ../fsset.py:1417 -msgid "Master Boot Record (MBR)" -msgstr "" - -#: ../fsset.py:1537 -#, python-format -msgid "" -"An error occurred trying to initialize swap on device %s. This problem is " -"serious, and the install cannot continue.\n" -"\n" -"Press to exit the installer." -msgstr "" - -#: ../fsset.py:1566 -msgid "Skip" -msgstr "" - -#: ../fsset.py:1566 ../fsset.py:1830 ../fsset.py:2581 -msgid "_Exit installer" -msgstr "" - -#: ../fsset.py:1587 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"is a version 0 Linux swap partition. If you want to use this device, you " -"must reformat as a version 1 Linux swap partition. If you skip it, the " -"installer will ignore it during the installation." -msgstr "" - -#: ../fsset.py:1594 -msgid "Reformat" -msgstr "" - -#: ../fsset.py:1598 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"in your /etc/fstab file is currently in use as a software suspend partition, " -"which means your system is hibernating. To perform an upgrade, please shut " -"down your system rather than hibernating it." -msgstr "" - -#: ../fsset.py:1606 -#, python-format -msgid "" -"The swap device:\n" -"\n" -" /dev/%s\n" -"\n" -"in your /etc/fstab file is currently in use as a software suspend partition, " -"which means your system is hibernating. If you are performing a new install, " -"make sure the installer is set to format all swap partitions." -msgstr "" - -#: ../fsset.py:1616 -msgid "" -"\n" -"\n" -"Choose Skip if you want the installer to ignore this partition during the " -"upgrade. Choose Format to reformat the partition as swap space." -msgstr "" - -#: ../fsset.py:1621 -msgid "Format" -msgstr "" - -#: ../fsset.py:1627 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"Devices in /etc/fstab should be specified by label, not by device name.\n" -"\n" -"Press OK to exit the installer." -msgstr "" - -#: ../fsset.py:1632 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"The /etc/fstab on your upgrade partition does not reference a valid swap " -"partition.\n" -"\n" -"Press OK to exit the installer" -msgstr "" - -#: ../fsset.py:1638 -#, python-format -msgid "" -"Error enabling swap device %s: %s\n" -"\n" -"This most likely means this swap partition has not been initialized.\n" -"\n" -"Press OK to exit the installer." -msgstr "" - -#: ../fsset.py:1712 -#, python-format -msgid "" -"An error occurred trying to format %s. This problem is serious, and the " -"install cannot continue.\n" -"\n" -"Press to exit the installer." -msgstr "" - -#: ../fsset.py:1762 -#, python-format -msgid "" -"An error occurred trying to migrate %s. This problem is serious, and the " -"install cannot continue.\n" -"\n" -"Press to exit the installer." -msgstr "" - -#: ../fsset.py:1798 ../fsset.py:1807 -msgid "Invalid mount point" -msgstr "" - -#: ../fsset.py:1799 -#, python-format -msgid "" -"An error occurred when trying to create %s. Some element of this path is " -"not a directory. This is a fatal error and the install cannot continue.\n" -"\n" -"Press to exit the installer." -msgstr "" - -#: ../fsset.py:1808 -#, python-format -msgid "" -"An error occurred when trying to create %s: %s. This is a fatal error and " -"the install cannot continue.\n" -"\n" -"Press to exit the installer." -msgstr "" - -#: ../fsset.py:1822 -msgid "Unable to mount filesystem" -msgstr "" - -#: ../fsset.py:1823 -#, python-format -msgid "" -"An error occurred mounting device %s as %s. You may continue installation, " -"but there may be problems." -msgstr "" - -#: ../fsset.py:1831 ../partedUtils.py:982 -msgid "_Continue" -msgstr "" - -#: ../fsset.py:1839 -#, python-format -msgid "" -"Error mounting device %s as %s: %s\n" -"\n" -"Devices in /etc/fstab should be specified by label or UUID, not by device " -"name.\n" -"\n" -"Press OK to exit the installer." -msgstr "" - -#: ../fsset.py:1846 -#, python-format -msgid "" -"Error mounting device %s as %s: %s\n" -"\n" -"Press OK to exit the installer." -msgstr "" - -#: ../fsset.py:1864 -msgid "" -"Error finding / entry.\n" -"\n" -"This is most likely means that your fstab is incorrect.\n" -"\n" -"Press OK to exit the installer." -msgstr "" - -#: ../fsset.py:2573 -msgid "Duplicate Labels" -msgstr "" - -#: ../fsset.py:2574 -#, python-format -msgid "" -"Multiple devices on your system are labelled %s. Labels across devices must " -"be unique for your system to function properly.\n" -"\n" -"Please fix this problem and restart the installation process." -msgstr "" - -#: ../fsset.py:2739 -msgid "Formatting" -msgstr "" - -#: ../fsset.py:2740 -#, python-format -msgid "Formatting %s file system..." -msgstr "" - -#: ../installer.py:88 -msgid "Fatal Error" -msgstr "" - -#: ../installer.py:89 -#, python-format -msgid "" -"You do not have enough RAM to install %s on this machine.\n" -"\n" -"Press to reboot your system.\n" -msgstr "" - -#: ../installer.py:173 -msgid "Starting text installation..." -msgstr "" - -#: ../keyboard_models.py:48 -msgid "keyboard|Arabic (azerty)" -msgstr "" - -#: ../keyboard_models.py:51 -msgid "keyboard|Arabic (azerty/digits)" -msgstr "" - -#: ../keyboard_models.py:54 -msgid "keyboard|Arabic (digits)" -msgstr "" - -#: ../keyboard_models.py:57 -msgid "keyboard|Arabic (qwerty)" -msgstr "" - -#: ../keyboard_models.py:60 -msgid "keyboard|Arabic (qwerty/digits)" -msgstr "" - -#: ../keyboard_models.py:63 -msgid "keyboard|Belgian (be-latin1)" -msgstr "" - -#: ../keyboard_models.py:66 -msgid "keyboard|Bengali (Inscript)" -msgstr "" - -#: ../keyboard_models.py:69 -msgid "keyboard|Bengali (Probhat)" -msgstr "" - -#: ../keyboard_models.py:72 -msgid "keyboard|Bulgarian" -msgstr "" - -#: ../keyboard_models.py:75 -msgid "keyboard|Bulgarian (Phonetic)" -msgstr "" - -#: ../keyboard_models.py:78 -msgid "keyboard|Brazilian (ABNT2)" -msgstr "" - -#: ../keyboard_models.py:81 -msgid "keyboard|French Canadian" -msgstr "" - -#: ../keyboard_models.py:84 -msgid "keyboard|Croatian" -msgstr "" - -#: ../keyboard_models.py:87 -msgid "keyboard|Czech" -msgstr "" - -#: ../keyboard_models.py:90 -msgid "keyboard|Czech (qwerty)" -msgstr "" - -#: ../keyboard_models.py:93 -msgid "keyboard|German" -msgstr "" - -#: ../keyboard_models.py:96 -msgid "keyboard|German (latin1)" -msgstr "" - -#: ../keyboard_models.py:99 -msgid "keyboard|German (latin1 w/ no deadkeys)" -msgstr "" - -#: ../keyboard_models.py:102 -msgid "keyboard|Devanagari (Inscript)" -msgstr "" - -#: ../keyboard_models.py:105 -msgid "keyboard|Dvorak" -msgstr "" - -#: ../keyboard_models.py:108 -msgid "keyboard|Danish" -msgstr "" - -#: ../keyboard_models.py:111 -msgid "keyboard|Danish (latin1)" -msgstr "" - -#: ../keyboard_models.py:114 -msgid "keyboard|Spanish" -msgstr "" - -#: ../keyboard_models.py:117 -msgid "keyboard|Estonian" -msgstr "" - -#: ../keyboard_models.py:120 -msgid "keyboard|Finnish" -msgstr "" - -#: ../keyboard_models.py:123 -msgid "keyboard|Finnish (latin1)" -msgstr "" - -#: ../keyboard_models.py:126 -msgid "keyboard|French" -msgstr "" - -#: ../keyboard_models.py:129 -msgid "keyboard|French (latin9)" -msgstr "" - -#: ../keyboard_models.py:132 -msgid "keyboard|French (latin1)" -msgstr "" - -#: ../keyboard_models.py:135 -msgid "keyboard|French (pc)" -msgstr "" - -#: ../keyboard_models.py:138 -msgid "keyboard|Swiss French" -msgstr "" - -#: ../keyboard_models.py:141 -msgid "keyboard|Swiss French (latin1)" -msgstr "" - -#: ../keyboard_models.py:144 -msgid "keyboard|Greek" -msgstr "" - -#: ../keyboard_models.py:147 -msgid "keyboard|Gujarati (Inscript)" -msgstr "" - -#: ../keyboard_models.py:150 -msgid "keyboard|Punjabi (Inscript)" -msgstr "" - -#: ../keyboard_models.py:153 -msgid "keyboard|Hungarian" -msgstr "" - -#: ../keyboard_models.py:156 -msgid "keyboard|Hungarian (101 key)" -msgstr "" - -#: ../keyboard_models.py:159 -msgid "keyboard|Icelandic" -msgstr "" - -#: ../keyboard_models.py:162 -msgid "keyboard|Italian" -msgstr "" - -#: ../keyboard_models.py:165 -msgid "keyboard|Italian (IBM)" -msgstr "" - -#: ../keyboard_models.py:168 -msgid "keyboard|Italian (it2)" -msgstr "" - -#: ../keyboard_models.py:171 -msgid "keyboard|Japanese" -msgstr "" - -#: ../keyboard_models.py:174 -msgid "keyboard|Korean" -msgstr "" - -#: ../keyboard_models.py:177 -msgid "keyboard|Latin American" -msgstr "" - -#: ../keyboard_models.py:180 -msgid "keyboard|Macedonian" -msgstr "" - -#: ../keyboard_models.py:183 -msgid "keyboard|Dutch" -msgstr "" - -#: ../keyboard_models.py:186 -msgid "keyboard|Norwegian" -msgstr "" - -#: ../keyboard_models.py:189 -msgid "keyboard|Polish" -msgstr "" - -#: ../keyboard_models.py:192 -msgid "keyboard|Portuguese" -msgstr "" - -#: ../keyboard_models.py:195 -msgid "keyboard|Romanian" -msgstr "" - -#: ../keyboard_models.py:198 -msgid "keyboard|Russian" -msgstr "" - -#: ../keyboard_models.py:201 -msgid "keyboard|Serbian" -msgstr "" - -#: ../keyboard_models.py:204 -msgid "keyboard|Serbian (latin)" -msgstr "" - -#: ../keyboard_models.py:207 -msgid "keyboard|Swedish" -msgstr "" - -#: ../keyboard_models.py:210 -msgid "keyboard|Swiss German" -msgstr "" - -#: ../keyboard_models.py:213 -msgid "keyboard|Swiss German (latin1)" -msgstr "" - -#: ../keyboard_models.py:216 -msgid "keyboard|Slovak (qwerty)" -msgstr "" - -#: ../keyboard_models.py:219 -msgid "keyboard|Slovenian" -msgstr "" - -#: ../keyboard_models.py:222 -msgid "keyboard|Tamil (Inscript)" -msgstr "" - -#: ../keyboard_models.py:225 -msgid "keyboard|Tamil (Typewriter)" -msgstr "" - -#: ../keyboard_models.py:228 -msgid "keyboard|Turkish" -msgstr "" - -#: ../keyboard_models.py:231 -msgid "keyboard|United Kingdom" -msgstr "" - -#: ../keyboard_models.py:234 -msgid "keyboard|Ukrainian" -msgstr "" - -#: ../keyboard_models.py:237 -msgid "keyboard|U.S. International" -msgstr "" - -#: ../keyboard_models.py:240 -msgid "keyboard|U.S. English" -msgstr "" - -#: ../network.py:31 -msgid "IP address is missing." -msgstr "" - -#: ../network.py:35 -msgid "" -"IPv4 addresses must contain four numbers between 0 and 255, separated by " -"periods." -msgstr "" - -#: ../network.py:38 -#, python-format -msgid "'%s' is not a valid IPv6 address." -msgstr "" - -#: ../network.py:40 -#, python-format -msgid "'%s' is an invalid IP address." -msgstr "" - -#: ../network.py:52 -msgid "Hostname must be 255 or fewer characters in length." -msgstr "" - -#: ../network.py:58 -msgid "" -"Hostname must start with a valid character in the ranges 'a-z', 'A-Z', or '0-" -"9'" -msgstr "" - -#: ../network.py:63 -msgid "" -"Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'" -msgstr "" - -#: ../packages.py:113 -msgid "Warning! This is pre-release software!" -msgstr "" - -#: ../packages.py:114 -#, python-format -msgid "" -"Thank you for downloading this pre-release of %s.\n" -"\n" -"This is not a final release and is not intended for use on production " -"systems. The purpose of this release is to collect feedback from testers, " -"and it is not suitable for day to day usage.\n" -"\n" -"To report feedback, please visit:\n" -"\n" -" %s\n" -"\n" -"and file a report against '%s'.\n" -msgstr "" - -#: ../packages.py:127 -msgid "_Exit" -msgstr "" - -#: ../packages.py:127 -msgid "_Install anyway" -msgstr "" - -#: ../packages.py:130 -msgid "Your system will now be rebooted..." -msgstr "" - -#: ../packages.py:131 ../tui_confirm.py:37 -msgid "_Back" -msgstr "" - -#: ../packages.py:131 ../partedUtils.py:981 ../tui_confirm.py:37 -msgid "_Reboot" -msgstr "" - -#: ../packages.py:132 -msgid "Rebooting System" -msgstr "" - -#: ../pakfireinstall.py:47 -#, python-format -msgid "%s MB" -msgstr "" - -#: ../pakfireinstall.py:50 -#, python-format -msgid "%s KB" -msgstr "" - -#: ../pakfireinstall.py:53 -#, python-format -msgid "%s Byte" -msgstr "" - -#: ../pakfireinstall.py:55 -#, python-format -msgid "%s Bytes" -msgstr "" - -#: ../pakfireinstall.py:134 -msgid "Base system" -msgstr "" - -#: ../pakfireinstall.py:134 -msgid "Installing base system..." -msgstr "" - -#: ../pakfireinstall.py:171 -msgid "Install Starting" -msgstr "" - -#: ../pakfireinstall.py:172 -msgid "Starting install process. This may take several minutes..." -msgstr "" - -#: ../pakfireinstall.py:183 -msgid "Post Install" -msgstr "" - -#: ../pakfireinstall.py:184 -msgid "Performing post install configuration..." -msgstr "" - -#: ../pakfireinstall.py:215 -msgid "Symmetric multiprocessing" -msgstr "" - -#: ../pakfireinstall.py:216 -msgid "Xen guest" -msgstr "" - -#: ../pakfireinstall.py:226 -msgid "Normal Boot" -msgstr "" - -#: ../pakfireinstall.py:233 -msgid "Installation Progress" -msgstr "" - -#: ../partedUtils.py:239 ../tui_partition.py:408 -msgid "Foreign" -msgstr "" - -#: ../partedUtils.py:329 -#, python-format -msgid "" -"/dev/%s currently has a %s partition layout. To use this drive for the " -"installation of %s, it must be re-initialized, causing the loss of ALL DATA " -"on this drive.\n" -"\n" -"Would you like to re-initialize this drive?" -msgstr "" - -#: ../partedUtils.py:338 -msgid "_Ignore drive" -msgstr "" - -#: ../partedUtils.py:339 -msgid "_Re-initialize drive" -msgstr "" - -#: ../partedUtils.py:842 -#, python-format -msgid "" -"The partition table on device %s (%s %-0.f MB) was unreadable.\n" -"\n" -"To create new partitions it must be initialized, causing the loss of ALL " -"DATA on this drive.\n" -"\n" -"This operation will override any previous installation choices about which " -"drives to ignore.\n" -"\n" -"Would you like to initialize this drive, erasing ALL DATA?" -msgstr "" - -#: ../partedUtils.py:972 -#, python-format -msgid "" -"The drive /dev/%s has more than 15 partitions on it. The SCSI subsystem in " -"the Linux kernel does not allow for more than 15 partitons at this time. " -"You will not be able to make changes to the partitioning of this disk or use " -"any partitions beyond /dev/%s15 in %s" -msgstr "" - -#: ../partedUtils.py:1056 -msgid "No Drives Found" -msgstr "" - -#: ../partedUtils.py:1057 -msgid "" -"An error has occurred - no valid devices were found on which to create new " -"file systems. Please check your hardware for the cause of this problem." -msgstr "" - -#: ../partIntfHelpers.py:43 -msgid "Please enter a volume group name." -msgstr "" - -#: ../partIntfHelpers.py:47 -msgid "Volume Group Names must be less than 128 characters" -msgstr "" - -#: ../partIntfHelpers.py:50 -#, python-format -msgid "Error - the volume group name %s is not valid." -msgstr "" - -#: ../partIntfHelpers.py:55 -msgid "" -"Error - the volume group name contains illegal characters or spaces. " -"Acceptable characters are letters, digits, '.' or '_'." -msgstr "" - -#: ../partIntfHelpers.py:65 -msgid "Please enter a logical volume name." -msgstr "" - -#: ../partIntfHelpers.py:69 -msgid "Logical Volume Names must be less than 128 characters" -msgstr "" - -#: ../partIntfHelpers.py:73 -#, python-format -msgid "Error - the logical volume name %s is not valid." -msgstr "" - -#: ../partIntfHelpers.py:79 -msgid "" -"Error - the logical volume name contains illegal characters or spaces. " -"Acceptable characters are letters, digits, '.' or '_'." -msgstr "" - -#: ../partIntfHelpers.py:103 -#, python-format -msgid "" -"The mount point %s is invalid. Mount points must start with '/' and cannot " -"end with '/', and must contain printable characters and no spaces." -msgstr "" - -#: ../partIntfHelpers.py:110 -msgid "Please specify a mount point for this partition." -msgstr "" - -#: ../partIntfHelpers.py:120 -#, python-format -msgid "This partition is part of the RAID device /dev/md%s." -msgstr "" - -#: ../partIntfHelpers.py:123 -msgid "This partition is part of a RAID device." -msgstr "" - -#: ../partIntfHelpers.py:128 -#, python-format -msgid "This partition is part of the LVM volume group '%s'." -msgstr "" - -#: ../partIntfHelpers.py:131 -msgid "This partition is part of a LVM volume group." -msgstr "" - -#: ../partIntfHelpers.py:146 ../partIntfHelpers.py:154 -#: ../partIntfHelpers.py:161 ../partIntfHelpers.py:171 -#: ../partIntfHelpers.py:195 -msgid "Unable To Delete" -msgstr "" - -#: ../partIntfHelpers.py:147 -msgid "You must first select a partition to delete." -msgstr "" - -#: ../partIntfHelpers.py:155 -msgid "You cannot delete free space." -msgstr "" - -#: ../partIntfHelpers.py:162 -msgid "You cannot delete a partition of a LDL formatted DASD." -msgstr "" - -#: ../partIntfHelpers.py:172 -#, python-format -msgid "" -"You cannot delete this partition, as it is an extended partition which " -"contains %s" -msgstr "" - -#: ../partIntfHelpers.py:190 -msgid "This partition is holding the data for the hard drive install." -msgstr "" - -#: ../partIntfHelpers.py:196 -msgid "" -"You cannot delete this partition:\n" -"\n" -msgstr "" - -#: ../partIntfHelpers.py:241 ../partIntfHelpers.py:535 -msgid "Confirm Delete" -msgstr "" - -#: ../partIntfHelpers.py:242 -#, python-format -msgid "You are about to delete all partitions on the device '/dev/%s'." -msgstr "" - -#: ../partIntfHelpers.py:245 ../partIntfHelpers.py:536 -msgid "_Delete" -msgstr "" - -#: ../partIntfHelpers.py:302 -msgid "Notice" -msgstr "" - -#: ../partIntfHelpers.py:303 -#, python-format -msgid "" -"The following partitions were not deleted because they are in use:\n" -"\n" -"%s" -msgstr "" - -#: ../partIntfHelpers.py:319 ../partIntfHelpers.py:332 -#: ../partIntfHelpers.py:358 ../partIntfHelpers.py:369 -msgid "Unable To Edit" -msgstr "" - -#: ../partIntfHelpers.py:320 -msgid "You must select a partition to edit" -msgstr "" - -#: ../partIntfHelpers.py:332 ../partIntfHelpers.py:370 -msgid "" -"You cannot edit this partition:\n" -"\n" -msgstr "" - -#: ../partIntfHelpers.py:359 -#, python-format -msgid "" -"You cannot edit this partition, as it is an extended partition which " -"contains %s" -msgstr "" - -#: ../partIntfHelpers.py:391 -msgid "Format as Swap?" -msgstr "" - -#: ../partIntfHelpers.py:392 -#, python-format -msgid "" -"/dev/%s has a partition type of 0x82 (Linux swap) but does not appear to be " -"formatted as a Linux swap partition.\n" -"\n" -"Would you like to format this partition as a swap partition?" -msgstr "" - -#: ../partIntfHelpers.py:412 -#, python-format -msgid "You need to select at least one hard drive to install %s." -msgstr "" - -#: ../partIntfHelpers.py:417 -msgid "" -"You have chosen to use a pre-existing partition for this installation " -"without formatting it. We recommend that you format this partition to make " -"sure files from a previous operating system installation do not cause " -"problems with this installation of Linux. However, if this partition " -"contains files that you need to keep, such as home directories, then " -"continue without formatting this partition." -msgstr "" - -#: ../partIntfHelpers.py:425 -msgid "Format?" -msgstr "" - -#: ../partIntfHelpers.py:425 -msgid "_Modify Partition" -msgstr "" - -#: ../partIntfHelpers.py:425 -msgid "Do _Not Format" -msgstr "" - -#: ../partIntfHelpers.py:433 -msgid "Error with Partitioning" -msgstr "" - -#: ../partIntfHelpers.py:434 -#, python-format -msgid "" -"The following critical errors exist with your requested partitioning scheme. " -"These errors must be corrected prior to continuing with your install of %s.\n" -"\n" -"%s" -msgstr "" - -#: ../partIntfHelpers.py:448 -msgid "Partitioning Warning" -msgstr "" - -#: ../partIntfHelpers.py:449 -#, python-format -msgid "" -"The following warnings exist with your requested partition scheme.\n" -"\n" -"%s\n" -"\n" -"Would you like to continue with your requested partitioning scheme?" -msgstr "" - -#: ../partIntfHelpers.py:463 -msgid "" -"The following pre-existing partitions have been selected to be formatted, " -"destroying all data." -msgstr "" - -#: ../partIntfHelpers.py:466 -msgid "" -"Select 'Yes' to continue and format these partitions, or 'No' to go back and " -"change these settings." -msgstr "" - -#: ../partIntfHelpers.py:472 -msgid "Format Warning" -msgstr "" - -#: ../partIntfHelpers.py:520 -#, python-format -msgid "" -"You are about to delete the volume group \"%s\".\n" -"\n" -"ALL logical volumes in this volume group will be lost!" -msgstr "" - -#: ../partIntfHelpers.py:524 -#, python-format -msgid "You are about to delete the logical volume \"%s\"." -msgstr "" - -#: ../partIntfHelpers.py:527 -msgid "You are about to delete a RAID device." -msgstr "" - -#: ../partIntfHelpers.py:530 -#, python-format -msgid "You are about to delete the /dev/%s partition." -msgstr "" - -#: ../partIntfHelpers.py:533 -msgid "The partition you selected will be deleted." -msgstr "" - -#: ../partIntfHelpers.py:543 -msgid "Confirm Reset" -msgstr "" - -#: ../partIntfHelpers.py:544 -msgid "" -"Are you sure you want to reset the partition table to its original state?" -msgstr "" - -#: ../partitioning.py:36 ../partitions.py:81 -msgid "Installation cannot continue." -msgstr "" - -#: ../partitioning.py:37 ../partitions.py:82 -msgid "" -"The partitioning options you have chosen have already been activated. You " -"can no longer return to the disk editing screen. Would you like to continue " -"with the installation process?" -msgstr "" - -#: ../partitioning.py:65 -msgid "Low Memory" -msgstr "" - -#: ../partitioning.py:66 -msgid "" -"As you don't have much memory in this machine, we need to turn on swap space " -"immediately. To do this we'll have to write your new partition table to the " -"disk immediately. Is that OK?" -msgstr "" - -#: ../partitions.py:122 -msgid "Encrypt device?" -msgstr "" - -#: ../partitions.py:123 -msgid "" -"You specified block device encryption should be enabled, but you have not " -"supplied a passphrase. If you do not go back and provide a passphrase, block " -"device encryption will be disabled." -msgstr "" - -#: ../partitions.py:130 ../partitions.py:260 -msgid "Continue" -msgstr "" - -#: ../partitions.py:151 -msgid "Writing partitioning to disk" -msgstr "" - -#: ../partitions.py:152 -msgid "" -"The partitioning options you have selected will now be written to disk. Any " -"data on deleted or reformatted partitions will be lost." -msgstr "" - -#: ../partitions.py:157 -msgid "Go _back" -msgstr "" - -#: ../partitions.py:158 -msgid "_Write changes to disk" -msgstr "" - -#: ../partitions.py:265 -msgid "Confirm" -msgstr "" - -#: ../partitions.py:266 -#, python-format -msgid "" -"Are you sure you want to skip entering a passphrase for device %s?\n" -"\n" -"If you skip this step the device's contents will not be available during " -"installation." -msgstr "" - -#: ../partitions.py:1077 -#, python-format -msgid "" -"You have not defined a root partition (/), which is required for " -"installation of %s to continue." -msgstr "" - -#: ../partitions.py:1082 -#, python-format -msgid "" -"Your root partition is less than 250 megabytes which is usually too small to " -"install %s." -msgstr "" - -#: ../partitions.py:1108 -#, python-format -msgid "" -"Your %s partition is less than %s megabytes which is lower than recommended " -"for a normal %s install." -msgstr "" - -#: ../partitions.py:1142 -msgid "" -"Installing on a USB device. This may or may not produce a working system." -msgstr "" - -#: ../partitions.py:1145 -msgid "" -"Installing on a FireWire device. This may or may not produce a working " -"system." -msgstr "" - -#: ../partitions.py:1155 -msgid "Bootable partitions can only be on RAID1 devices." -msgstr "" - -#: ../partitions.py:1160 -msgid "Bootable partitions cannot be on a logical volume." -msgstr "" - -#: ../partitions.py:1166 -msgid "Bootable partitions cannot be on a RAID device." -msgstr "" - -#: ../partitions.py:1171 ../partitions.py:1177 -#, python-format -msgid "Bootable partitions cannot be on an %s filesystem." -msgstr "" - -#: ../partitions.py:1181 -msgid "Bootable partitions cannot be on an encrypted block device" -msgstr "" - -#: ../partitions.py:1185 -msgid "" -"You have not specified a swap partition. Although not strictly required in " -"all cases, it will significantly improve performance for most installations." -msgstr "" - -#: ../partitions.py:1192 -#, python-format -msgid "" -"You have specified more than 32 swap devices. The kernel for %s only " -"supports 32 swap devices." -msgstr "" - -#: ../partitions.py:1203 -#, python-format -msgid "" -"You have allocated less swap space (%dM) than available RAM (%dM) on your " -"system. This could negatively impact performance." -msgstr "" - -#: ../partitions.py:1508 -msgid "the partition in use by the installer." -msgstr "" - -#: ../partitions.py:1511 -msgid "a partition which is a member of a RAID array." -msgstr "" - -#: ../partitions.py:1514 -msgid "a partition which is a member of a LVM Volume Group." -msgstr "" - -#: ../partRequests.py:275 ../partRequests.py:278 -#, python-format -msgid "The mount point %s must be formatted during live CD installs." -msgstr "" - -#: ../partRequests.py:284 -#, python-format -msgid "" -"This mount point is invalid. The %s directory must be on the / file system." -msgstr "" - -#: ../partRequests.py:287 -#, python-format -msgid "" -"The mount point %s cannot be used. It must be a symbolic link for proper " -"system operation. Please select a different mount point." -msgstr "" - -#: ../partRequests.py:296 -msgid "This mount point must be on a linux file system." -msgstr "" - -#: ../partRequests.py:317 -#, python-format -msgid "" -"The mount point \"%s\" is already in use, please choose a different mount " -"point." -msgstr "" - -#: ../partRequests.py:331 -#, python-format -msgid "" -"The size of the %s partition (%10.2f MB) exceeds the maximum size of %10.2f " -"MB." -msgstr "" - -#: ../partRequests.py:539 -#, python-format -msgid "" -"The size of the requested partition (size = %s MB) exceeds the maximum size " -"of %s MB." -msgstr "" - -#: ../partRequests.py:544 -#, python-format -msgid "The size of the requested partition is negative! (size = %s MB)" -msgstr "" - -#: ../partRequests.py:548 -msgid "Partitions can't start below the first cylinder." -msgstr "" - -#: ../partRequests.py:551 -msgid "Partitions can't end on a negative cylinder." -msgstr "" - -#: ../partRequests.py:753 -msgid "No members in RAID request, or not RAID level specified." -msgstr "" - -#: ../partRequests.py:758 -#, python-format -msgid "A RAID device of type %s requires at least %s members." -msgstr "" - -#: ../partRequests.py:767 -#, python-format -msgid "" -"This RAID device can have a maximum of %s spares. To have more spares you " -"will need to add members to the RAID device." -msgstr "" - -#: ../partRequests.py:1033 -msgid "" -"Logical volume size must be larger than the volume group's physical extent " -"size." -msgstr "" - -#: ../tui_bootloader.py:27 -msgid "Which boot loader would you like to use?" -msgstr "" - -#: ../tui_bootloader.py:37 -msgid "Use GRUB Boot Loader" -msgstr "" - -#: ../tui_bootloader.py:38 -msgid "No Boot Loader" -msgstr "" - -#: ../tui_bootloader.py:41 ../tui_bootloader.py:103 ../tui_bootloader.py:161 -#: ../tui_bootloader.py:278 ../tui_bootloader.py:383 -msgid "Boot Loader Configuration" -msgstr "" - -#: ../tui_bootloader.py:58 -msgid "Skip Boot Loader" -msgstr "" - -#: ../tui_bootloader.py:59 -msgid "" -"You have elected not to install any boot loader, which is not recommended " -"unless you have an advanced need. Booting your system into Linux directly " -"from the hard drive almost always requires a boot loader.\n" -"\n" -"Are you sure you want to skip boot loader installation?" -msgstr "" - -#: ../tui_bootloader.py:88 -msgid "" -"A few systems need to pass special options to the kernel at boot time to " -"function properly. If you need to pass boot options to the kernel, enter " -"them now. If you don't need any or aren't sure, leave this blank." -msgstr "" - -#: ../tui_bootloader.py:97 -msgid "Force use of LBA32 (not normally required)" -msgstr "" - -#: ../tui_bootloader.py:120 -msgid "" -"If LBA32 is not supported by your system's BIOS, forcing its use can prevent " -"your machine from booting.\n" -"\n" -"Would you like to continue and force LBA32 mode?" -msgstr "" - -#: ../tui_bootloader.py:162 -msgid "Where do you want to install the boot loader?" -msgstr "" - -#: ../tui_bootloader.py:188 ../tui_bootloader.py:255 ../tui_partition.py:844 -msgid "Device" -msgstr "" - -#: ../tui_bootloader.py:189 ../tui_bootloader.py:255 -msgid "Boot label" -msgstr "" - -#: ../tui_bootloader.py:193 -msgid "Clear" -msgstr "" - -#: ../tui_bootloader.py:201 -msgid "Edit Boot Label" -msgstr "" - -#: ../tui_bootloader.py:219 ../tui_bootloader.py:224 -msgid "Invalid Boot Label" -msgstr "" - -#: ../tui_bootloader.py:220 -msgid "Boot label may not be empty." -msgstr "" - -#: ../tui_bootloader.py:225 -msgid "Boot label contains illegal characters." -msgstr "" - -#: ../tui_bootloader.py:255 -msgid "Default" -msgstr "" - -#: ../tui_bootloader.py:273 -#, python-format -msgid "" -"The boot manager %s uses can boot other operating systems as well. Please " -"tell me what partitions you would like to be able to boot and what label you " -"want to use for each of them." -msgstr "" - -#: ../tui_bootloader.py:286 -msgid "" -" select | select default | delete | next screen>" -msgstr "" - -#: ../tui_bootloader.py:335 -msgid "Cannot Delete" -msgstr "" - -#: ../tui_bootloader.py:336 -#, python-format -msgid "" -"This boot target cannot be deleted because it is for the %s system you are " -"about to install." -msgstr "" - -#: ../tui_bootloader.py:378 -msgid "" -"A boot loader password prevents users from passing arbitrary options to the " -"kernel. For highest security, you should set a password, but a password is " -"not necessary for more casual users." -msgstr "" - -#: ../tui_bootloader.py:386 -msgid "Use a GRUB Password" -msgstr "" - -#: ../tui_bootloader.py:399 -msgid "Boot Loader Password:" -msgstr "" - -#: ../tui_bootloader.py:400 -msgid "Confirm:" -msgstr "" - -#: ../tui_bootloader.py:429 -msgid "Passwords Do Not Match" -msgstr "" - -#: ../tui_bootloader.py:430 -msgid "Passwords do not match" -msgstr "" - -#: ../tui_bootloader.py:434 -msgid "Password Too Short" -msgstr "" - -#: ../tui_bootloader.py:435 -msgid "Boot loader password is too short" -msgstr "" - -#: ../tui_bootloader.py:440 -msgid "" -"Your boot loader password is shorter than six characters. We recommend a " -"longer boot loader password.\n" -"\n" -"Would you like to continue with this password?" -msgstr "" - -#: ../tui_complete.py:25 -msgid "" -"Press to end the installation process.\n" -"\n" -msgstr "" - -#: ../tui_complete.py:26 -msgid " to exit" -msgstr "" - -#: ../tui_complete.py:30 -#, python-format -msgid "" -"Congratulations, your %s installation is complete.\n" -"\n" -"%s%s" -msgstr "" - -#: ../tui_complete.py:33 -#, python-format -msgid "" -"For information on errata (updates and bug fixes), visit %s.\n" -"\n" -"Information on using your system is available in the %s wiki at %s." -msgstr "" - -#: ../tui_complete.py:39 -msgid "Complete" -msgstr "" - -#: ../tui_complete.py:40 -msgid "Reboot" -msgstr "" - -#: ../tui_confirm.py:23 -msgid "Installation to begin" -msgstr "" - -#: ../tui_confirm.py:24 -msgid "" -"Now, we got all information we need for installation. If there is something " -"you want change you can still go back. If not choose OK to start." -msgstr "" - -#: ../tui_confirm.py:34 -msgid "Reboot?" -msgstr "" - -#: ../tui_confirm.py:35 -msgid "The system will be rebooted now." -msgstr "" - -#: ../tui_keyboard.py:36 -msgid "Keyboard Selection" -msgstr "" - -#: ../tui_keyboard.py:37 -msgid "Which model keyboard is attached to this computer?" -msgstr "" - -#: ../tui_language.py:39 -msgid "Language Selection" -msgstr "" - -#: ../tui_language.py:40 -msgid "What language would you like to use during the installation process?" -msgstr "" - -#: ../tui_network.py:39 -msgid "Hostname" -msgstr "" - -#: ../tui_network.py:42 -msgid "" -"Please name this computer. The hostname identifies the computer on a " -"network." -msgstr "" - -#: ../tui_network.py:63 ../tui_network.py:70 -msgid "Invalid Hostname" -msgstr "" - -#: ../tui_network.py:64 -msgid "You have not specified a hostname." -msgstr "" - -#: ../tui_network.py:71 -#, python-format -msgid "" -"The hostname \"%s\" is not valid for the following reason:\n" -"\n" -"%s" -msgstr "" - -#: ../tui_partition.py:41 -msgid "Must specify a value" -msgstr "" - -#: ../tui_partition.py:44 -msgid "Requested value is not an integer" -msgstr "" - -#: ../tui_partition.py:46 -msgid "Requested value is too large" -msgstr "" - -#: ../tui_partition.py:95 ../tui_partition.py:132 -msgid "Free space" -msgstr "" - -#: ../tui_partition.py:97 -msgid "Extended" -msgstr "" - -#: ../tui_partition.py:111 -msgid "None" -msgstr "" - -#: ../tui_partition.py:178 -#, python-format -msgid "Could not allocate requested partitions: %s." -msgstr "" - -#: ../tui_partition.py:182 -#, python-format -msgid "Warning: %s" -msgstr "" - -#: ../tui_partition.py:183 -msgid "Modify Partition" -msgstr "" - -#: ../tui_partition.py:183 -msgid "Add anyway" -msgstr "" - -#: ../tui_partition.py:201 ../tui_partition.py:203 ../tui_partition.py:205 -#: ../tui_partition.py:230 -msgid "" -msgstr "" - -#: ../tui_partition.py:220 -msgid "Mount Point:" -msgstr "" - -#: ../tui_partition.py:239 -msgid "File System type:" -msgstr "" - -#: ../tui_partition.py:270 -msgid "Allowable Drives:" -msgstr "" - -#: ../tui_partition.py:292 ../tui_partition.py:371 ../tui_partition.py:419 -msgid "Size (MB):" -msgstr "" - -#: ../tui_partition.py:324 -msgid "Fixed Size:" -msgstr "" - -#: ../tui_partition.py:326 -msgid "Fill maximum size of (MB):" -msgstr "" - -#: ../tui_partition.py:330 -msgid "Fill all available space:" -msgstr "" - -#: ../tui_partition.py:351 -msgid "Start Cylinder:" -msgstr "" - -#: ../tui_partition.py:364 -msgid "End Cylinder:" -msgstr "" - -#: ../tui_partition.py:386 -msgid "Number of spares?" -msgstr "" - -#: ../tui_partition.py:400 -msgid "File System Type:" -msgstr "" - -#: ../tui_partition.py:413 -msgid "File System Label:" -msgstr "" - -#: ../tui_partition.py:424 -msgid "File System Option:" -msgstr "" - -#: ../tui_partition.py:427 ../tui_partition.py:652 -#, python-format -msgid "Format as %s" -msgstr "" - -#: ../tui_partition.py:429 ../tui_partition.py:654 -#, python-format -msgid "Migrate to %s" -msgstr "" - -#: ../tui_partition.py:431 ../tui_partition.py:656 -msgid "Leave unchanged" -msgstr "" - -#: ../tui_partition.py:446 ../tui_partition.py:629 -msgid "File System Options" -msgstr "" - -#: ../tui_partition.py:449 -msgid "" -"Please choose how you would like to prepare the file system on this " -"partition." -msgstr "" - -#: ../tui_partition.py:457 ../tui_partition.py:607 -msgid "Check for bad blocks" -msgstr "" - -#: ../tui_partition.py:461 -msgid "Leave unchanged (preserve data)" -msgstr "" - -#: ../tui_partition.py:470 -msgid "Format as:" -msgstr "" - -#: ../tui_partition.py:489 -msgid "Migrate to:" -msgstr "" - -#: ../tui_partition.py:559 -msgid "Add Partition" -msgstr "" - -#: ../tui_partition.py:601 -msgid "Force to be a primary partition" -msgstr "" - -#: ../tui_partition.py:684 ../tui_partition.py:738 -msgid "Invalid Entry for Partition Size" -msgstr "" - -#: ../tui_partition.py:696 -msgid "Invalid Entry for Maximum Size" -msgstr "" - -#: ../tui_partition.py:716 -msgid "Invalid Entry for Starting Cylinder" -msgstr "" - -#: ../tui_partition.py:730 -msgid "Invalid Entry for End Cylinder" -msgstr "" - -#: ../tui_partition.py:748 ../tui_partition.py:769 -msgid "Error With Request" -msgstr "" - -#: ../tui_partition.py:838 -msgid "Partitioning" -msgstr "" - -#: ../tui_partition.py:844 -msgid "Start" -msgstr "" - -#: ../tui_partition.py:844 -msgid "End" -msgstr "" - -#: ../tui_partition.py:844 -msgid "Size" -msgstr "" - -#: ../tui_partition.py:844 -msgid "Type" -msgstr "" - -#: ../tui_partition.py:844 -msgid "Mount Point" -msgstr "" - -#: ../tui_partition.py:848 -msgid "New" -msgstr "" - -#: ../tui_partition.py:850 -msgid "Delete" -msgstr "" - -#: ../tui_partition.py:853 -msgid "" -" F1-Help F2-New F3-Edit F4-Delete F5-Reset F12-OK " -msgstr "" - -#: ../tui_partition.py:883 -msgid "No Root Partition" -msgstr "" - -#: ../tui_partition.py:884 -msgid "Installation requires a / partition." -msgstr "" - -#: ../tui_partition.py:923 -msgid "Partitioning Type" -msgstr "" - -#: ../tui_partition.py:925 -msgid "" -"Installation requires partitioning of your hard drive. The default layout " -"is reasonable for most users. You can either choose to use this or create " -"your own." -msgstr "" - -#: ../tui_partition.py:932 -msgid "Remove all partitions on selected drives and create default layout" -msgstr "" - -#: ../tui_partition.py:933 -msgid "Create custom layout" -msgstr "" - -#: ../tui_partition.py:947 -msgid "Which drive(s) do you want to use for this installation?" -msgstr "" - -#: ../tui_partition.py:960 -msgid ",<+>,<-> selection | Add drive | next screen" -msgstr "" - -#: ../tui_partition.py:1026 -msgid "Review Partition Layout" -msgstr "" - -#: ../tui_partition.py:1027 -msgid "Review and modify partitioning layout?" -msgstr "" - -#: ../tui_progress.py:52 -msgid "File Installation" -msgstr "" - -#: ../tui.py:118 -msgid "Exception Occurred" -msgstr "" - -#: ../tui.py:189 -msgid "Error!" -msgstr "" - -#: ../tui.py:190 -#, python-format -msgid "" -"An error occurred when attempting to load an pomona interface component.\n" -"\n" -"className = %s\n" -"\n" -"Error: %s" -msgstr "" - -#: ../tui.py:195 ../tui.py:197 -msgid "Exit" -msgstr "" - -#: ../tui.py:195 ../tui.py:391 -msgid "Retry" -msgstr "" - -#: ../tui.py:220 -msgid "Cancelled" -msgstr "" - -#: ../tui.py:221 -msgid "I can't go to the previous step from here. You will have to try again." -msgstr "" - -#: ../tui.py:235 -#, python-format -msgid "Welcome to %s" -msgstr "" - -#: ../tui.py:238 -msgid "" -" for help | between elements | selects | next screen" -msgstr "" - -#: ../tui.py:240 -msgid "" -" / between elements | selects | next " -"screen" -msgstr "" - -#: ../tui.py:285 -msgid "Help not available" -msgstr "" - -#: ../tui.py:286 -msgid "No help is available for this step of the install." -msgstr "" - -#: ../tui.py:387 -msgid "Fix" -msgstr "" - -#: ../tui.py:392 -msgid "Ignore" -msgstr "" - -#: ../tui_timezone.py:63 -msgid "In which time zone are you located?" -msgstr "" - -#: ../tui_timezone.py:78 -msgid "System clock uses UTC" -msgstr "" - -#: ../tui_timezone.py:81 -msgid "Time Zone Selection" -msgstr "" - -#: ../tui_userauth.py:29 -msgid "Root Password" -msgstr "" - -#: ../tui_userauth.py:31 -msgid "" -"Pick a root password. You must type it twice to ensure you know it and do " -"not make a typing mistake. Remember that the root password isa critical part " -"of system security!" -msgstr "" - -#: ../tui_userauth.py:41 -msgid "Password:" -msgstr "" - -#: ../tui_userauth.py:42 -msgid "Password (confirm):" -msgstr "" - -#: ../tui_userauth.py:59 -msgid "Password Length" -msgstr "" - -#: ../tui_userauth.py:60 -msgid "The root password must be at least 6 characters long." -msgstr "" - -#: ../tui_userauth.py:63 -msgid "Password Mismatch" -msgstr "" - -#: ../tui_userauth.py:64 -msgid "The passwords you entered were different. Please try again." -msgstr "" - -#: ../tui_userauth.py:67 -msgid "Error with Password" -msgstr "" - -#: ../tui_userauth.py:68 -msgid "" -"Requested password contains non-ASCII characters, which are not allowed." -msgstr "" - -#: ../tui_welcome.py:12 -#, python-format -msgid "%s" -msgstr "" - -#: ../tui_welcome.py:13 -#, python-format -msgid "" -"Welcome to %s!\n" -"\n" -msgstr "" - -#. generated from lang-table -msgid "English" -msgstr "" - -#. generated from lang-table -msgid "German" -msgstr "" - -#. generated from lang-table -msgid "Danish" -msgstr "" diff --git a/pkgs/core/pomona/src/pomona b/pkgs/core/pomona/src/pomona deleted file mode 100644 index 75c9ce52c..000000000 --- a/pkgs/core/pomona/src/pomona +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# 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 3 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 . # -# # -############################################################################### - -############################################################################### -# # -# This is a small wrapper that runs our installer. # -# # -############################################################################### - -echo "Running the Pomona Installer..." - -python /usr/lib/pomona/pomona.py $@ -ret=$? - -for i in $@; do - if [ "$i" == "--debug" ]; then - echo - echo "We are running in debug mode!" - echo - echo "So, rebooting is paused and you can do some things on the" - echo "other shells. If you are finished, press ENTER." - read - break - fi -done - -#reboot - -cat < pychecker-log - -if [ -s pychecker-log ]; then - echo "Pychecker reports the following issues:" - cat pychecker-log - exit 1 -fi - -rm pychecker-log - -exit 0 diff --git a/pkgs/core/pomona/src/storage/__init__.py b/pkgs/core/pomona/src/storage/__init__.py deleted file mode 100644 index 2a0da0b8d..000000000 --- a/pkgs/core/pomona/src/storage/__init__.py +++ /dev/null @@ -1,1176 +0,0 @@ -#!/usr/bin/python - -from devicetree import DeviceTree - -from deviceaction import * -from devicelibs import lvm -from devicelibs.lvm import safeLvmName -from devices import * -from formats import get_default_filesystem_type -from udev import * - -from constants import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -def storageInitialize(installer): - storage = installer.ds.storage - - storage.shutdown() - - if installer.dispatch.dir == DISPATCH_BACK: - return - - # XXX I don't understand why I have to do this - udev_trigger(subsystem="block") - - #XXX Determine our cdrom drive/usb key here and add it to protectedPartiotions - storage.reset() - -class Storage(object): - def __init__(self, installer): - self.installer = installer - - self.protectedDisks = [] - self.clearDisks = [] - self.ignoredDisks = [] - - self.defaultFSType = get_default_filesystem_type() - self.defaultBootFSType = get_default_filesystem_type(boot=True) - - self.doAutoPartition = False - self.encryptedAutoPart = False - #self.autoPartitionRequests = [] - self.autoPartitionRequests = [PartSpec(mountpoint="/", fstype=self.defaultFSType, size=1024, grow=True), - PartSpec(mountpoint="/boot", fstype=self.defaultFSType, size=75, grow=False),] - - #self.devicetree = DeviceTree(self.installer) - self.devicetree = None - - self._nextID = 0 - - def shutdown(self): - self.installer.log.debug("Shutting down storage...") - - def reset(self): - """ Reset storage configuration to reflect actual system state. - - This should rescan from scratch but not clobber user-obtained - information like passphrases - """ - #for device in self.devices: - # if device.format.type == "luks" and device.format.exists: - # self.__luksDevs[device.format.uuid] = device.format._LUKS__passphrase - - self.installer.window = self.installer.intf.waitWindow(_("Finding Devices"), - _("Finding storage devices...")) - self.devicetree = DeviceTree(self.installer) - self.devicetree.populate() - self.fsset = FSSet(self.installer) - self.installer.window.pop() - - def checkNoDisks(self): - """Check that there are valid disk devices.""" - if not self.disks: - self.installer.intf.messageWindow(_("No Drives Found"), - _("An error has occurred - no valid devices were " - "found on which to create new file systems. " - "Please check your hardware for the cause " - "of this problem.")) - return True - return False - - def sanityCheck(self): - """ Run a series of tests to verify the storage configuration. - - This function is called at the end of partitioning so that - we can make sure you don't have anything silly (like no /, - a really small /, etc). Returns (errors, warnings) where - each is a list of strings. - """ - checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 384), - ('/home', 100), ('/boot', 75)] - warnings = [] - errors = [] - - filesystems = self.fsset.mountpoints - root = self.fsset.rootDevice - swaps = self.fsset.swapDevices - #try: - # boot = self.anaconda.platform.bootDevice() - #except DeviceError: - # boot = None - boot = None - - if not root: - errors.append(_("You have not defined a root partition (/), " - "which is required for installation of %s " - "to continue.") % (PRODUCT_NAME,)) - - if root and root.size < 250: - warnings.append(_("Your root partition is less than 250 " - "megabytes which is usually too small to " - "install %s.") % (PRODUCT_NAME,)) - - recommended_size = 1024 - if (root and root.size < recommended_size): - errors.append(_("Your / partition is less than %s " - "megabytes which is lower than recommended " - "for a normal %s install.") - %(recommended_size, PRODUCT_NAME)) - - # livecds have to have the rootfs type match up - #if (root and - # self.installer.backend.rootFsType and - # root.format.type != self.installer.backend.rootFsType): - # errors.append(_("Your / partition does not match the " - # "the live image you are installing from. " - # "It must be formatted as %s.") - # % (self.anaconda.backend.rootFsType,)) - - for (mount, size) in checkSizes: - if mount in filesystems and filesystems[mount].size < size: - warnings.append(_("Your %s partition is less than %s " - "megabytes which is lower than recommended " - "for a normal %s install.") - %(mount, size, PRODUCT_NAME)) - - usb_disks = [] - firewire_disks = [] - #for disk in self.disks: - # if isys.driveUsesModule(disk.name, ["usb-storage", "ub"]): - # usb_disks.append(disk) - # elif isys.driveUsesModule(disk.name, ["sbp2", "firewire-sbp2"]): - # firewire_disks.append(disk) - - uses_usb = False - uses_firewire = False - for device in filesystems.values(): - for disk in usb_disks: - if device.dependsOn(disk): - uses_usb = True - break - - for disk in firewire_disks: - if device.dependsOn(disk): - uses_firewire = True - break - - if uses_usb: - warnings.append(_("Installing on a USB device. This may " - "or may not produce a working system.")) - if uses_firewire: - warnings.append(_("Installing on a FireWire device. This may " - "or may not produce a working system.")) - - if not boot: - errors.append(_("You have not created a boot partition.")) - - if (boot and boot.type == "mdarray" and - boot.level != 1): - errors.append(_("Bootable partitions can only be on RAID1 " - "devices.")) - - # can't have bootable partition on LV - if boot and boot.type == "lvmlv": - errors.append(_("Bootable partitions cannot be on a " - "logical volume.")) - - # most arches can't have boot on RAID - if boot and boot.type == "mdarray" and not self.anaconda.platform.supportsMdRaidBoot: - errors.append(_("Bootable partitions cannot be on a RAID " - "device.")) - - # Lots of filesystems types don't support /boot. - if boot and not boot.format.bootable: - errors.append(_("Bootable partitions cannot be on an %s " - "filesystem.") % boot.format.name) - - # vfat /boot is insane. - if (boot and boot == root and boot.format.type == "vfat"): - errors.append(_("Bootable partitions cannot be on an %s " - "filesystem.") % boot.format.type) - - if (boot and filter(lambda d: d.type == "luks/dm-crypt", - self.deviceDeps(boot))): - errors.append(_("Bootable partitions cannot be on an " - "encrypted block device")) - - if not swaps: - warnings.append(_("You have not specified a swap partition. " - "Although not strictly required in all cases, " - "it will significantly improve performance for " - "most installations.")) - - return (errors, warnings) - - def deviceDeps(self, device): - return self.devicetree.getDependentDevices(device) - - @property - def nextID(self): - id = self._nextID - self._nextID += 1 - return id - - @property - def disks(self): - """ A list of the disks in the device tree. - - Ignored disks are not included, as are disks with no media present. - - This is based on the current state of the device tree and - does not necessarily reflect the actual on-disk state of the - system's disks. - """ - disks = [] - devices = self.devicetree.devices - for d in devices: - if isinstance(devices[d], DiskDevice) and devices[d].mediaPresent: - disks.append(devices[d]) - disks.sort(key=lambda d: d.name) - return disks - - @property - def devices(self): - """ A list of all the devices in the device tree. """ - devices = self.devicetree.devices.values() - devices.sort(key=lambda d: d.path) - return devices - - @property - def partitions(self): - """ A list of the partitions in the device tree. - - This is based on the current state of the device tree and - does not necessarily reflect the actual on-disk state of the - system's disks. - """ - partitions = self.devicetree.getDevicesByInstance(PartitionDevice) - partitions.sort(key=lambda d: d.name) - return partitions - - @property - def vgs(self): - """ A list of the LVM Volume Groups in the device tree. - - This is based on the current state of the device tree and - does not necessarily reflect the actual on-disk state of the - system's disks. - """ - vgs = self.devicetree.getDevicesByType("lvmvg") - vgs.sort(key=lambda d: d.name) - return vgs - - def createDevice(self, device): - """ Schedule creation of a device. - - TODO: We could do some things here like assign the next - available raid minor if one isn't already set. - """ - self.devicetree.registerAction(ActionCreateDevice(self.installer, device)) - if device.format.type: - self.devicetree.registerAction(ActionCreateFormat(self.installer, device)) - - def destroyDevice(self, device): - """ Schedule destruction of a device. """ - if device.format.exists and device.format.type: - # schedule destruction of any formatting while we're at it - self.devicetree.registerAction(ActionDestroyFormat(self.installer, device)) - - action = ActionDestroyDevice(self.installer, device) - self.devicetree.registerAction(action) - - def newPartition(self, *args, **kwargs): - """ Return a new PartitionDevice instance for configuring. """ - if kwargs.has_key("fmt_type"): - kwargs["format"] = getFormat(kwargs.pop("fmt_type"), installer=self.installer, - mountpoint=kwargs.pop("mountpoint", None)) - - if kwargs.has_key("disks"): - parents = kwargs.pop("disks") - if isinstance(parents, Device): - kwargs["parents"] = [parents] - else: - kwargs["parents"] = parents - - if kwargs.has_key("name"): - name = kwargs.pop("name") - else: - name = "req%d" % self.nextID - - return PartitionDevice(self.installer, name, *args, **kwargs) - - def newVG(self, *args, **kwargs): - """ Return a new LVMVolumeGroupDevice instance. """ - pvs = kwargs.pop("pvs", []) - for pv in pvs: - if pv not in self.devices: - raise ValueError("pv is not in the device tree") - - if kwargs.has_key("name"): - name = kwargs.pop("name") - else: - # XXX name = self.createSuggestedVGName(self.anaconda.id.network) - name = self.createSuggestedVGName(None) - - if name in [d.name for d in self.devices]: - raise ValueError("name already in use") - - return LVMVolumeGroupDevice(self.installer, name, pvs, *args, **kwargs) - - def newLV(self, *args, **kwargs): - """ Return a new LVMLogicalVolumeDevice instance. """ - if kwargs.has_key("vg"): - vg = kwargs.pop("vg") - - mountpoint = kwargs.pop("mountpoint", None) - if kwargs.has_key("fmt_type"): - kwargs["format"] = getFormat(kwargs.pop("fmt_type"), - installer=self.installer, - mountpoint=mountpoint) - - if kwargs.has_key("name"): - name = kwargs.pop("name") - else: - if kwargs.get("format") and kwargs["format"].type == "swap": - swap = True - else: - swap = False - name = self.createSuggestedLVName(vg, - swap=swap, - mountpoint=mountpoint) - - if name in [d.name for d in self.devices]: - raise ValueError("Name already in use") - - return LVMLogicalVolumeDevice(self.installer, name, vg, *args, **kwargs) - - def createSuggestedVGName(self, network): - """ Return a reasonable, unused VG name. """ - # try to create a volume group name incorporating the hostname - #hn = network.hostname # XXX - hn = "%s.localdomain" % PROCUCT_SNAME - vgnames = [vg.name for vg in self.vgs] - if hn is not None and hn != '': - if hn == 'localhost' or hn == 'localhost.localdomain': - vgtemplate = "VolGroup" - elif hn.find('.') != -1: - hn = safeLvmName(hn) - vgtemplate = "vg_%s" % (hn.split('.')[0].lower(),) - else: - hn = safeLvmName(hn) - vgtemplate = "vg_%s" % (hn.lower(),) - else: - vgtemplate = "VolGroup" - - if vgtemplate not in vgnames and \ - vgtemplate not in lvm.lvm_vg_blacklist: - return vgtemplate - else: - i = 0 - while 1: - tmpname = "%s%02d" % (vgtemplate, i,) - if not tmpname in vgnames and \ - tmpname not in lvm.lvm_vg_blacklist: - break - - i += 1 - if i > 99: - tmpname = "" - - return tmpname - - def createSuggestedLVName(self, vg, swap=None, mountpoint=None): - """ Return a suitable, unused name for a new logical volume. """ - # FIXME: this is not at all guaranteed to work - if mountpoint: - # try to incorporate the mountpoint into the name - if mountpoint == '/': - lvtemplate = 'lv_root' - else: - tmp = safeLvmName(mountpoint) - lvtemplate = "lv_%s" % (tmp,) - else: - if swap: - if len([s for s in self.swaps if s in vg.lvs]): - idx = len([s for s in self.swaps if s in vg.lvs]) - while True: - lvtemplate = "lv_swap%02d" % idx - if lvtemplate in [lv.lvname for lv in vg.lvs]: - idx += 1 - else: - break - else: - lvtemplate = "lv_swap" - else: - idx = len(vg.lvs) - while True: - lvtemplate = "LogVol%02d" % idx - if lvtemplate in [l.lvname for l in vg.lvs]: - idx += 1 - else: - break - - return lvtemplate - - def deviceImmutable(self, device): - """ Return any reason the device cannot be modified/removed. - - Return False if the device can be removed. - - Devices that cannot be removed include: - - - protected partitions - - devices that are part of an md array or lvm vg - - extended partition containing logical partitions that - meet any of the above criteria - - """ - if not isinstance(device, Device): - raise ValueError("arg1 (%s) must be a Device instance" % device) - - if device.name in self.protectedDisks: - return _("This partition is holding the data for the hard " - "drive install.") - elif device.format.type == "mdmember": - for array in self.mdarrays: - if array.dependsOn(device): - if array.minor is not None: - return _("This device is part of the RAID " - "device %s.") % (array.path,) - else: - return _("This device is part of a RAID device.") - elif device.format.type == "lvmpv": - for vg in self.vgs: - if vg.dependsOn(device): - if vg.name is not None: - return _("This device is part of the LVM " - "volume group '%s'.") % (vg.name,) - else: - return _("This device is part of a LVM volume " - "group.") - elif device.format.type == "luks": - try: - luksdev = self.devicetree.getChildren(device)[0] - except IndexError: - pass - else: - return self.deviceImmutable(luksdev) - elif isinstance(device, PartitionDevice) and device.isExtended: - reasons = {} - for dep in self.deviceDeps(device): - reason = self.deviceImmutable(dep) - if reason: - reasons[dep.path] = reason - if reasons: - msg = _("This device is an extended partition which " - "contains logical partitions that cannot be " - "deleted:\n\n") - for dev in reasons: - msg += "%s: %s" % (dev, reasons[dev]) - return msg - - for i in self.devicetree.immutableDevices: - if i[0] == device.name: - return i[1] - - return False - - -class FSSet(object): - """ A class to represent a set of filesystems. """ - def __init__(self, installer): - self.installer = installer - self.devicetree = installer.ds.storage.devicetree - self.cryptTab = None - self.blkidTab = None - self.origFStab = None - self.active = False - self._dev = None - self._devpts = None - self._sysfs = None - self._proc = None - self._devshm = None - - @property - def sysfs(self): - if not self._sysfs: - self._sysfs = NoDevice(format=getFormat("sysfs", - device="sys", - mountpoint="/sys")) - return self._sysfs - - @property - def dev(self): - if not self._dev: - self._dev = DirectoryDevice("/dev", format=getFormat("bind", - device="/dev", - mountpoint="/dev", - exists=True), - exists=True) - - return self._dev - - @property - def devpts(self): - if not self._devpts: - self._devpts = NoDevice(format=getFormat("devpts", - device="devpts", - mountpoint="/dev/pts")) - return self._devpts - - @property - def proc(self): - if not self._proc: - self._proc = NoDevice(format=getFormat("proc", - device="proc", - mountpoint="/proc")) - return self._proc - - @property - def devshm(self): - if not self._devshm: - self._devshm = NoDevice(format=getFormat("tmpfs", - device="tmpfs", - mountpoint="/dev/shm")) - return self._devshm - - @property - def devices(self): - devices = self.devicetree.devices.values() - devices.sort(key=lambda d: d.path) - return devices - - @property - def mountpoints(self): - filesystems = {} - for device in self.devices: - if device.format.mountable and device.format.mountpoint: - filesystems[device.format.mountpoint] = device - return filesystems - - def _parseOneLine(self, (devspec, mountpoint, fstype, options, dump, passno)): - # find device in the tree - device = self.devicetree.resolveDevice(devspec, - cryptTab=self.cryptTab, - blkidTab=self.blkidTab) - if device: - # fall through to the bottom of this block - pass - elif devspec.startswith("/dev/loop"): - # FIXME: create devices.LoopDevice - self.installer.log.warning("completely ignoring your loop mount") - elif ":" in devspec: - # NFS -- preserve but otherwise ignore - device = NFSDevice(devspec, - format=getFormat(fstype, - device=devspec)) - elif devspec.startswith("/") and fstype == "swap": - # swap file - device = FileDevice(devspec, - parents=get_containing_device(devspec, self.devicetree), - format=getFormat(fstype, - device=devspec, - exists=True), - exists=True) - elif fstype == "bind" or "bind" in options: - # bind mount... set fstype so later comparison won't - # turn up false positives - fstype = "bind" - device = FileDevice(devspec, - parents=get_containing_device(devspec, self.devicetree), - exists=True) - device.format = getFormat("bind", - device=device.path, - exists=True) - elif mountpoint in ("/proc", "/sys", "/dev/shm", "/dev/pts"): - # drop these now -- we'll recreate later - return None - else: - # nodev filesystem -- preserve or drop completely? - format = getFormat(fstype) - if devspec == "none" or \ - isinstance(format, get_device_format_class("nodev")): - device = NoDevice(format) - else: - device = StorageDevice(devspec) - - if device is None: - self.installer.log.error("failed to resolve %s (%s) from fstab" % (devspec, - fstype)) - return None - - # make sure, if we're using a device from the tree, that - # the device's format we found matches what's in the fstab - fmt = getFormat(fstype, device=device.path) - if fmt.type != device.format.type: - self.installer.log.warning("scanned format (%s) differs from fstab " - "format (%s)" % (device.format.type, fstype)) - - if device.format.mountable: - device.format.mountpoint = mountpoint - device.format.mountopts = options - - # is this useful? - try: - device.format.options = options - except AttributeError: - pass - - return device - - def parseFSTab(self, chroot=""): - """ parse /etc/fstab - - preconditions: - all storage devices have been scanned, including filesystems - postconditions: - - FIXME: control which exceptions we raise - - XXX do we care about bind mounts? - how about nodev mounts? - loop mounts? - """ - if not chroot or not os.path.isdir(chroot): - chroot = "" - - path = "%s/etc/fstab" % chroot - if not os.access(path, os.R_OK): - # XXX should we raise an exception instead? - self.installer.log.info("cannot open %s for read" % path) - return - - blkidTab = BlkidTab(self.installer, chroot=chroot) - try: - blkidTab.parse() - self.installer.log.debug("blkid.tab devs: %s" % blkidTab.devices.keys()) - except Exception as e: - self.installer.log.info("error parsing blkid.tab: %s" % e) - blkidTab = None - - cryptTab = CryptTab(self.devicetree, blkidTab=blkidTab, chroot=chroot) - try: - cryptTab.parse(chroot=chroot) - self.installer.log.debug("crypttab maps: %s" % cryptTab.mappings.keys()) - except Exception as e: - self.installer.log.info("error parsing crypttab: %s" % e) - cryptTab = None - - self.blkidTab = blkidTab - self.cryptTab = cryptTab - - with open(path) as f: - self.installer.log.debug("parsing %s" % path) - - lines = f.readlines() - - # save the original file - self.origFStab = ''.join(lines) - - for line in lines: - # strip off comments - (line, pound, comment) = line.partition("#") - fields = line.split() - - if not 4 <= len(fields) <= 6: - continue - elif len(fields) == 4: - fields.extend([0, 0]) - elif len(fields) == 5: - fields.append(0) - - (devspec, mountpoint, fstype, options, dump, passno) = fields - - try: - device = self._parseOneLine((devspec, mountpoint, fstype, options, dump, passno)) - except Exception as e: - raise Exception("fstab entry %s is malformed: %s" % (devspec, e)) - - if not device: - continue - - if device not in self.devicetree.devices.values(): - self.devicetree._addDevice(device) - - def fsFreeSpace(self, chroot='/'): - space = [] - for device in self.devices: - if not device.format.mountable or \ - not device.format.status: - continue - - path = "%s/%s" % (chroot, device.format.mountpoint) - try: - space.append((device.format.mountpoint, - isys.pathSpaceAvailable(path))) - except SystemError: - self.installer.log.error("failed to calculate free space for %s" % (device.format.mountpoint,)) - - space.sort(key=lambda s: s[1]) - return space - - def mtab(self): - format = "%s %s %s %s 0 0\n" - mtab = "" - devices = self.mountpoints.values() + self.swapDevices - devices.extend([self.devshm, self.devpts, self.sysfs, self.proc]) - devices.sort(key=lambda d: getattr(d.format, "mountpoint", None)) - for device in devices: - if not device.format.status: - continue - if not device.format.mountable: - continue - if device.format.mountpoint: - options = device.format.mountopts - if options: - options = options.replace("defaults,", "") - options = options.replace("defaults", "") - - if options: - options = "rw," + options - else: - options = "rw" - mtab = mtab + format % (device.path, - device.format.mountpoint, - device.format.type, - options) - return mtab - - def turnOnSwap(self): - intf = self.installer.intf - for device in self.swapDevices: - try: - device.setup() - device.format.setup() - except SuspendError: - if intf: - msg = _("The swap device:\n\n %s\n\n" - "in your /etc/fstab file is currently in " - "use as a software suspend device, " - "which means your system is hibernating. " - "If you are performing a new install, " - "make sure the installer is set " - "to format all swap devices.") \ - % device.path - intf.messageWindow(_("Error"), msg) - sys.exit(0) - except DeviceError as msg: - if intf: - err = _("Error enabling swap device %s: %s\n\n" - "This most likely means this swap " - "device has not been initialized.\n\n" - "Press OK to exit the installer.") % \ - (device.path, msg) - intf.messageWindow(_("Error"), err) - sys.exit(0) - - def mountFilesystems(self, installer, raiseErrors=None, readOnly=None, - skipRoot=False): - intf = installer.intf - devices = self.mountpoints.values() + self.swapDevices - devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc]) - devices.sort(key=lambda d: getattr(d.format, "mountpoint", None)) - - for device in devices: - if not device.format.mountable or not device.format.mountpoint: - continue - - if skipRoot and device.format.mountpoint == "/": - continue - - options = device.format.options - if "noauto" in options.split(","): - continue - - try: - device.setup() - except Exception as msg: - # FIXME: need an error popup - continue - - if readOnly: - options = "%s,%s" % (options, readOnly) - - try: - device.format.setup(options=options, - chroot=installer.rootPath) - except OSError as (num, msg): - if intf: - if num == errno.EEXIST: - intf.messageWindow(_("Invalid mount point"), - _("An error occurred when trying " - "to create %s. Some element of " - "this path is not a directory. " - "This is a fatal error and the " - "install cannot continue.\n\n" - "Press to exit the " - "installer.") - % (device.format.mountpoint,)) - else: - intf.messageWindow(_("Invalid mount point"), - _("An error occurred when trying " - "to create %s: %s. This is " - "a fatal error and the install " - "cannot continue.\n\n" - "Press to exit the " - "installer.") - % (device.format.mountpoint, msg)) - self.installer.log.error("OSError: (%d) %s" % (num, msg) ) - sys.exit(0) - except SystemError as (num, msg): - if raiseErrors: - raise - if intf and not device.format.linuxNative: - ret = intf.messageWindow(_("Unable to mount filesystem"), - _("An error occurred mounting " - "device %s as %s. You may " - "continue installation, but " - "there may be problems.") % - (device.path, - device.format.mountpoint), - type="custom", - custom_icon="warning", - custom_buttons=[_("_Exit installer"), - _("_Continue")]) - - if ret == 0: - sys.exit(0) - else: - continue - - self.installer.log.error("SystemError: (%d) %s" % (num, msg) ) - sys.exit(0) - except FSError as msg: - if intf: - intf.messageWindow(_("Unable to mount filesystem"), - _("An error occurred mounting " - "device %s as %s: %s. This is " - "a fatal error and the install " - "cannot continue.\n\n" - "Press to exit the " - "installer.") - % (device.path, - device.format.mountpoint, - msg)) - self.installer.log.error("FSError: %s" % msg) - sys.exit(0) - - self.active = True - - def umountFilesystems(self, instPath, ignoreErrors=True, swapoff=True): - devices = self.mountpoints.values() + self.swapDevices - devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc]) - devices.sort(key=lambda d: getattr(d.format, "mountpoint", None)) - devices.reverse() - for device in devices: - if not device.format.mountable and \ - (device.format.type != "swap" or swapoff): - continue - - device.format.teardown() - device.teardown() - - self.active = False - - def createSwapFile(self, rootPath, device, size): - """ Create and activate a swap file under rootPath. """ - filename = "/SWAP" - count = 0 - basedir = os.path.normpath("%s/%s" % (rootPath, - device.format.mountpoint)) - while os.path.exists("%s/%s" % (basedir, filename)) or \ - self.devicetree.getDeviceByName(filename): - file = os.path.normpath("%s/%s" % (basedir, filename)) - count += 1 - filename = "/SWAP-%d" % count - - dev = FileDevice(filename, - size=size, - parents=[device], - format=getFormat("swap", device=filename)) - dev.create() - dev.setup() - dev.format.create() - dev.format.setup() - # nasty, nasty - self.devicetree._addDevice(dev) - - def mkDevRoot(self, instPath): - root = self.rootDevice - dev = "%s/%s" % (instPath, root.path) - if not os.path.exists("%s/dev/root" %(instPath,)) and os.path.exists(dev): - rdev = os.stat(dev).st_rdev - os.mknod("%s/dev/root" % (instPath,), stat.S_IFBLK | 0600, rdev) - - @property - def swapDevices(self): - swaps = [] - for device in self.devices: - if device.format.type == "swap": - swaps.append(device) - return swaps - - @property - def rootDevice(self): - for device in self.devices: - try: - mountpoint = device.format.mountpoint - except AttributeError: - mountpoint = None - - if mountpoint == "/": - return device - - @property - def migratableDevices(self): - """ List of devices whose filesystems can be migrated. """ - migratable = [] - for device in self.devices: - if device.format.migratable and device.format.exists: - migratable.append(device) - - return migratable - - def write(self, instPath): - """ write out all config files based on the set of filesystems """ - # /etc/fstab - fstab_path = os.path.normpath("%s/etc/fstab" % instPath) - fstab = self.fstab() - open(fstab_path, "w").write(fstab) - - # /etc/crypttab - crypttab_path = os.path.normpath("%s/etc/crypttab" % instPath) - crypttab = self.crypttab() - open(crypttab_path, "w").write(crypttab) - - # /etc/mdadm.conf - mdadm_path = os.path.normpath("%s/etc/mdadm.conf" % instPath) - mdadm_conf = self.mdadmConf() - open(mdadm_path, "w").write(mdadm_conf) - - def crypttab(self): - # if we are upgrading, do we want to update crypttab? - # gut reaction says no, but plymouth needs the names to be very - # specific for passphrase prompting - if not self.cryptTab: - self.cryptTab = CryptTab(self.devicetree) - self.cryptTab.populate() - - devices = self.mountpoints.values() + self.swapDevices - - # prune crypttab -- only mappings required by one or more entries - for name in self.cryptTab.mappings.keys(): - keep = False - mapInfo = self.cryptTab[name] - cryptoDev = mapInfo['device'] - for device in devices: - if device == cryptoDev or device.dependsOn(cryptoDev): - keep = True - break - - if not keep: - del self.cryptTab.mappings[name] - - return self.cryptTab.crypttab() - - def mdadmConf(self): - """ Return the contents of mdadm.conf. """ - arrays = self.devicetree.getDevicesByType("mdarray") - conf = "" - devices = self.mountpoints.values() + self.swapDevices - for array in arrays: - writeConf = False - for device in devices: - if device == array or device.dependsOn(array): - writeConf = True - break - - if writeConf: - conf += array.mdadmConfEntry - - return conf - - def fstab (self): - format = "%-23s %-23s %-7s %-15s %d %d\n" - fstab = """ -# -# /etc/fstab -# Created by pomona on %s -# -# Accessible filesystems, by reference, are maintained under '/dev/disk' -# See man pages fstab(5), findfs(8), mount(8) and/or vol_id(8) for more info -# -""" % time.asctime() - - devices = self.mountpoints.values() + self.swapDevices - devices.extend([self.devshm, self.devpts, self.sysfs, self.proc]) - netdevs = self.devicetree.getDevicesByInstance(NetworkStorageDevice) - for device in devices: - # why the hell do we put swap in the fstab, anyway? - if not device.format.mountable and device.format.type != "swap": - continue - - fstype = device.format.type - if fstype == "swap": - mountpoint = "swap" - options = device.format.options - else: - mountpoint = device.format.mountpoint - options = device.format.mountopts - if not mountpoint: - self.installer.log.warning("%s filesystem on %s has no mountpoint" % \ - (fstype, device.path)) - continue - - options = options or "defaults" - for netdev in netdevs: - if device.dependsOn(netdev): - options = options + ",_netdev" - break - devspec = device.fstabSpec - dump = device.format.dump - if device.format.check and mountpoint == "/": - passno = 1 - elif device.format.check: - passno = 2 - else: - passno = 0 - fstab = fstab + device.fstabComment - fstab = fstab + format % (devspec, mountpoint, fstype, - options, dump, passno) - return fstab - -class PartSpec(object): - def __init__(self, mountpoint=None, fstype=None, size=None, maxSize=None, - grow=False, asVol=False, weight=0): - self.mountpoint = mountpoint - self.fstype = fstype - self.size = size - self.maxSize = maxSize - self.grow = grow - self.asVol = asVol - self.weight = weight - - -class BlkidTab(object): - """ Dictionary-like interface to blkid.tab with device path keys """ - def __init__(self, installer, chroot=""): - self.installer = installer - self.chroot = chroot - self.devices = {} - - def parse(self): - path = "%s/etc/blkid/blkid.tab" % self.chroot - self.installer.log.debug("parsing %s" % path) - with open(path) as f: - for line in f.readlines(): - # this is pretty ugly, but an XML parser is more work than - # is justifiable for this purpose - if not line.startswith("\n")] - (data, sep, device) = line.partition(">") - if not device: - continue - - self.devices[device] = {} - for pair in data.split(): - try: - (key, value) = pair.split("=") - except ValueError: - continue - - self.devices[device][key] = value[1:-1] # strip off quotes - - def __getitem__(self, key): - return self.devices[key] - - def get(self, key, default=None): - return self.devices.get(key, default) - - -class CryptTab(object): - """ Dictionary-like interface to crypttab entries with map name keys """ - def __init__(self, devicetree, blkidTab=None, chroot=""): - self.devicetree = devicetree - self.blkidTab = blkidTab - self.chroot = chroot - self.mappings = {} - - def parse(self, chroot=""): - """ Parse /etc/crypttab from an existing installation. """ - if not chroot or not os.path.isdir(chroot): - chroot = "" - - path = "%s/etc/crypttab" % chroot - log.debug("parsing %s" % path) - with open(path) as f: - if not self.blkidTab: - try: - self.blkidTab = BlkidTab(chroot=chroot) - self.blkidTab.parse() - except Exception: - self.blkidTab = None - - for line in f.readlines(): - (line, pound, comment) = line.partition("#") - fields = line.split() - if not 2 <= len(fields) <= 4: - continue - elif len(fields) == 2: - fields.extend(['none', '']) - elif len(fields) == 3: - fields.append('') - - (name, devspec, keyfile, options) = fields - - # resolve devspec to a device in the tree - device = self.devicetree.resolveDevice(devspec, - blkidTab=self.blkidTab) - if device: - self.mappings[name] = {"device": device, - "keyfile": keyfile, - "options": options} - - def populate(self): - """ Populate the instance based on the device tree's contents. """ - for device in self.devicetree.devices.values(): - # XXX should we put them all in there or just the ones that - # are part of a device containing swap or a filesystem? - # - # Put them all in here -- we can filter from FSSet - if device.format.type != "luks": - continue - - key_file = device.format.keyFile - if not key_file: - key_file = "none" - - options = device.format.options - if not options: - options = "" - - self.mappings[device.format.mapName] = {"device": device, - "keyfile": key_file, - "options": options} - - def crypttab(self): - """ Write out /etc/crypttab """ - crypttab = "" - for name in self.mappings: - entry = self[name] - crypttab += "%s UUID=%s %s %s\n" % (name, - entry['device'].format.uuid, - entry['keyfile'], - entry['options']) - return crypttab - - def __getitem__(self, key): - return self.mappings[key] - - def get(self, key, default=None): - return self.mappings.get(key, default) diff --git a/pkgs/core/pomona/src/storage/deviceaction.py b/pkgs/core/pomona/src/storage/deviceaction.py deleted file mode 100644 index 9361b5229..000000000 --- a/pkgs/core/pomona/src/storage/deviceaction.py +++ /dev/null @@ -1,352 +0,0 @@ -#!/usr/bin/python - -import copy - -from devices import StorageDevice, PartitionDevice -from formats import getFormat -from errors import * -from udev import * - -# The values are just hints as to the ordering. -# Eg: fsmod and devmod ordering depends on the mod (shrink -v- grow) -ACTION_TYPE_NONE = 0 -ACTION_TYPE_DESTROY = 1000 -ACTION_TYPE_RESIZE = 500 -ACTION_TYPE_MIGRATE = 250 -ACTION_TYPE_CREATE = 100 - -action_strings = {ACTION_TYPE_NONE: "None", - ACTION_TYPE_DESTROY: "Destroy", - ACTION_TYPE_RESIZE: "Resize", - ACTION_TYPE_MIGRATE: "Migrate", - ACTION_TYPE_CREATE: "Create"} - -ACTION_OBJECT_NONE = 0 -ACTION_OBJECT_FORMAT = 1 -ACTION_OBJECT_DEVICE = 2 - -object_strings = {ACTION_OBJECT_NONE: "None", - ACTION_OBJECT_FORMAT: "Format", - ACTION_OBJECT_DEVICE: "Device"} - -RESIZE_SHRINK = 88 -RESIZE_GROW = 89 - -resize_strings = {RESIZE_SHRINK: "Shrink", - RESIZE_GROW: "Grow"} - -def action_type_from_string(type_string): - if type_string is None: - return None - - for (k,v) in action_strings.items(): - if v.lower() == type_string.lower(): - return k - - return resize_type_from_string(type_string) - -def action_object_from_string(type_string): - if type_string is None: - return None - - for (k,v) in object_strings.items(): - if v.lower() == type_string.lower(): - return k - -def resize_type_from_string(type_string): - if type_string is None: - return None - - for (k,v) in resize_strings.items(): - if v.lower() == type_string.lower(): - return k - -class DeviceAction(object): - """ An action that will be carried out in the future on a Device. - - These classes represent actions to be performed on devices or - filesystems. - - The operand Device instance will be modified according to the - action, but no changes will be made to the underlying device or - filesystem until the DeviceAction instance's execute method is - called. The DeviceAction instance's cancel method should reverse - any modifications made to the Device instance's attributes. - - If the Device instance represents a pre-existing device, the - constructor should call any methods or set any attributes that the - action will eventually change. Device/DeviceFormat classes should verify - that the requested modifications are reasonable and raise an - exception if not. - - Only one action of any given type/object pair can exist for any - given device at any given time. This is enforced by the - DeviceTree. - - Basic usage: - - a = DeviceAction(dev) - a.execute() - - OR - - a = DeviceAction(dev) - a.cancel() - - - XXX should we back up the device with a deep copy for forcibly - cancelling actions? - - The downside is that we lose any checking or verification that - would get done when resetting the Device instance's attributes to - their original values. - - The upside is that we would be guaranteed to achieve a total - reversal. No chance of, eg: resizes ending up altering Device - size due to rounding or other miscalculation. -""" - type = ACTION_TYPE_NONE - obj = ACTION_OBJECT_NONE - - def __init__(self, installer, device): - self.installer = installer - if not isinstance(device, StorageDevice): - raise ValueError("arg 1 must be a StorageDevice instance") - self.device = device - - - def execute(self, intf=None): - """ perform the action """ - pass - - def cancel(self): - """ cancel the action """ - pass - - def isDestroy(self): - return self.type == ACTION_TYPE_DESTROY - - def isCreate(self): - return self.type == ACTION_TYPE_CREATE - - def isMigrate(self): - return self.type == ACTION_TYPE_MIGRATE - - def isResize(self): - return self.type == ACTION_TYPE_RESIZE - - def isShrink(self): - return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_SHRINK) - - def isGrow(self): - return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_GROW) - - def isDevice(self): - return self.obj == ACTION_OBJECT_DEVICE - - def isFormat(self): - return self.obj == ACTION_OBJECT_FORMAT - - def __str__(self): - s = "%s %s" % (action_strings[self.type], object_strings[self.obj]) - if self.isResize(): - s += " (%s)" % resize_strings[self.dir] - if self.isFormat(): - if self.device.format: - fmt_type = self.device.format.type - else: - fmt_type = None - s += " %s on" % fmt_type - if self.isMigrate(): - pass - s += " %s (%s)" % (self.device.name, self.device.type) - return s - -class ActionCreateDevice(DeviceAction): - """ Action representing the creation of a new device. """ - type = ACTION_TYPE_CREATE - obj = ACTION_OBJECT_DEVICE - - def __init__(self, installer, device): - # FIXME: assert device.fs is None - DeviceAction.__init__(self, installer, device) - - def execute(self, intf=None): - self.device.create(intf=intf) - - -class ActionDestroyDevice(DeviceAction): - """ An action representing the deletion of an existing device. """ - type = ACTION_TYPE_DESTROY - obj = ACTION_OBJECT_DEVICE - - def __init__(self, installer, device): - # XXX should we insist that device.fs be None? - DeviceAction.__init__(self, installer, device) - if device.exists: - device.teardown() - - def execute(self, intf=None): - self.device.destroy() - - -class ActionResizeDevice(DeviceAction): - """ An action representing the resizing of an existing device. """ - type = ACTION_TYPE_RESIZE - obj = ACTION_OBJECT_DEVICE - - def __init__(self, installer, device, newsize): - if device.currentSize == newsize: - raise ValueError("new size same as old size") - - if not device.resizable: - raise ValueError("device is not resizable") - - DeviceAction.__init__(self, installer, device) - if newsize > device.currentSize: - self.dir = RESIZE_GROW - else: - self.dir = RESIZE_SHRINK - self.origsize = device.targetSize - self.device.targetSize = newsize - - def execute(self, intf=None): - self.device.resize(intf=intf) - - def cancel(self): - self.device.targetSize = self.origsize - - -class ActionCreateFormat(DeviceAction): - """ An action representing creation of a new filesystem. """ - type = ACTION_TYPE_CREATE - obj = ACTION_OBJECT_FORMAT - - def __init__(self, installer, device, format=None): - DeviceAction.__init__(self, installer, device) - if format: - self.origFormat = device.format - if self.device.format.exists: - self.device.format.teardown() - self.device.format = format - else: - self.origFormat = getFormat(None, installer=installer) - - def execute(self, intf=None): - if isinstance(self.device, PartitionDevice): - if self.format.partedFlag is not None: - self.device.setFlag(self.format.partedFlag) - self.device.disk.commit() - - udev_settle() - self.device.setup() - self.device.format.create(intf=intf, - device=self.device.path, - options=self.device.formatArgs) - # Get the UUID now that the format is created - udev_settle() - self.device.updateSysfsPath() - info = udev_get_block_device("/sys%s" % self.device.sysfsPath) - self.device.format.uuid = udev_device_get_uuid(info) - - def cancel(self): - self.device.format = self.origFormat - - @property - def format(self): - return self.device.format - - -class ActionDestroyFormat(DeviceAction): - """ An action representing the removal of an existing filesystem. - - XXX this seems unnecessary - """ - type = ACTION_TYPE_DESTROY - obj = ACTION_OBJECT_FORMAT - - def __init__(self, installer, device): - DeviceAction.__init__(self, installer, device) - # Save a deep copy of the device stack this format occupies. - # This is necessary since the stack of devices and formats - # required to get to this format may get yanked out from under - # us between now and execute. - self._device = copy.deepcopy(device) - self.origFormat = self._device.format - if device.format.exists: - device.format.teardown() - self.device.format = None - - def execute(self, intf=None): - """ wipe the filesystem signature from the device """ - if self.origFormat: - if isinstance(self.device, PartitionDevice) and \ - self.origFormat.partedFlag is not None: - # unset partition flags and commit - self.device.unsetFlag(self.origFormat.partedFlag) - self.device.disk.commit() - udev_settle() - - # set up our copy of the original device stack since the - # reference we got may have had any number of things changed - # since then (most notably, formats removed by this very - # class' constructor) - self._device.setup() - self.origFormat.destroy() - udev_settle() - self._device.teardown() - - def cancel(self): - self.device.format = self.origFormat - - @property - def format(self): - return self.origFormat - - -class ActionResizeFormat(DeviceAction): - """ An action representing the resizing of an existing filesystem. - - XXX Do we even want to support resizing of a filesystem without - also resizing the device it resides on? - """ - type = ACTION_TYPE_RESIZE - obj = ACTION_OBJECT_FORMAT - - def __init__(self, installer, device, newsize): - if device.targetSize == newsize: - raise ValueError("new size same as old size") - - DeviceAction.__init__(self, installer, device) - if newsize > device.format.currentSize: - self.dir = RESIZE_GROW - else: - self.dir = RESIZE_SHRINK - self.origSize = self.device.format.targetSize - self.device.format.targetSize = newsize - - def execute(self, intf=None): - self.device.setup() - self.device.format.doResize(intf=intf) - - def cancel(self): - self.device.format.targetSize = self.origSize - -class ActionMigrateFormat(DeviceAction): - """ An action representing the migration of an existing filesystem. """ - type = ACTION_TYPE_MIGRATE - obj = ACTION_OBJECT_FORMAT - - def __init__(self, installer, device): - if not device.format.migratable or not device.format.exists: - raise ValueError("device format is not migratable") - - DeviceAction.__init__(self, installer, device) - self.device.format.migrate = True - - def execute(self, intf=None): - self.device.setup() - self.device.format.doMigrate(intf=intf) - - def cancel(self): - self.device.format.migrate = False diff --git a/pkgs/core/pomona/src/storage/devicelibs/__init__.py b/pkgs/core/pomona/src/storage/devicelibs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pkgs/core/pomona/src/storage/devicelibs/crypto.py b/pkgs/core/pomona/src/storage/devicelibs/crypto.py deleted file mode 100644 index 52c9eddcf..000000000 --- a/pkgs/core/pomona/src/storage/devicelibs/crypto.py +++ /dev/null @@ -1,109 +0,0 @@ -# -# crypto.py -# -# Copyright (C) 2009 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 . -# -# Author(s): Dave Lehman -# Martin Sivak -# - -import os -from pycryptsetup import CryptSetup - -from ..errors import * - -def askyes(question): - return True - -def dolog(priority, text): - pass - -def is_luks(device): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - return cs.isLuks(device) - -def luks_uuid(device): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - return cs.luksUUID(device).strip() - -def luks_status(name): - """True means active, False means inactive (or non-existent)""" - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - return cs.luksStatus(name)!=0 - -def luks_format(device, - passphrase=None, key_file=None, - cipher=None, key_size=None): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - key_file_unlink = False - - if passphrase: - key_file = cs.prepare_passphrase_file(passphrase) - key_file_unlink = True - elif key_file and os.path.isfile(key_file): - pass - else: - raise ValueError("luks_format requires either a passphrase or a key file") - - #None is not considered as default value and pycryptsetup doesn't accept it - #so we need to filter out all Nones - kwargs = {} - kwargs["device"] = device - if cipher: kwargs["cipher"] = cipher - if key_file: kwargs["keyfile"] = key_file - if key_size: kwargs["keysize"] = key_size - - rc = cs.luksFormat(**kwargs) - if key_file_unlink: os.unlink(key_file) - - if rc: - raise CryptoError("luks_format failed for '%s'" % device) - -def luks_open(device, name, passphrase=None, key_file=None): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - key_file_unlink = False - - if passphrase: - key_file = cs.prepare_passphrase_file(passphrase) - key_file_unlink = True - elif key_file and os.path.isfile(key_file): - pass - else: - raise ValueError("luks_open requires either a passphrase or a key file") - - rc = cs.luksOpen(device = device, name = name, keyfile = key_file) - if key_file_unlink: os.unlink(key_file) - if rc: - raise CryptoError("luks_open failed for %s (%s)" % (device, name)) - -def luks_close(name): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - rc = cs.luksClose(name) - if rc: - raise CryptoError("luks_close failed for %s" % name) - -def luks_add_key(device, - new_passphrase=None, new_key_file=None, - passphrase=None, key_file=None): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - return cs.addKey(device, new_passphrase, new_key_file, passphrase, key_file) - - -def luks_remove_key(device, - del_passphrase=None, del_key_file=None, - passphrase=None, key_file=None): - cs = CryptSetup(yesDialog = askyes, logFunc = dolog) - return cs.removeKey(device, del_passphrase, del_key_file, passphrase, key_file) diff --git a/pkgs/core/pomona/src/storage/devicelibs/lvm.py b/pkgs/core/pomona/src/storage/devicelibs/lvm.py deleted file mode 100644 index 20fa02ac2..000000000 --- a/pkgs/core/pomona/src/storage/devicelibs/lvm.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/python - -import os -import re - -import util - -MAX_LV_SLOTS = 256 - -def has_lvm(): - has_lvm = False - for path in os.environ["PATH"].split(":"): - if os.access("%s/lvm" % path, os.X_OK): - has_lvm = True - break - - if has_lvm: - has_lvm = False - for line in open("/proc/devices").readlines(): - if "device-mapper" in line.split(): - has_lvm = True - break - - return has_lvm - -# Start config_args handling code -# -# Theoretically we can handle all that can be handled with the LVM --config -# argument. For every time we call an lvm_cc (lvm compose config) funciton -# we regenerate the config_args with all global info. -config_args = [] # Holds the final argument list -config_args_data = { "filterRejects": [], # regular expressions to reject. - "filterAccepts": [] } # regexp to accept - -def _composeConfig(): - """lvm command accepts lvm.conf type arguments preceded by --config. """ - global config_args, config_args_data - config_args = [] - - filter_string = "" - rejects = config_args_data["filterRejects"] - # we don't need the accept for now. - # accepts = config_args_data["filterAccepts"] - # if len(accepts) > 0: - # for i in range(len(rejects)): - # filter_string = filter_string + ("\"a|%s|\", " % accpets[i]) - - if len(rejects) > 0: - for i in range(len(rejects)): - filter_string = filter_string + ("\"r|%s|\"," % rejects[i]) - - filter_string = " filter=[%s] " % filter_string.strip(",") - - # As we add config strings we should check them all. - if filter_string == "": - # Nothing was really done. - return - - # devices_string can have (inside the brackets) "dir", "scan", - # "preferred_names", "filter", "cache_dir", "write_cache_state", - # "types", "sysfs_scan", "md_component_detection". see man lvm.conf. - devices_string = " devices {%s} " % (filter_string) # strings can be added - config_string = devices_string # more strings can be added. - config_args = ["--config", config_string] - -def lvm_cc_addFilterRejectRegexp(regexp): - """ Add a regular expression to the --config string.""" - global config_args_data - config_args_data["filterRejects"].append(regexp) - - # compoes config once more. - _composeConfig() - -def lvm_cc_resetFilter(): - global config_args_data - config_args_data["filterRejects"] = [] - config_args_data["filterAccepts"] = [] -# End config_args handling code. - -# Names that should not be used int the creation of VGs -lvm_vg_blacklist = [] -def blacklistVG(name): - global lvm_vg_blacklist - lvm_vg_blacklist.append(name) - -def getPossiblePhysicalExtents(floor=0): - """Returns a list of integers representing the possible values for - the physical extent of a volume group. Value is in KB. - - floor - size (in KB) of smallest PE we care about. - """ - - possiblePE = [] - curpe = 8 - while curpe <= 16384*1024: - if curpe >= floor: - possiblePE.append(curpe) - curpe = curpe * 2 - - return possiblePE - -def getMaxLVSize(): - """ Return the maximum size (in MB) of a logical volume. """ - if util.getArch() in ("x86_64",): #64bit architectures - return (8*1024*1024*1024*1024) #Max is 8EiB (very large number..) - else: - return (16*1024*1024) #Max is 16TiB - -def safeLvmName(name): - tmp = name.strip() - tmp = tmp.replace("/", "_") - tmp = re.sub("[^0-9a-zA-Z._]", "", tmp) - tmp = tmp.lstrip("_") - - return tmp diff --git a/pkgs/core/pomona/src/storage/devicelibs/swap.py b/pkgs/core/pomona/src/storage/devicelibs/swap.py deleted file mode 100644 index 6c45d7d7f..000000000 --- a/pkgs/core/pomona/src/storage/devicelibs/swap.py +++ /dev/null @@ -1,85 +0,0 @@ -import resource - -import util -import os - -from ..errors import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -def mkswap(device, label=''): - argv = [] - if label: - argv.extend(["-L", label]) - argv.append(device) - - rc = util.execWithRedirect("mkswap", argv, - stderr = "/dev/tty5", - stdout = "/dev/tty5", - searchPath=1) - - if rc: - raise SwapError("mkswap failed for '%s'" % device) - -def swapon(device, priority=None): - pagesize = resource.getpagesize() - buf = None - if pagesize > 2048: - num = pagesize - else: - num = 2048 - - try: - fd = os.open(device, os.O_RDONLY) - buf = os.read(fd, num) - except OSError: - pass - finally: - try: - os.close(fd) - except (OSError, UnboundLocalError): - pass - - if buf is not None and len(buf) == pagesize: - sig = buf[pagesize - 10:] - if sig == 'SWAP-SPACE': - raise OldSwapError - if sig == 'S1SUSPEND\x00' or sig == 'S2SUSPEND\x00': - raise SuspendError - - argv = [] - if isinstance(priority, int) and 0 <= priority <= 32767: - argv.extend(["-p", "%d" % priority]) - argv.append(device) - - rc = util.execWithRedirect("swapon", - argv, - stderr = "/dev/tty5", - stdout = "/dev/tty5", - searchPath=1) - - if rc: - raise SwapError("swapon failed for '%s'" % device) - -def swapoff(device): - rc = util.execWithRedirect("swapoff", [device], - stderr = "/dev/tty5", - stdout = "/dev/tty5", - searchPath=1) - - if rc: - raise SwapError("swapoff failed for '%s'" % device) - -def swapstatus(device): - lines = open("/proc/swaps").readlines() - status = False - for line in lines: - if not line.strip(): - continue - - if line.split()[0] == device: - status = True - break - - return status diff --git a/pkgs/core/pomona/src/storage/devices.py b/pkgs/core/pomona/src/storage/devices.py deleted file mode 100644 index 362805481..000000000 --- a/pkgs/core/pomona/src/storage/devices.py +++ /dev/null @@ -1,1698 +0,0 @@ -#/usr/bin/python - -import copy -import math -import parted -import _ped - -from errors import * -from formats import get_device_format_class, getFormat -from udev import * -from util import notify_kernel, numeric_type - -def devicePathToName(devicePath): - if devicePath.startswith("/dev/"): - name = devicePath[5:] - else: - name = devicePath - - if name.startswith("mapper/"): - name = name[7:] - - return name - -class Device(object): - """ A generic device. - - Device instances know which devices they depend upon (parents - attribute). They do not know which devices depend upon them, but - they do know whether or not they have any dependent devices - (isleaf attribute). - - A Device's setup method should set up all parent devices as well - as the device itself. It should not run the resident format's - setup method. - - Which Device types rely on their parents' formats being active? - DMCryptDevice - - A Device's teardown method should accept the keyword argument - recursive, which takes a boolean value and indicates whether or - not to recursively close parent devices. - - A Device's create method should create all parent devices as well - as the device itself. It should also run the Device's setup method - after creating the device. The create method should not create a - device's resident format. - - Which device type rely on their parents' formats to be created - before they can be created/assembled? - VolumeGroup - DMCryptDevice - - A Device's destroy method should destroy any resident format - before destroying the device itself. - - """ - _type = "generic device" - - def __init__(self, installer, name, parents=None, description=''): - """ Create a Device instance. - - Arguments: - - name -- the device name (generally a device node's basename) - - Keyword Arguments: - - parents -- a list of required Device instances - description -- a string describing the device - - """ - self.installer = installer - - self._name = name - if parents is None: - parents = [] - elif not isinstance(parents, list): - raise ValueError("parents must be a list of Device instances") - self.parents = parents - self.kids = 0 - self.description = description - - for parent in self.parents: - parent.addChild() - - def __deepcopy__(self, memo): - """ Create a deep copy of a Device instance. - - We can't do copy.deepcopy on parted objects, which is okay. - For these parted objects, we just do a shallow copy. - """ - new = self.__class__.__new__(self.__class__) - memo[id(self)] = new - shallow_copy_attrs = ('partedDisk', '_partedDevice', - '_partedPartition', '_origPartedDisk', - '_raidSet', 'installer', 'screen') - for (attr, value) in self.__dict__.items(): - if attr in shallow_copy_attrs: - setattr(new, attr, copy.copy(value)) - else: - setattr(new, attr, copy.deepcopy(value, memo)) - - return new - - def removeChild(self): - self.kids -= 1 - - def addChild(self): - self.kids += 1 - - def setup(self, intf=None): - """ Open, or set up, a device. """ - raise NotImplementedError("setup method not defined for Device") - - def teardown(self, recursive=None): - """ Close, or tear down, a device. """ - raise NotImplementedError("teardown method not defined for Device") - - def create(self, intf=None): - """ Create the device. """ - raise NotImplementedError("create method not defined for Device") - - def destroy(self): - """ Destroy the device. """ - raise NotImplementedError("destroy method not defined for Device") - - def setupParents(self): - """ Run setup method of all parent devices. """ - for parent in self.parents: - parent.setup() - - def teardownParents(self, recursive=None): - """ Run teardown method of all parent devices. """ - for parent in self.parents: - parent.teardown(recursive=recursive) - - def createParents(self): - """ Run create method of all parent devices. """ - self.installer.log.info("NOTE: recursive device creation disabled") - for parent in self.parents: - if not parent.exists: - raise DeviceError("parent device does not exist") - #parent.create() - - def dependsOn(self, dep): - """ Return True if this device depends on dep. """ - # XXX does a device depend on itself? - if dep in self.parents: - return True - - for parent in self.parents: - if parent.dependsOn(dep): - return True - - return False - - @property - def status(self): - """ This device's status. - - For now, this should return a boolean: - True the device is open and ready for use - False the device is not open - """ - return False - - @property - def name(self): - """ This device's name. """ - return self._name - - @property - def isleaf(self): - """ True if this device has no children. """ - return self.kids == 0 - - @property - def typeDescription(self): - """ String describing the device type. """ - return self._type - - @property - def type(self): - """ Device type. """ - return self._type - - @property - def mediaPresent(self): - return True - - -class StorageDevice(Device): - """ A generic storage device. - - A fully qualified path to the device node can be obtained via the - path attribute, although it is not guaranteed to be useful, or - even present, unless the StorageDevice's setup method has been - run. - - StorageDevice instances can optionally contain a filesystem, - represented by an FS instance. A StorageDevice's create method - should create a filesystem if one has been specified. - """ - _type = "storage device" - _devDir = "/dev" - sysfsBlockDir = "class/block" - _resizable = False - - def __init__(self, installer, device, format=None, - size=None, major=None, minor=None, - sysfsPath='', parents=None, exists=None): - """ Create a StorageDevice instance. - - Arguments: - - device -- the device name (generally a device node's basename) - - Keyword Arguments: - - size -- the device's size (units/format TBD) - major -- the device major - minor -- the device minor - sysfsPath -- sysfs device path - format -- a DeviceFormat instance - parents -- a list of required Device instances - description -- a string describing the device - - """ - self.installer = installer - - # allow specification of individual parents - if isinstance(parents, Device): - parents = [parents] - - Device.__init__(self, installer, device, parents=parents) - - self.uuid = None - self._format = None - self._size = numeric_type(size) - self.major = numeric_type(major) - self.minor = numeric_type(minor) - self.sysfsPath = sysfsPath - self.exists = exists - - # this may be handy for disk, dmraid, mpath, mdraid - self.diskLabel = None - - self.format = format - self.fstabComment = "" - self._targetSize = self._size - - self._partedDevice = None - - @property - def partedDevice(self): - if self.exists and self.status and not self._partedDevice: - # We aren't guaranteed to be able to get a device. In - # particular, built-in USB flash readers show up as devices but - # do not always have any media present, so parted won't be able - # to find a device. - try: - self._partedDevice = parted.Device(path=self.path) - except _ped.DeviceException: - pass - - return self._partedDevice - - def _getTargetSize(self): - return self._targetSize - - def _setTargetSize(self, newsize): - self._targetSize = newsize - - targetSize = property(lambda s: s._getTargetSize(), - lambda s, v: s._setTargetSize(v), - doc="Target size of this device") - - @property - def path(self): - """ Device node representing this device. """ - return "%s/%s" % (self._devDir, self.name) - - def updateSysfsPath(self): - """ Update this device's sysfs path. """ - sysfsName = self.name.replace("/", "!") - path = os.path.join("/sys", self.sysfsBlockDir, sysfsName) - self.sysfsPath = os.path.realpath(path)[4:] - self.installer.log.debug("%s sysfsPath set to %s" % (self.name, self.sysfsPath)) - - @property - def formatArgs(self): - """ Device-specific arguments to format creation program. """ - return [] - - @property - def resizable(self): - """ Can this type of device be resized? """ - return self._resizable and self.exists - - def notifyKernel(self): - """ Send a 'change' uevent to the kernel for this device. """ - if not self.exists: - self.installer.log.debug("Not sending change uevent for non-existent device") - return - - if not self.status: - self.installer.log.debug("Not sending change uevent for inactive device") - return - - path = os.path.normpath("/sys/%s" % self.sysfsPath) - try: - notify_kernel(path, action="change") - except Exception, e: - self.installer.log.warning("Failed to notify kernel of change: %s" % e) - - @property - def fstabSpec(self): - spec = self.path - if self.format and self.format.uuid: - spec = "UUID=%s" % self.format.uuid - return spec - - def resize(self, intf=None): - """ Resize the device. - - New size should already be set. - """ - raise NotImplementedError("resize method not defined for StorageDevice") - - def setup(self, intf=None): - """ Open, or set up, a device. """ - if not self.exists: - raise DeviceError("device has not been created") - - self.setupParents() - for parent in self.parents: - parent.format.setup() - - def teardown(self, recursive=None): - """ Close, or tear down, a device. """ - if not self.exists and not recursive: - raise DeviceError("device has not been created") - - if self.status and self.format.exists: - self.format.teardown() - udev_settle(timeout=10) - - if recursive: - self.teardownParents(recursive=recursive) - - def _getSize(self): - """ Get the device's size in MB, accounting for pending changes. """ - if self.exists and not self.mediaPresent: - return 0 - - if self.exists and self.partedDevice: - self._size = self.currentSize - - size = self._size - if self.exists and self.resizable and self.targetSize != size: - size = self.targetSize - - return size - - def _setSize(self, newsize): - """ Set the device's size to a new value. """ - if newsize > self.maxSize: - raise DeviceError("device cannot be larger than %s MB" % - (self.maxSize(),)) - self._size = newsize - - size = property(lambda x: x._getSize(), - lambda x, y: x._setSize(y), - doc="The device's size in MB, accounting for pending changes") - - @property - def currentSize(self): - """ The device's actual size. """ - size = 0 - if self.exists and self.partedDevice: - size = self.partedDevice.getSize() - elif self.exists: - size = self._size - return size - - @property - def minSize(self): - """ The minimum size this device can be. """ - if self.exists: - self.setup() - - if self.format.minSize: - return self.format.minSize - else: - return self.size - - @property - def maxSize(self): - """ The maximum size this device can be. """ - if self.format.maxSize > self.currentSize: - return self.currentSize - else: - return self.format.maxSize - - @property - def status(self): - """ This device's status. - - For now, this should return a boolean: - True the device is open and ready for use - False the device is not open - """ - if not self.exists: - return False - return os.access(self.path, os.W_OK) - - def _setFormat(self, format): - """ Set the Device's format. """ - if not format: - format = getFormat(None, installer=self.installer, device=self.path, exists=self.exists) - if self._format and self._format.status: - # FIXME: self.format.status doesn't mean much - raise DeviceError("Cannot replace active format") - - self._format = format - - def _getFormat(self): - return self._format - - format = property(lambda d: d._getFormat(), - lambda d,f: d._setFormat(f), - doc="The device's formatting.") - - def create(self, intf=None): - """ Create the device. """ - if self.exists: - raise DeviceError("device has already been created") - - self.createParents() - self.setupParents() - self.exists = True - self.setup() - - def destroy(self): - """ Destroy the device. """ - if not self.exists: - raise DeviceError("device has not been created") - - if not self.isleaf: - raise DeviceError("Cannot destroy non-leaf device") - - self.exists = False - - @property - def removable(self): - devpath = os.path.normpath("/sys/%s" % self.sysfsPath) - remfile = os.path.normpath("%s/removable" % devpath) - return (self.sysfsPath and os.path.exists(devpath) and - os.access(remfile, os.R_OK) and - open(remfile).readline().strip() == "1") - -class DiskDevice(StorageDevice): - """ A disk """ - _type = "disk" - - def __init__(self, installer, device, format=None, - size=None, major=None, minor=None, sysfsPath='', \ - parents=None, initcb=None, initlabel=None): - """ Create a DiskDevice instance. - - Arguments: - - device -- the device name (generally a device node's basename) - - Keyword Arguments: - - size -- the device's size (units/format TBD) - major -- the device major - minor -- the device minor - sysfsPath -- sysfs device path - format -- a DeviceFormat instance - parents -- a list of required Device instances - removable -- whether or not this is a removable device - - initcb -- the call back to be used when initiating disk. - initlabel -- whether to start with a fresh disklabel - - - DiskDevices always exist. - """ - self.installer = installer - StorageDevice.__init__(self, self.installer, device, format=format, - size=size, major=major, minor=minor, exists=True, - sysfsPath=sysfsPath, parents=parents) - - self.partedDisk = None - - if self.partedDevice: - if initlabel: - self.partedDisk = self.freshPartedDisk() - else: - try: - self.partedDisk = parted.Disk(device=self.partedDevice) - except _ped.DiskLabelException: - # if we have a cb function use it. else an error. - if initcb is not None and initcb(): - self.partedDisk = parted.freshDisk(device=self.partedDevice, \ - ty = platform.getPlatform(None).diskType) - else: - raise DeviceUserDeniedFormatError("User prefered to not format.") - - # We save the actual state of the disk here. Before the first - # modification (addPartition or removePartition) to the partition - # table we reset self.partedPartition to this state so we can - # perform the modifications one at a time. - if self.partedDisk: - self._origPartedDisk = self.partedDisk.duplicate() - else: - self._origPartedDisk = None - - def freshPartedDisk(self): - labelType = platform.getPlatform(None).diskType - return parted.freshDisk(device=self.partedDevice, ty=labelType) - - @property - def mediaPresent(self): - return self.partedDevice is not None - - @property - def model(self): - return getattr(self.partedDevice, "model", None) - - @property - def size(self): - """ The disk's size in MB """ - return super(DiskDevice, self).size - #size = property(StorageDevice._getSize) - - def resetPartedDisk(self): - """ Reset parted.Disk to reflect the actual layout of the disk. """ - self.partedDisk = self._origPartedDisk - - def removePartition(self, device): - if not self.mediaPresent: - raise DeviceError("Cannot remove partition from disk %s which has no media" % self.name) - - partition = self.partedDisk.getPartitionByPath(device.path) - if partition: - self.partedDisk.removePartition(partition) - - def addPartition(self, device): - if not self.mediaPresent: - raise DeviceError("cannot add partition to disk %s which has no media" % self.name) - - for part in self.partedDisk.partitions: - self.installer.log.debug("Disk %s: partition %s has geom %s" % (self.name, - part.getDeviceNodeName(), - part.geometry)) - - geometry = device.partedPartition.geometry - constraint = parted.Constraint(exactGeom=geometry) - partition = parted.Partition(disk=self.partedDisk, - type=device.partedPartition.type, - geometry=geometry) - self.partedDisk.addPartition(partition, constraint=constraint) - - def probe(self): - """ Probe for any missing information about this device. - - pyparted should be able to tell us anything we want to know. - size, disklabel type, maybe even partition layout - """ - if not self.diskLabel: - self.installer.log.debug("Setting %s diskLabel to %s" % (self.name, - self.partedDisk.type)) - self.diskLabel = self.partedDisk.type - - def commit(self, intf=None): - """ Commit changes to the device. """ - if not self.mediaPresent: - raise DeviceError("cannot commit to disk %s which has no media" % self.name) - - self.setupParents() - self.setup() - - # give committing 5 tries, failing that, raise an exception - attempt = 1 - maxTries = 5 - keepTrying = True - - while keepTrying and (attempt <= maxTries): - try: - self.partedDisk.commit() - keepTrying = False - except parted.DiskException as msg: - self.installer.log.warning(msg) - attempt += 1 - - if keepTrying: - raise DeviceError("cannot commit to disk %s after %d attempts" % (self.name, maxTries,)) - - # commit makes the kernel re-scan the partition table - udev_settle() - - def destroy(self): - """ Destroy the device. """ - if not self.mediaPresent: - raise DeviceError("cannot destroy disk %s which has no media" % self.name) - - self.partedDisk.deleteAllPartitions() - # this is perhaps a separate operation (wiping the disklabel) - self.partedDisk.clobber() - self.partedDisk.commit() - self.teardown() - - def setup(self, intf=None): - """ Open, or set up, a device. """ - if not os.path.exists(self.path): - raise DeviceError("device does not exist") - -class PartitionDevice(StorageDevice): - """ A disk partition. - - On types and flags... - - We don't need to deal with numerical partition types at all. The - only type we are concerned with is primary/logical/extended. Usage - specification is accomplished through the use of flags, which we - will set according to the partition's format. - """ - _type = "partition" - _resizable = True - - def __init__(self, installer, name, format=None, - size=None, grow=False, maxsize=None, - major=None, minor=None, bootable=None, - sysfsPath='', parents=None, exists=None, - partType=None, primary=False, weight=0): - """ Create a PartitionDevice instance. - - Arguments: - - name -- the device name (generally a device node's basename) - - Keyword Arguments: - - exists -- indicates whether this is an existing device - format -- the device's format (DeviceFormat instance) - - For existing partitions: - - parents -- the disk that contains this partition - major -- the device major - minor -- the device minor - sysfsPath -- sysfs device path - - For new partitions: - - partType -- primary,extended,&c (as parted constant) - grow -- whether or not to grow the partition - maxsize -- max size for growable partitions (in MB) - size -- the device's size (in MB) - bootable -- whether the partition is bootable - parents -- a list of potential containing disks - weight -- an initial sorting weight to assign - """ - self.req_disks = [] - self.req_partType = None - self.req_primary = None - self.req_grow = None - self.req_bootable = None - self.req_size = 0 - self.req_base_size = 0 - self.req_max_size = 0 - self.req_base_weight = 0 - - self._bootable = False - - StorageDevice.__init__(self, installer, name, format=format, size=size, - major=major, minor=minor, exists=exists, - sysfsPath=sysfsPath, parents=parents) - - if not exists: - # this is a request, not a partition -- it has no parents - self.req_disks = self.parents[:] - for dev in self.parents: - dev.removeChild() - self.parents = [] - - # FIXME: Validate partType, but only if this is a new partition - # Otherwise, overwrite it with the partition's type. - self._partType = None - self.partedFlags = {} - self._partedPartition = None - - # FIXME: Validate size, but only if this is a new partition. - # For existing partitions we will get the size from - # parted. - - if self.exists: - #self.partedPartition = parted.getPartitionByName(self.path) - self._partedPartition = self.disk.partedDisk.getPartitionByPath(self.path) - if not self._partedPartition: - raise DeviceError("cannot find parted partition instance") - - # collect information about the partition from parted - self.probe() - else: - # XXX It might be worthwhile to create a shit-simple - # PartitionRequest class and pass one to this constructor - # for new partitions. - self.req_name = name - self.req_partType = partType - self.req_primary = primary - self.req_max_size = numeric_type(maxsize) - self.req_grow = grow - self.req_bootable = bootable - - # req_size may be manipulated in the course of partitioning - self.req_size = self._size - - # req_base_size will always remain constant - self.req_base_size = self._size - - self.req_base_weight = weight - - def _setTargetSize(self, newsize): - if newsize != self.currentSize: - # change this partition's geometry in-memory so that other - # partitioning operations can complete (e.g., autopart) - self._targetSize = newsize - disk = self.disk.partedDisk - - # resize the partition's geometry in memory - (constraint, geometry) = self._computeResize(self.partedPartition) - disk.setPartitionGeometry(partition=self.partedPartition, - constraint=constraint, - start=geometry.start, end=geometry.end) - - @property - def path(self): - """ Device node representing this device. """ - if not self.parents: - # Bogus, but code in various places compares devices by path - # So we must return something unique - return self.name - - return "%s/%s" % (self.parents[0]._devDir, self.name) - - @property - def partType(self): - """ Get the partition's type (as parted constant). """ - try: - ptype = self.partedPartition.type - except AttributeError: - ptype = self._partType - - if not self.exists and ptype is None: - ptype = self.req_partType - - return ptype - - @property - def isExtended(self): - return self.partType & parted.PARTITION_EXTENDED - - @property - def isLogical(self): - return self.partType & parted.PARTITION_LOGICAL - - @property - def isPrimary(self): - return self.partType == parted.PARTITION_NORMAL - - @property - def isProtected(self): - return self.partType & parted.PARTITION_PROTECTED - - def _getPartedPartition(self): - return self._partedPartition - - def _setPartedPartition(self, partition): - """ Set this PartitionDevice's parted Partition instance. """ - if partition is None: - path = None - elif isinstance(partition, parted.Partition): - path = partition.path - else: - raise ValueError("partition must be a parted.Partition instance") - - self._partedPartition = partition - self.updateName() - - partedPartition = property(lambda d: d._getPartedPartition(), - lambda d,p: d._setPartedPartition(p)) - - def _getWeight(self): - return self.req_base_weight - - def _setWeight(self, weight): - self.req_base_weight = weight - - weight = property(lambda d: d._getWeight(), - lambda d,w: d._setWeight(w)) - - def updateSysfsPath(self): - """ Update this device's sysfs path. """ - if not self.parents: - self.sysfsPath = '' - - elif self.parents[0]._devDir == "/dev/mapper": - dm_node = dm.dm_node_from_name(self.name) - path = os.path.join("/sys", self.sysfsBlockDir, dm_node) - self.sysfsPath = os.path.realpath(path)[4:] - - else: - StorageDevice.updateSysfsPath(self) - - def updateName(self): - if self.partedPartition is None: - self._name = self.req_name - else: - self._name = \ - devicePathToName(self.partedPartition.getDeviceNodeName()) - - def dependsOn(self, dep): - """ Return True if this device depends on dep. """ - if isinstance(dep, PartitionDevice) and dep.isExtended and self.isLogical: - return True - - return Device.dependsOn(self, dep) - - def _setFormat(self, format): - """ Set the Device's format. """ - StorageDevice._setFormat(self, format) - - def _setBootable(self, bootable): - """ Set the bootable flag for this partition. """ - if self.partedPartition: - if self.flagAvailable(parted.PARTITION_BOOT): - if bootable: - self.setFlag(parted.PARTITION_BOOT) - else: - self.unsetFlag(parted.PARTITION_BOOT) - else: - raise DeviceError(_("boot flag not available for this " - "partition")) - - self._bootable = bootable - else: - self.req_bootable = bootable - - def _getBootable(self): - return self._bootable or self.req_bootable - - bootable = property(_getBootable, _setBootable) - - def flagAvailable(self, flag): - if not self.partedPartition: - return - - return self.partedPartition.isFlagAvailable(flag) - - def getFlag(self, flag): - if not self.partedPartition or not self.flagAvailable(flag): - return - - return self.partedPartition.getFlag(flag) - - def setFlag(self, flag): - if not self.partedPartition or not self.flagAvailable(flag): - return - - self.partedPartition.setFlag(flag) - - def unsetFlag(self, flag): - if not self.partedPartition or not self.flagAvailable(flag): - return - - self.partedPartition.unsetFlag(flag) - - def probe(self): - """ Probe for any missing information about this device. - - size, partition type, flags - """ - if not self.exists: - return - - # this is in MB - self._size = self.partedPartition.getSize() - self.targetSize = self._size - - self._partType = self.partedPartition.type - - self._bootable = self.getFlag(parted.PARTITION_BOOT) - - def create(self, intf=None): - """ Create the device. """ - if self.exists: - raise DeviceError("device already exists") - - self.createParents() - self.setupParents() - - self.disk.addPartition(self) - self.disk.commit() - - self.partedPartition = self.disk.partedDisk.getPartitionByPath(self.path) - - self.exists = True - self.setup() - - def _computeResize(self, partition): - # compute new size for partition - currentGeom = partition.geometry - currentDev = currentGeom.device - newLen = long(self.targetSize * 1024 * 1024) / currentDev.sectorSize - newGeometry = parted.Geometry(device=currentDev, - start=currentGeom.start, - length=newLen) - constraint = parted.Constraint(exactGeom=newGeometry) - - return (constraint, newGeometry) - - def resize(self, intf=None): - """ Resize the device. - - self.targetSize must be set to the new size. - """ - if self.targetSize != self.currentSize: - # partedDisk has been restored to _origPartedDisk, so - # recalculate resize geometry because we may have new - # partitions on the disk, which could change constraints - partition = self.disk.partedDisk.getPartitionByPath(self.path) - (constraint, geometry) = self._computeResize(partition) - - self.disk.partedDisk.setPartitionGeometry(partition=partition, - constraint=constraint, - start=geometry.start, - end=geometry.end) - - self.disk.commit() - self.notifyKernel() - - def destroy(self): - """ Destroy the device. """ - if not self.exists: - raise DeviceError("device has not been created") - - if not self.sysfsPath: - return - - if not self.isleaf: - raise DeviceError("Cannot destroy non-leaf device") - - self.setupParents() - self.disk.removePartition(self) - self.disk.commit() - - self.exists = False - - def _getSize(self): - """ Get the device's size. """ - size = self._size - if self.partedPartition: - # this defaults to MB - size = self.partedPartition.getSize() - return size - - def _setSize(self, newsize): - """ Set the device's size (for resize, not creation). - - Arguments: - - newsize -- the new size (in MB) - - """ - if not self.exists: - raise DeviceError("device does not exist") - - if newsize > self.disk.size: - raise ValueError("partition size would exceed disk size") - - # this defaults to MB - maxAvailableSize = self.partedPartition.getMaxAvailableSize() - - if newsize > maxAvailableSize: - raise ValueError("new size is greater than available space") - - # now convert the size to sectors and update the geometry - geometry = self.partedPartition.geometry - physicalSectorSize = geometry.device.physicalSectorSize - - new_length = (newsize * (1024 * 1024)) / physicalSectorSize - geometry.length = new_length - - def _getDisk(self): - """ The disk that contains this partition.""" - try: - disk = self.parents[0] - except IndexError: - disk = None - return disk - - def _setDisk(self, disk): - """Change the parent. - - Setting up a disk is not trivial. It has the potential to change - the underlying object. If necessary we must also change this object. - """ - if self.disk: - self.disk.removeChild() - - if disk: - self.parents = [disk] - disk.addChild() - else: - self.parents = [] - - disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d)) - - @property - def maxSize(self): - """ The maximum size this partition can be. """ - # XXX: this is MB by default - maxPartSize = self.partedPartition.getMaxAvailableSize() - - if self.format.maxSize > maxPartSize: - return maxPartSize - else: - return self.format.maxSize - -class OpticalDevice(StorageDevice): - """ An optical drive, eg: cdrom, dvd+r, &c. - - XXX Is this useful? - """ - _type = "cdrom" - - def __init__(self, installer, name, major=None, minor=None, exists=None, - format=None, parents=None, sysfsPath=''): - StorageDevice.__init__(self, installer, name, format=format, - major=major, minor=minor, exists=True, - parents=parents, sysfsPath=sysfsPath) - - @property - def mediaPresent(self): - """ Return a boolean indicating whether or not the device contains - media. - """ - if not self.exists: - raise DeviceError("device has not been created", self.path) - - try: - fd = os.open(self.path, os.O_RDONLY) - except OSError as e: - # errno 123 = No medium found - if e.errno == 123: - return False - else: - return True - else: - os.close(fd) - return True - - def eject(self): - """ Eject the drawer. """ - #import _isys - - if not self.exists: - raise DeviceError("device has not been created", self.path) - - # Make a best effort attempt to do the eject. If it fails, it's not - # critical. - fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK) - - #try: - # _isys.ejectcdrom(fd) - #except SystemError as e: - # log.warning("error ejecting cdrom %s: %s" % (self.name, e)) - - os.close(fd) - -class DMDevice(StorageDevice): - """ A device-mapper device """ - _type = "dm" - _devDir = "/dev/mapper" - - def __init__(self, installer, name, format=None, size=None, dmUuid=None, - target=None, exists=None, parents=None, sysfsPath=''): - """ Create a DMDevice instance. - - Arguments: - - name -- the device name (generally a device node's basename) - - Keyword Arguments: - - target -- the device-mapper target type (string) - size -- the device's size (units/format TBD) - dmUuid -- the device's device-mapper UUID - sysfsPath -- sysfs device path - format -- a DeviceFormat instance - parents -- a list of required Device instances - exists -- indicates whether this is an existing device - """ - StorageDevice.__init__(self, installer, name, format=format, size=size, - exists=exists, - parents=parents, sysfsPath=sysfsPath) - self.target = target - self.dmUuid = dmUuid - - def __str__(self): - s = StorageDevice.__str__(self) - s += (" target = %(target)s dmUuid = %(dmUuid)s" % - {"target": self.target, "dmUuid": self.dmUuid}) - return s - - @property - def fstabSpec(self): - """ Return the device specifier for use in /etc/fstab. """ - return self.path - - def updateSysfsPath(self): - """ Update this device's sysfs path. """ - if not self.exists: - raise DeviceError("device has not been created") - - if self.status: - dm_node = self.getDMNode() - path = os.path.join("/sys", self.sysfsBlockDir, dm_node) - self.sysfsPath = os.path.realpath(path)[4:] - else: - self.sysfsPath = '' - - #def getTargetType(self): - # return dm.getDmTarget(name=self.name) - - def getDMNode(self): - """ Return the dm-X (eg: dm-0) device node for this device. """ - if not self.exists: - raise DeviceError("device has not been created") - - return dm.dm_node_from_name(self.name) - - def _setName(self, name): - """ Set the device's map name. """ - if self.status: - raise DeviceError("device is active") - - self._name = name - #self.sysfsPath = "/dev/disk/by-id/dm-name-%s" % self.name - - name = property(lambda d: d._name, - lambda d,n: d._setName(n)) - - -class LVMVolumeGroupDevice(DMDevice): - """ An LVM Volume Group - - XXX Maybe this should inherit from StorageDevice instead of - DMDevice since there's no actual device. - """ - _type = "lvmvg" - - def __init__(self, installer, name, parents, size=None, free=None, - peSize=None, peCount=None, peFree=None, pvCount=None, - lvNames=[], uuid=None, exists=None, sysfsPath=''): - """ Create a LVMVolumeGroupDevice instance. - - Arguments: - - name -- the device name (generally a device node's basename) - parents -- a list of physical volumes (StorageDevice) - - Keyword Arguments: - - peSize -- physical extent size (in MB) - exists -- indicates whether this is an existing device - sysfsPath -- sysfs device path - - For existing VG's only: - - size -- the VG's size (in MB) - free -- amount of free space in the VG - peFree -- number of free extents - peCount -- total number of extents - pvCount -- number of PVs in this VG - lvNames -- the names of this VG's LVs - uuid -- the VG's UUID - - """ - self.pvClass = get_device_format_class("lvmpv") - if not self.pvClass: - raise DeviceError("cannot find 'lvmpv' class") - - if isinstance(parents, list): - for dev in parents: - if not isinstance(dev.format, self.pvClass): - raise ValueError("constructor requires a list of PVs") - elif not isinstance(parents.format, self.pvClass): - raise ValueError("constructor requires a list of PVs") - - DMDevice.__init__(self, installer, name, parents=parents, - exists=exists, sysfsPath=sysfsPath) - - self.uuid = uuid - self.free = numeric_type(free) - self.peSize = numeric_type(peSize) - self.peCount = numeric_type(peCount) - self.peFree = numeric_type(peFree) - self.pvCount = numeric_type(pvCount) - self.lvNames = lvNames - - # circular references, here I come - self._lvs = [] - - # TODO: validate peSize if given - if not self.peSize: - self.peSize = 4.0 # MB - - #self.probe() - - def __str__(self): - s = DMDevice.__str__(self) - s += (" free = %(free)s PE Size = %(peSize)s PE Count = %(peCount)s\n" - " PE Free = %(peFree)s PV Count = %(pvCount)s\n" - " LV Names = %(lvNames)s modified = %(modified)s\n" - " extents = %(extents)s free space = %(freeSpace)s\n" - " free extents = %(freeExtents)s\n" - " PVs = %(pvs)s\n" - " LVs = %(lvs)s" % - {"free": self.free, "peSize": self.peSize, "peCount": self.peCount, - "peFree": self.peFree, "pvCount": self.pvCount, - "lvNames": self.lvNames, "modified": self.isModified, - "extents": self.extents, "freeSpace": self.freeSpace, - "freeExtents": self.freeExtents, "pvs": self.pvs, "lvs": self.lvs}) - return s - - def probe(self): - """ Probe for any information about this device. """ - if not self.exists: - raise DeviceError("device has not been created") - - @property - def status(self): - """ The device's status (True means active). """ - if not self.exists: - return False - - # certainly if any of this VG's LVs are active then so are we - for lv in self.lvs: - if lv.status: - return True - - # if any of our PVs are not active then we cannot be - for pv in self.pvs: - if not pv.status: - return False - - # if we are missing some of our PVs we cannot be active - if len(self.pvs) != self.pvCount: - return False - - return True - - def _addDevice(self, device): - """ Add a new physical volume device to the volume group. - - XXX This is for use by device probing routines and is not - intended for modification of the VG. - """ - if not self.exists: - raise DeviceError("device does not exist") - - if not isinstance(device.format, self.pvClass): - raise ValueError("addDevice requires a PV arg") - - if self.uuid and device.format.vgUuid != self.uuid: - raise ValueError("UUID mismatch") - - if device in self.pvs: - raise ValueError("device is already a member of this VG") - - self.parents.append(device) - device.addChild() - - # now see if the VG can be activated - if len(self.parents) == self.pvCount: - self.setup() - - def _removeDevice(self, device): - """ Remove a physical volume from the volume group. - - This is for cases like clearing of preexisting partitions. - """ - try: - self.parents.remove(device) - except ValueError, e: - raise ValueError("cannot remove non-member PV device from VG") - - device.removeChild() - - def setup(self, intf=None): - """ Open, or set up, a device. - - XXX we don't do anything like "vgchange -ay" because we don't - want all of the LVs activated, just the VG itself. - """ - if not self.exists: - raise DeviceError("device has not been created") - - if self.status: - return - - if len(self.parents) < self.pvCount: - raise DeviceError("cannot activate VG with missing PV(s)") - - self.setupParents() - - def teardown(self, recursive=None): - """ Close, or tear down, a device. """ - if not self.exists and not recursive: - raise DeviceError("device has not been created") - - if self.status: - lvm.vgdeactivate(self.name) - - if recursive: - self.teardownParents(recursive=recursive) - - def create(self, intf=None): - """ Create the device. """ - if self.exists: - raise DeviceError("device already exists") - - pv_list = [] - #for pv in self.parents: - # This is a little bit different from other devices in that - # for VG we need the PVs to be formatted before we can create - # the VG. - # pv.create() - # pv.format.create() - # pv_list.append(pv.path) - pv_list = [pv.path for pv in self.parents] - self.createParents() - self.setupParents() - lvm.vgcreate(self.name, pv_list, self.peSize) - # FIXME set / update self.uuid here - self.exists = True - self.setup() - - def destroy(self): - """ Destroy the device. """ - if not self.exists: - raise DeviceError("device has not been created") - - # set up the pvs since lvm needs access to them to do the vgremove - self.setupParents() - - # this sometimes fails for some reason. - try: - lvm.vgreduce(self.name, [], rm=True) - lvm.vgremove(self.name) - except lvm.LVMError: - raise DeviceError("Could not completely remove VG %s" % self.name) - finally: - self.notifyKernel() - self.exists = False - - def reduce(self, pv_list): - """ Remove the listed PVs from the VG. """ - if not self.exists: - raise DeviceError("device has not been created") - - lvm.vgreduce(self.name, pv_list) - # XXX do we need to notify the kernel? - - def _addLogVol(self, lv): - """ Add an LV to this VG. """ - if lv in self._lvs: - raise ValueError("lv is already part of this vg") - - # verify we have the space, then add it - # do not verify for growing vg (because of ks) - if not lv.exists and \ - not [pv for pv in self.pvs if getattr(pv, "req_grow", None)] and \ - lv.size > self.freeSpace: - raise DeviceError("new lv is too large to fit in free space") - - self._lvs.append(lv) - - def _removeLogVol(self, lv): - """ Remove an LV from this VG. """ - if lv not in self.lvs: - raise ValueError("specified lv is not part of this vg") - - self._lvs.remove(lv) - - def _addPV(self, pv): - """ Add a PV to this VG. """ - if pv in self.pvs: - raise ValueError("pv is already part of this vg") - - # for the time being we will not allow vgextend - if self.exists: - raise DeviceError("cannot add pv to existing vg") - - self.parents.append(pv) - pv.addChild() - - def _removePV(self, pv): - """ Remove an PV from this VG. """ - if not pv in self.pvs: - raise ValueError("specified pv is not part of this vg") - - # for the time being we will not allow vgreduce - if self.exists: - raise DeviceError("cannot remove pv from existing vg") - - self.parents.remove(pv) - pv.removeChild() - - # We can't rely on lvm to tell us about our size, free space, &c - # since we could have modifications queued, unless the VG and all of - # its PVs already exist. - # - # -- liblvm may contain support for in-memory devices - - @property - def isModified(self): - """ Return True if the VG has changes queued that LVM is unaware of. """ - modified = True - if self.exists and not filter(lambda d: not d.exists, self.pvs): - modified = False - - return modified - - @property - def size(self): - """ The size of this VG """ - # TODO: just ask lvm if isModified returns False - - # sum up the sizes of the PVs and align to pesize - size = 0 - for pv in self.pvs: - size += max(0, self.align(pv.size - pv.format.peStart)) - - return size - - @property - def extents(self): - """ Number of extents in this VG """ - # TODO: just ask lvm if isModified returns False - - return self.size / self.peSize - - @property - def freeSpace(self): - """ The amount of free space in this VG (in MB). """ - # TODO: just ask lvm if isModified returns False - - # total the sizes of any LVs - used = 0 - size = self.size - self.installer.log.debug("%s size is %dMB" % (self.name, size)) - for lv in self.lvs: - self.installer.log.debug("lv %s (%s) uses %dMB" % (lv.name, lv, lv.size)) - used += self.align(lv.size, roundup=True) - - free = self.size - used - self.installer.log.debug("vg %s has %dMB free" % (self.name, free)) - return free - - @property - def freeExtents(self): - """ The number of free extents in this VG. """ - # TODO: just ask lvm if isModified returns False - return self.freeSpace / self.peSize - - def align(self, size, roundup=None): - """ Align a size to a multiple of physical extent size. """ - size = numeric_type(size) - - if roundup: - round = math.ceil - else: - round = math.floor - - # we want Kbytes as a float for our math - size *= 1024.0 - pesize = self.peSize * 1024.0 - return long((round(size / pesize) * pesize) / 1024) - - @property - def pvs(self): - """ A list of this VG's PVs """ - return self.parents[:] # we don't want folks changing our list - - @property - def lvs(self): - """ A list of this VG's LVs """ - return self._lvs[:] # we don't want folks changing our list - - @property - def complete(self): - """Check if the vg has all its pvs in the system - Return True if complete. - """ - return len(self.pvs) == self.pvCount or not self.exists - -class LVMLogicalVolumeDevice(DMDevice): - """ An LVM Logical Volume """ - _type = "lvmlv" - _resizable = True - - def __init__(self, installer, name, vgdev, size=None, uuid=None, - format=None, exists=None, sysfsPath='', - grow=None, maxsize=None, percent=None): - """ Create a LVMLogicalVolumeDevice instance. - - Arguments: - - name -- the device name (generally a device node's basename) - vgdev -- volume group (LVMVolumeGroupDevice instance) - - Keyword Arguments: - - size -- the device's size (in MB) - uuid -- the device's UUID - sysfsPath -- sysfs device path - format -- a DeviceFormat instance - exists -- indicates whether this is an existing device - - For new (non-existent) LVs only: - - grow -- whether to grow this LV - maxsize -- maximum size for growable LV (in MB) - percent -- percent of VG space to take - - """ - if isinstance(vgdev, list): - if len(vgdev) != 1: - raise ValueError("constructor requires a single LVMVolumeGroupDevice instance") - elif not isinstance(vgdev[0], LVMVolumeGroupDevice): - raise ValueError("constructor requires a LVMVolumeGroupDevice instance") - elif not isinstance(vgdev, LVMVolumeGroupDevice): - raise ValueError("constructor requires a LVMVolumeGroupDevice instance") - DMDevice.__init__(self, installer, name, size=size, format=format, - sysfsPath=sysfsPath, parents=vgdev, - exists=exists) - - self.uuid = uuid - - self.req_grow = None - self.req_max_size = 0 - self.req_size = 0 - self.req_percent = 0 - - if not self.exists: - self.req_grow = grow - self.req_max_size = numeric_type(maxsize) - # XXX should we enforce that req_size be pe-aligned? - self.req_size = self._size - self.req_percent = numeric_type(percent) - - # here we go with the circular references - self.vg._addLogVol(self) - - def __str__(self): - s = DMDevice.__str__(self) - s += (" VG device = %(vgdev)r percent = %(percent)s" % - {"vgdev": self.vg, "percent": self.req_percent}) - return s - - def _setSize(self, size): - size = self.vg.align(numeric_type(size)) - self.installer.log.debug("Trying to set lv %s size to %dMB" % (self.name, size)) - if size <= (self.vg.freeSpace + self._size): - self._size = size - self.targetSize = size - else: - self.installer.log.debug("Failed to set size: %dMB short" % (size - (self.vg.freeSpace + self._size),)) - raise ValueError("Not enough free space in volume group") - - size = property(StorageDevice._getSize, _setSize) - - @property - def vg(self): - """ This Logical Volume's Volume Group. """ - return self.parents[0] - - @property - def path(self): - """ Device node representing this device. """ - # Thank you lvm for this lovely hack. - return "%s/%s-%s" % (self._devDir, self.vg.name.replace("-","--"), - self._name.replace("-","--")) - - def getDMNode(self): - """ Return the dm-X (eg: dm-0) device node for this device. """ - # Thank you lvm for this lovely hack. - if not self.exists: - raise DeviceError("Device has not been created", self.path) - - return dm.dm_node_from_name("%s-%s" % (self.vg.name.replace("-","--"), \ - self._name.replace("-","--"))) - - @property - def name(self): - """ This device's name. """ - return "%s-%s" % (self.vg.name, self._name) - - @property - def lvname(self): - """ The LV's name (not including VG name). """ - return self._name - - @property - def complete(self): - """ Test if vg exits and if it has all pvs. """ - return self.vg.complete - - def setup(self, intf=None): - """ Open, or set up, a device. """ - if not self.exists: - raise DeviceError("Device has not been created", self.path) - - if self.status: - return - - self.vg.setup() - lvm.lvactivate(self.vg.name, self._name) - - # we always probe since the device may not be set up when we want - # information about it - self._size = self.currentSize - - def teardown(self, recursive=None): - """ Close, or tear down, a device. """ - if not self.exists and not recursive: - raise DeviceError("Device has not been created", self.path) - - if self.status and self.format.exists: - self.format.teardown() - udev_settle(timeout=10) - - if self.status: - lvm.lvdeactivate(self.vg.name, self._name) - - if recursive: - # It's likely that teardown of a VG will fail due to other - # LVs being active (filesystems mounted, &c), so don't let - # it bring everything down. - try: - self.vg.teardown(recursive=recursive) - except Exception as e: - log.debug("vg %s teardown failed; continuing" % self.vg.name) - - def create(self, intf=None): - """ Create the device. """ - if self.exists: - raise DeviceError("Device already exists", self.path) - - self.createParents() - self.setupParents() - - # should we use --zero for safety's sake? - lvm.lvcreate(self.vg.name, self._name, self.size) - # FIXME set / update self.uuid here - self.exists = True - self.setup() - - def destroy(self): - """ Destroy the device. """ - if not self.exists: - raise DeviceError("Device has not been created", self.path) - - self.teardown() - # set up the vg's pvs so lvm can remove the lv - self.vg.setupParents() - lvm.lvremove(self.vg.name, self._name) - self.exists = False - - def resize(self, intf=None): - # XXX resize format probably, right? - if not self.exists: - raise DeviceError("Device has not been created", self.path) - - # Setup VG parents (in case they are dmraid partitions for example) - self.vg.setupParents() - - if self.format.exists: - self.format.teardown() - - udev_settle(timeout=10) - lvm.lvresize(self.vg.name, self._name, self.size) diff --git a/pkgs/core/pomona/src/storage/devicetree.py b/pkgs/core/pomona/src/storage/devicetree.py deleted file mode 100644 index 8d3a1e17e..000000000 --- a/pkgs/core/pomona/src/storage/devicetree.py +++ /dev/null @@ -1,536 +0,0 @@ -#!/usr/bin/python - -import os -import block - -import formats - -from devicelibs import lvm -from devices import * -from errors import * -from udev import * - -class DeviceTree: - def __init__(self, installer): - self.installer = installer - self.storage = self.installer.ds.storage - - self._devices = [] - self._actions = [] - - self._ignoredDisks = [] - self.immutableDevices = [] - for disk in self.storage.ignoredDisks: - self.addIgnoredDisk(disk) - - def addIgnoredDisk(self, disk): - self._ignoredDisks.append(disk) - lvm.lvm_cc_addFilterRejectRegexp(disk) - - def populate(self): - """ Locate all storage devices. """ - # each iteration scans any devices that have appeared since the - # previous iteration - old_devices = [] - ignored_devices = [] - while True: - devices = [] - new_devices = udev_get_block_devices() - - for new_device in new_devices: - found = False - for old_device in old_devices: - if old_device['name'] == new_device['name']: - found = True - break - - if not found: - devices.append(new_device) - - if len(devices) == 0: - # nothing is changing -- we are finished building devices - break - - old_devices = new_devices - self.installer.log.info("Devices to scan: %s" % [d['name'] for d in devices]) - for dev in devices: - self.addUdevDevice(dev) - - # After having the complete tree we make sure that the system - # inconsistencies are ignored or resolved. - #for leaf in self.leaves: - # self._handleInconsistencies(leaf) - - #self.teardownAll() - try: - os.unlink("/etc/mdadm.conf") - except OSError: - pass - - @property - def devices(self): - """ Dict with device path keys and Device values. """ - devices = {} - - for device in self._devices: - if device.path in devices: - raise DeviceTreeError("duplicate paths in device tree") - - devices[device.path] = device - - return devices - - @property - def filesystems(self): - """ List of filesystems. """ - #""" Dict with mountpoint keys and filesystem values. """ - filesystems = [] - for dev in self.leaves: - if dev.format and getattr(dev.format, 'mountpoint', None): - filesystems.append(dev.format) - - return filesystems - - @property - def leaves(self): - """ List of all devices upon which no other devices exist. """ - leaves = [d for d in self._devices if d.isleaf] - return leaves - - def teardownAll(self): - """ Run teardown methods on all devices. """ - for device in self.leaves: - try: - device.teardown(recursive=True) - except (DeviceError, DeviceFormatError, LVMError) as e: - self.installer.log.info("Teardown of %s failed: %s" % (device.name, e)) - - def _addDevice(self, newdev): - """ Add a device to the tree. - - Raise ValueError if the device's identifier is already - in the list. - """ - if newdev.path in [d.path for d in self._devices]: - raise ValueError("device is already in tree") - - # make sure this device's parent devices are in the tree already - for parent in newdev.parents: - if parent not in self._devices: - raise DeviceTreeError("parent device not in tree") - - self._devices.append(newdev) - self.installer.log.info("Added %s (%s) to device tree" % (newdev.name, newdev.type)) - #self.installer.log.info(" Status: %s" % newdev.status) - #self.installer.log.info(" Format: %s" % newdev.format.type) - - def _removeDevice(self, dev, force=None, moddisk=True): - """ Remove a device from the tree. - - Only leaves may be removed. - """ - if dev not in self._devices: - raise ValueError("Device '%s' not in tree" % dev.name) - - if not dev.isleaf and not force: - self.installer.log.debug("%s has %d kids" % (dev.name, dev.kids)) - raise ValueError("Cannot remove non-leaf device '%s'" % dev.name) - - # if this is a partition we need to remove it from the parted.Disk - if moddisk and isinstance(dev, PartitionDevice) and \ - dev.disk is not None: - # if this partition hasn't been allocated it could not have - # a disk attribute - if dev.partedPartition.type == parted.PARTITION_EXTENDED and \ - len(dev.disk.partedDisk.getLogicalPartitions()) > 0: - raise ValueError("Cannot remove extended partition %s. " - "Logical partitions present." % dev.name) - - dev.disk.partedDisk.removePartition(dev.partedPartition) - - self._devices.remove(dev) - self.installer.log.debug("Removed %s (%s) from device tree" % (dev.name, - dev.type)) - - for parent in dev.parents: - # Will this cause issues with garbage collection? - # Do we care about garbage collection? At all? - parent.removeChild() - - def isIgnored(self, info): - """ Return True if info is a device we should ignore. - - Arguments: - - info -- a dict representing a udev db entry - - TODO: - - - filtering of SAN/FC devices - - filtering by driver? - - """ - sysfs_path = udev_device_get_sysfs_path(info) - name = udev_device_get_name(info) - if not sysfs_path: - return None - - if name in self._ignoredDisks: - return True - - for ignored in self._ignoredDisks: - if ignored == os.path.basename(os.path.dirname(sysfs_path)): - # this is a partition on a disk in the ignore list - return True - - # Ignore partitions found on the raw disks which are part of a - # dmraidset - for set in self.getDevicesByType("dm-raid array"): - for disk in set.parents: - if disk.name == os.path.basename(os.path.dirname(sysfs_path)): - return True - - # Ignore loop and ram devices, we normally already skip these in - # udev.py: enumerate_block_devices(), but we can still end up trying - # to add them to the tree when they are slaves of other devices, this - # happens for example with the livecd - if name.startswith("loop") or name.startswith("ram"): - return True - - # FIXME: check for virtual devices whose slaves are on the ignore list - - def getDeviceByName(self, name): - found = None - for device in self._devices: - if device.name == name: - found = device - break - return found - - def getDevicesByType(self, device_type): - # TODO: expand this to catch device format types - return [d for d in self._devices if d.type == device_type] - - def getDevicesByInstance(self, device_class): - return [d for d in self._devices if isinstance(d, device_class)] - - def registerAction(self, action): - """ Register an action to be performed at a later time. - - Modifications to the Device instance are handled before we - get here. - """ - if (action.isDestroy() or action.isResize() or \ - (action.isCreate() and action.isFormat())) and \ - action.device not in self._devices: - raise DeviceTreeError("device is not in the tree") - elif (action.isCreate() and action.isDevice()): - # this allows multiple create actions w/o destroy in between; - # we will clean it up before processing actions - #raise DeviceTreeError("device is already in the tree") - if action.device in self._devices: - self._removeDevice(action.device) - for d in self._devices: - if d.path == action.device.path: - self._removeDevice(d) - - if action.isCreate() and action.isDevice(): - self._addDevice(action.device) - elif action.isDestroy() and action.isDevice(): - self._removeDevice(action.device) - elif action.isCreate() and action.isFormat(): - if isinstance(action.device.format, formats.fs.FS) and \ - action.device.format.mountpoint in self.filesystems: - raise DeviceTreeError("mountpoint already in use") - - self.installer.log.debug("Registered action: %s" % action) - self._actions.append(action) - - def addUdevDevice(self, info): - # FIXME: this should be broken up into more discrete chunks - name = udev_device_get_name(info) - uuid = udev_device_get_uuid(info) - sysfs_path = udev_device_get_sysfs_path(info) - - if self.isIgnored(info): - self.installer.log.debug("Ignoring %s (%s)" % (name, sysfs_path)) - return - - self.installer.log.debug("Scanning %s (%s)..." % (name, sysfs_path)) - device = self.getDeviceByName(name) - - # - # The first step is to either look up or create the device - # - if udev_device_is_dm(info): - # try to look up the device - if device is None and uuid: - # try to find the device by uuid - device = self.getDeviceByUuid(uuid) - - if device is None: - device = self.addUdevDMDevice(info) - elif udev_device_is_md(info): - if device is None and uuid: - # try to find the device by uuid - device = self.getDeviceByUuid(uuid) - - if device is None: - device = self.addUdevMDDevice(info) - elif udev_device_is_cdrom(info): - if device is None: - device = self.addUdevOpticalDevice(info) - elif udev_device_is_dmraid(info): - # This is special handling to avoid the "unrecognized disklabel" - # code since dmraid member disks won't have a disklabel. We - # use a StorageDevice because DiskDevices need disklabels. - # Quite lame, but it doesn't matter much since we won't use - # the StorageDevice instances for anything. - if device is None: - device = StorageDevice(name, - major=udev_device_get_major(info), - minor=udev_device_get_minor(info), - sysfsPath=sysfs_path, exists=True) - self._addDevice(device) - elif udev_device_is_disk(info): - if device is None: - device = self.addUdevDiskDevice(info) - elif udev_device_is_partition(info): - if device is None: - device = self.addUdevPartitionDevice(info) - - # now handle the device's formatting - self.handleUdevDeviceFormat(info, device) - - def addUdevDiskDevice(self, info): - name = udev_device_get_name(info) - uuid = udev_device_get_uuid(info) - sysfs_path = udev_device_get_sysfs_path(info) - device = None - - try: - device = DiskDevice(self.installer, name, - major=udev_device_get_major(info), - minor=udev_device_get_minor(info), - sysfsPath=sysfs_path, - initlabel=False) - except DeviceUserDeniedFormatError: #drive not initialized? - self.addIgnoredDisk(name) - return - - self._addDevice(device) - return device - - def addUdevPartitionDevice(self, info): - name = udev_device_get_name(info) - uuid = udev_device_get_uuid(info) - sysfs_path = udev_device_get_sysfs_path(info) - device = None - - disk_name = os.path.basename(os.path.dirname(sysfs_path)) - disk = self.getDeviceByName(disk_name) - - if disk is None: - # create a device instance for the disk - path = os.path.dirname(os.path.realpath(sysfs_path)) - new_info = udev_get_block_device(path) - if new_info: - self.addUdevDevice(new_info) - disk = self.getDeviceByName(disk_name) - - if disk is None: - # if the current device is still not in - # the tree, something has gone wrong - self.installer.log.error("Failure scanning device %s" % disk_name) - return - - try: - device = PartitionDevice(self.installer, name, sysfsPath=sysfs_path, - major=udev_device_get_major(info), - minor=udev_device_get_minor(info), - exists=True, parents=[disk]) - except DeviceError: - # corner case sometime the kernel accepts a partition table - # which gets rejected by parted, in this case we will - # prompt to re-initialize the disk, so simply skip the - # faulty partitions. - return - - self._addDevice(device) - return device - - def addUdevOpticalDevice(self, info): - # Looks like if it has ID_INSTANCE=0:1 we can ignore it. - device = OpticalDevice(self.installer, udev_device_get_name(info), - major=udev_device_get_major(info), - minor=udev_device_get_minor(info), - sysfsPath=udev_device_get_sysfs_path(info)) - self._addDevice(device) - return device - - def handleUdevDeviceFormat(self, info, device): - #log.debug("%s" % info) - name = udev_device_get_name(info) - sysfs_path = udev_device_get_sysfs_path(info) - uuid = udev_device_get_uuid(info) - label = udev_device_get_label(info) - format_type = udev_device_get_format(info) - - format = None - if (not device) or (not format_type) or device.format.type: - # this device has no formatting or it has already been set up - # FIXME: this probably needs something special for disklabels - self.installer.log.debug("no type or existing type for %s, bailing" % (name,)) - return - - # set up the common arguments for the format constructor - args = [format_type] - kwargs = {"uuid": uuid, - "label": label, - "device": device.path, - "exists": True} - - # set up type-specific arguments for the format constructor - if format_type == "crypto_LUKS": - # luks/dmcrypt - kwargs["name"] = "luks-%s" % uuid - elif format_type == "linux_raid_member": - # mdraid - try: - kwargs["mdUuid"] = udev_device_get_md_uuid(info) - except KeyError: - self.installer.log.debug("mdraid member %s has no md uuid" % name) - elif format_type == "LVM2_member": - # lvm - try: - kwargs["vgName"] = udev_device_get_vg_name(info) - except KeyError as e: - self.installer.log.debug("PV %s has no vg_name" % name) - try: - kwargs["vgUuid"] = udev_device_get_vg_uuid(info) - except KeyError: - self.installer.log.debug("PV %s has no vg_uuid" % name) - try: - kwargs["peStart"] = udev_device_get_pv_pe_start(info) - except KeyError: - self.installer.log.debug("PV %s has no pe_start" % name) - - try: - self.installer.log.debug("type detected on '%s' is '%s'" % (name, format_type,)) - device.format = formats.getFormat(format_type, *args, **kwargs) - except FSError, e: - self.installer.log.debug("type '%s' on '%s' invalid, assuming no format - %s" % - (format_type, name, e,)) - device.format = formats.DeviceFormat(self.installer) - return - - # - # now do any special handling required for the device's format - # - #if device.format.type == "luks": - # self.handleUdevLUKSFormat(info, device) - #elif device.format.type == "mdmember": - # self.handleUdevMDMemberFormat(info, device) - #elif device.format.type == "dmraidmember": - # self.handleUdevDMRaidMemberFormat(info, device) - #elif device.format.type == "lvmpv": - # self.handleUdevLVMPVFormat(info, device) - - def handleUdevDMRaidMemberFormat(self, info, device): - name = udev_device_get_name(info) - sysfs_path = udev_device_get_sysfs_path(info) - uuid = udev_device_get_uuid(info) - major = udev_device_get_major(info) - minor = udev_device_get_minor(info) - - def _all_ignored(rss): - retval = True - for rs in rss: - if rs.name not in self._ignoredDisks: - retval = False - break - return retval - - # Have we already created the DMRaidArrayDevice? - rss = block.getRaidSetFromRelatedMem(uuid=uuid, name=name, - major=major, minor=minor) - if len(rss) == 0: - # we ignore the device in the hope that all the devices - # from this set will be ignored. - # FIXME: Can we reformat a raid device? - self.addIgnoredDisk(device.name) - return - - # We ignore the device if all the rss are in self._ignoredDisks - if _all_ignored(rss): - self.addIgnoredDisk(device.name) - return - - for rs in rss: - dm_array = self.getDeviceByName(rs.name) - if dm_array is not None: - # We add the new device. - dm_array._addDevice(device) - else: - # Activate the Raid set. - rs.activate(mknod=True) - - # Create the DMRaidArray - if self.zeroMbr: - cb = lambda: True - else: - cb = lambda: questionInitializeDisk(self.intf, - rs.name) - - # Create the DMRaidArray - if not self.clearPartDisks or \ - rs.name in self.clearPartDisks: - # if the disk contains protected partitions - # we will not wipe the disklabel even if - # clearpart --initlabel was specified - initlabel = self.reinitializeDisks - for protected in self.protectedPartitions: - disk_name = re.sub(r'p\d+$', '', protected) - if disk_name != protected and \ - disk_name == rs.name: - initlabel = False - break - - try: - dm_array = DMRaidArrayDevice(rs.name, - raidSet=rs, - parents=[device], - initcb=cb, - initlabel=initlabel) - - self._addDevice(dm_array) - # Use the rs's object on the device. - # pyblock can return the memebers of a set and the - # device has the attribute to hold it. But ATM we - # are not really using it. Commenting this out until - # we really need it. - #device.format.raidmem = block.getMemFromRaidSet(dm_array, - # major=major, minor=minor, uuid=uuid, name=name) - except DeviceUserDeniedFormatError: - # We should ignore the dmraid and its components - self.addIgnoredDisk(rs.name) - if _all_ignored(rss): - self.addIgnoredDisk(device.name) - rs.deactivate() - - def getDependentDevices(self, dep): - """ Return a list of devices that depend on dep. - - The list includes both direct and indirect dependents. - """ - dependents = [] - - # special handling for extended partitions since the logical - # partitions and their deps effectively depend on the extended - logicals = [] - if isinstance(dep, PartitionDevice) and dep.partType and \ - dep.isExtended: - # collect all of the logicals on the same disk - for part in self.getDevicesByInstance(PartitionDevice): - if part.partType and part.isLogical and part.disk == dep.disk: - logicals.append(part) diff --git a/pkgs/core/pomona/src/storage/errors.py b/pkgs/core/pomona/src/storage/errors.py deleted file mode 100644 index 7a02dc084..000000000 --- a/pkgs/core/pomona/src/storage/errors.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/python - -class StorageError(Exception): - pass - -# Device -class DeviceError(StorageError): - pass - -class DeviceCreateError(DeviceError): - pass - -class DeviceDestroyError(DeviceError): - pass - -class DeviceResizeError(DeviceError): - pass - -class DeviceSetupError(DeviceError): - pass - -class DeviceTeardownError(DeviceError): - pass - -class DeviceUserDeniedFormatError(DeviceError): - pass - -# DeviceFormat -class DeviceFormatError(StorageError): - pass - -class FormatCreateError(DeviceFormatError): - pass - -class FormatDestroyError(DeviceFormatError): - pass - -class FormatSetupError(DeviceFormatError): - pass - -class FormatTeardownError(DeviceFormatError): - pass - -class DMRaidMemberError(DeviceFormatError): - pass - -class FSError(DeviceFormatError): - pass - -class FSResizeError(FSError): - pass - -class FSMigrateError(FSError): - pass - -class LUKSError(DeviceFormatError): - pass - -class MDMemberError(DeviceFormatError): - pass - -class PhysicalVolumeError(DeviceFormatError): - pass - -class SwapSpaceError(DeviceFormatError): - pass - -# devicelibs -class SwapError(StorageError): - pass - -class SuspendError(SwapError): - pass - -class OldSwapError(SwapError): - pass - -class MDRaidError(StorageError): - pass - -class DMError(StorageError): - pass - -class LVMError(StorageError): - pass - -class CryptoError(StorageError): - pass - -# DeviceTree -class DeviceTreeError(StorageError): - pass - -# DeviceAction -class DeviceActionError(StorageError): - pass - -# partitioning -class PartitioningError(StorageError): - pass - -class PartitioningWarning(StorageError): - pass - -# udev -class UdevError(StorageError): - pass diff --git a/pkgs/core/pomona/src/storage/formats/__init__.py b/pkgs/core/pomona/src/storage/formats/__init__.py deleted file mode 100644 index f73f13840..000000000 --- a/pkgs/core/pomona/src/storage/formats/__init__.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/python - -import os -import copy - -device_formats = {} -def register_device_format(fmt_class): - if not issubclass(fmt_class, DeviceFormat): - raise ValueError("Argument must be a subclass of DeviceFormat") - device_formats[fmt_class._type] = fmt_class - -def getFormat(fmt_type, *args, **kwargs): - """ Return a DeviceFormat instance based on fmt_type and args. - - Given a device format type and a set of constructor arguments, - return a DeviceFormat instance. - - Return None if no suitable format class is found. - - Arguments: - - fmt_type -- the name of the format type (eg: 'ext3', 'swap') - - Keyword Arguments: - - The keyword arguments may vary according to the format type, - but here is the common set: - - device -- path to the device on which the format resides - uuid -- the UUID of the (preexisting) formatted device - exists -- whether or not the format exists on the device - - """ - fmt_class = get_device_format_class(fmt_type) - fmt = None - if fmt_class: - fmt = fmt_class(*args, **kwargs) - try: - className = fmt.__class__.__name__ - except AttributeError: - className = None - return fmt - -def get_device_format_class(fmt_type): - """ Return an appropriate format class based on fmt_type. """ - if not device_formats: - collect_device_format_classes() - - fmt = device_formats.get(fmt_type) - if not fmt: - for fmt_class in device_formats.values(): - if fmt_type and fmt_type == fmt_class._name: - fmt = fmt_class - break - elif fmt_type in fmt_class._udevTypes: - fmt = fmt_class - break - - # default to no formatting, AKA "Unknown" - if not fmt: - fmt = DeviceFormat - return fmt - -def collect_device_format_classes(): - """ Pick up all device format classes from this directory. - - Note: Modules must call register_device_format(FormatClass) in - order for the format class to be picked up. - """ - dir = os.path.dirname(__file__) - for module_file in os.listdir(dir): - # make sure we're not importing this module - if module_file.endswith(".py") and module_file != __file__: - mod_name = module_file[:-3] - try: - globals()[mod_name] = __import__(mod_name, globals(), locals(), [], -1) - except ImportError, e: - pass - -default_fstypes = ("ext4", "ext3", "ext2") -default_boot_fstypes = ("ext3", "ext2") -def get_default_filesystem_type(boot=None): - if boot: - fstypes = default_boot_fstypes - else: - fstypes = default_fstypes - - for fstype in fstypes: - try: - supported = get_device_format_class(fstype).supported - except AttributeError: - supported = None - - if supported: - return fstype - - raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(fstypes)) - -class DeviceFormat(object): - """ Generic device format. """ - _type = None - _name = "Unknown" - _udevTypes = [] - partedFlag = None - _formattable = False # can be formatted - _supported = False # is supported - _resizable = False # can be resized - _bootable = False # can be used as boot - _migratable = False # can be migrated - _maxSize = 0 # maximum size in MB - _minSize = 0 # minimum size in MB - _dump = False - _check = False - - def __init__(self, installer, *args, **kwargs): - """ Create a DeviceFormat instance. - - Keyword Arguments: - - device -- path to the underlying device - uuid -- this format's UUID - exists -- indicates whether this is an existing format - - """ - self.installer = installer - - self.device = kwargs.get("device") - self.uuid = kwargs.get("uuid") - self.exists = kwargs.get("exists") - self.options = kwargs.get("options") - self._migrate = False - - def __deepcopy__(self, memo): - new = self.__class__.__new__(self.__class__) - memo[id(self)] = new - shallow_copy_attrs = ('installer', 'screen') - for (attr, value) in self.__dict__.items(): - if attr in shallow_copy_attrs: - setattr(new, attr, copy.copy(value)) - else: - setattr(new, attr, copy.deepcopy(value, memo)) - - return new - - def _setOptions(self, options): - self._options = options - - def _getOptions(self): - return self._options - - options = property(_getOptions, _setOptions) - - def _setDevice(self, devspec): - if devspec and not devspec.startswith("/"): - raise ValueError("device must be a fully qualified path: %s" % devspec) - self._device = devspec - - def _getDevice(self): - return self._device - - device = property(lambda f: f._getDevice(), - lambda f,d: f._setDevice(d), - doc="Full path the device this format occupies") - - @property - def name(self): - if self._name: - name = self._name - else: - name = self.type - return name - - @property - def type(self): - return self._type - - def probe(self): - pass - - def notifyKernel(self): - if not self.device: - return - - if self.device.startswith("/dev/mapper/"): - try: - name = dm_node_from_name(os.path.basename(self.device)) - except Exception, e: - self.installer.log.warning("Failed to get dm node for %s" % self.device) - return - elif self.device: - name = os.path.basename(self.device) - - path = get_sysfs_path_by_name(name) - try: - notify_kernel(path, action="change") - except Exception, e: - self.installer.log.warning("Failed to notify kernel of change: %s" % e) - - def create(self, *args, **kwargs): - # allow late specification of device path - device = kwargs.get("device") - if device: - self.device = device - - if not os.path.exists(self.device): - raise FormatCreateError("invalid device specification") - - def destroy(self, *args, **kwargs): - # zero out the 1MB at the beginning and end of the device in the - # hope that it will wipe any metadata from filesystems that - # previously occupied this device - self.installer.log.debug("Zeroing out beginning and end of %s..." % self.device) - try: - fd = os.open(self.device, os.O_RDWR) - buf = '\0' * 1024 * 1024 - os.write(fd, buf) - os.lseek(fd, -1024 * 1024, 2) - os.write(fd, buf) - os.close(fd) - except OSError as e: - if getattr(e, "errno", None) == 28: # No space left in device - pass - else: - self.installer.log.error("Error zeroing out %s: %s" % (self.device, e)) - os.close(fd) - except Exception as e: - self.installer.log.error("Error zeroing out %s: %s" % (self.device, e)) - os.close(fd) - - self.exists = False - - def setup(self, *args, **kwargs): - if not self.exists: - raise FormatSetupError("format has not been created") - - if self.status: - return - - # allow late specification of device path - device = kwargs.get("device") - if device: - self.device = device - - if not self.device or not os.path.exists(self.device): - raise FormatSetupError("invalid device specification") - - def teardown(self, *args, **kwargs): - pass - - @property - def status(self): - return (self.exists and - self.__class__ is not DeviceFormat and - isinstance(self.device, str) and - self.device and - os.path.exists(self.device)) - - @property - def formattable(self): - """ Can we create formats of this type? """ - return self._formattable - - @property - def supported(self): - """ Is this format a supported type? """ - return self._supported - - @property - def resizable(self): - """ Can formats of this type be resized? """ - return self._resizable - - @property - def bootable(self): - """ Is this format type suitable for a boot partition? """ - return self._bootable - - @property - def migratable(self): - """ Can formats of this type be migrated? """ - return self._migratable - - @property - def migrate(self): - return self._migrate - - @property - def linuxNative(self): - """ Is this format type native to linux? """ - return self._linuxNative - - @property - def mountable(self): - """ Is this something we can mount? """ - return False - - @property - def dump(self): - """ Whether or not this format will be dumped by dump(8). """ - return self._dump - - @property - def check(self): - """ Whether or not this format is checked on boot. """ - return self._check - - @property - def maxSize(self): - """ Maximum size (in MB) for this format type. """ - return self._maxSize - - @property - def minSize(self): - """ Minimum size (in MB) for this format type. """ - return self._minSize - - -collect_device_format_classes() diff --git a/pkgs/core/pomona/src/storage/formats/fs.py b/pkgs/core/pomona/src/storage/formats/fs.py deleted file mode 100644 index 2eace6153..000000000 --- a/pkgs/core/pomona/src/storage/formats/fs.py +++ /dev/null @@ -1,929 +0,0 @@ -#!/usr/bin/python - -import os -import tempfile - -import isys - -import util - -from ..errors import * -from . import DeviceFormat, register_device_format - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -fs_configs = {} - -def get_kernel_filesystems(): - fs_list = [] - for line in open("/proc/filesystems").readlines(): - fs_list.append(line.split()[-1]) - return fs_list - -global kernel_filesystems -kernel_filesystems = get_kernel_filesystems() - -class FS(DeviceFormat): - """ Filesystem class. """ - _type = "Abstract Filesystem Class" # fs type name - _mountType = None # like _type but for passing to mount - _name = None - _mkfs = "" # mkfs utility - _modules = [] # kernel modules required for support - _resizefs = "" # resize utility - _labelfs = "" # labeling utility - _fsck = "" # fs check utility - _migratefs = "" # fs migration utility - _defaultFormatOptions = [] # default options passed to mkfs - _defaultMountOptions = ["defaults"] # default options passed to mount - _defaultLabelOptions = [] - _defaultCheckOptions = [] - _defaultMigrateOptions = [] - _migrationTarget = None - lostAndFoundContext = None - - def __init__(self, installer, *args, **kwargs): - """ Create a FS instance. - - Keyword Args: - - device -- path to the device containing the filesystem - mountpoint -- the filesystem's mountpoint - label -- the filesystem label - uuid -- the filesystem UUID - mountopts -- mount options for the filesystem - size -- the filesystem's size in MiB - exists -- indicates whether this is an existing filesystem - - """ - if self.__class__ is FS: - raise TypeError("FS is an abstract class.") - - self.installer = installer - - DeviceFormat.__init__(self, self.installer, *args, **kwargs) - # TODO: fsprofiles and other ways to add format args - self.mountpoint = kwargs.get("mountpoint") - self.mountopts = kwargs.get("mountopts") - self.label = kwargs.get("label") - - # filesystem size does not necessarily equal device size - self._size = kwargs.get("size") - self._mountpoint = None # the current mountpoint when mounted - if self.exists: - self._size = self._getExistingSize() - - self._targetSize = self._size - - if self.supported: - self.loadModule() - - def _setTargetSize(self, newsize): - """ Set a target size for this filesystem. """ - if not self.exists: - raise FSError("filesystem has not been created") - - if newsize is None: - # unset any outstanding resize request - self._targetSize = None - return - - if not self.minSize < newsize < self.maxSize: - raise ValueError("invalid target size request") - - self._targetSize = newsize - - def _getTargetSize(self): - """ Get this filesystem's target size. """ - return self._targetSize - - targetSize = property(_getTargetSize, _setTargetSize, - doc="Target size for this filesystem") - - def _getSize(self): - """ Get this filesystem's size. """ - size = self._size - if self.resizable and self.targetSize != size: - size = self.targetSize - return size - - size = property(_getSize, doc="This filesystem's size, accounting " - "for pending changes") - - def _getExistingSize(self): - """ Determine the size of this filesystem. Filesystem must - exist. - """ - size = 0 - - if self.mountable: - origMountPoint = self._mountpoint - - tmppath = tempfile.mkdtemp(prefix='getsize-', dir='/tmp') - self.mount(mountpoint=tmppath, options="ro") - buf = os.statvfs(tmppath) - self.unmount() - os.rmdir(tmppath) - - self._mountpoint = origMountPoint - - size = (buf.f_frsize * buf.f_blocks) / 1024.0 / 1024.0 - - return size - - @property - def currentSize(self): - """ The filesystem's current actual size. """ - size = 0 - if self.exists: - size = self._size - return float(size) - - def _getFormatOptions(self, options=None): - argv = [] - if options and isinstance(options, list): - argv.extend(options) - argv.extend(self.defaultFormatOptions) - argv.append(self.device) - return argv - - def doFormat(self, *args, **kwargs): - """ Create the filesystem. - - Arguments: - - None - - Keyword Arguments: - - intf -- InstallInterface instance - options -- list of options to pass to mkfs - - """ - intf = kwargs.get("intf") - options = kwargs.get("options") - - if self.exists: - raise FormatCreateError("filesystem already exists", self.device) - - if not self.formattable: - return - - if not self.mkfsProg: - return - - if self.exists: - return - - if not os.path.exists(self.device): - raise FormatCreateError("device does not exist", self.device) - - argv = self._getFormatOptions(options=options) - - self.installer.window = None - self.installer.window = self.installer.intf.progressWindow(_("Formatting"), - _("Creating filesystem on %s...") % (self.device,), - 100, pulse = True) - - try: - rc = util.execWithPulseProgress(self.mkfsProg, - argv, - stdout="/dev/tty5", - stderr="/dev/tty5", - progress=w) - except Exception as e: - raise FormatCreateError(e, self.device) - finally: - if self.installer.window: - self.installer.window.pop() - - if rc: - raise FormatCreateError("format failed: %s" % rc, self.device) - - self.exists = True - self.notifyKernel() - - def doMigrate(self, intf=None): - if not self.exists: - raise FSError("filesystem has not been created") - - if not self.migratable or not self.migrate: - return - - if not os.path.exists(self.device): - raise FSError("device does not exist") - - # if journal already exists skip - if isys.ext2HasJournal(self.device): - self.installer.log.info("Skipping migration of %s, has a journal already." % self.device) - return - - argv = self._defaultMigrateOptions[:] - argv.append(self.device) - try: - rc = util.execWithRedirect(self.migratefsProg, - argv, - stdout = "/dev/tty5", - stderr = "/dev/tty5", - searchPath = 1) - except Exception as e: - raise FSMigrateError("filesystem migration failed: %s" % e, self.device) - - if rc: - raise FSMigrateError("filesystem migration failed: %s" % rc, self.device) - - # the other option is to actually replace this instance with an - # instance of the new filesystem type. - self._type = self.migrationTarget - - @property - def resizeArgs(self): - argv = [self.device, "%d" % (self.targetSize,)] - return argv - - def doResize(self, *args, **kwargs): - """ Resize this filesystem to new size @newsize. - - Arguments: - - None - - Keyword Arguments: - - intf -- InstallInterface instance - - """ - intf = kwargs.get("intf") - - if not self.exists: - raise FSResizeError("filesystem does not exist", self.device) - - if not self.resizable: - raise FSResizeError("filesystem not resizable", self.device) - - if self.targetSize == self.currentSize: - return - - if not self.resizefsProg: - return - - if not os.path.exists(self.device): - raise FSResizeError("device does not exist", self.device) - - self.doCheck(intf=intf) - - w = None - if intf: - w = intf.progressWindow(_("Resizing"), - _("Resizing filesystem on %s...") - % (self.device,), - 100, pulse = True) - - try: - rc = util.execWithPulseProgress(self.resizefsProg, - self.resizeArgs, - stdout="/dev/tty5", - stderr="/dev/tty5", - progress=w) - except Exception as e: - raise FSResizeError(e, self.device) - finally: - if w: - w.pop() - - if rc: - raise FSResizeError("resize failed: %s" % rc, self.device) - - # XXX must be a smarter way to do this - self._size = self.targetSize - self.notifyKernel() - - def _getCheckArgs(self): - argv = [] - argv.extend(self.defaultCheckOptions) - argv.append(self.device) - return argv - - def doCheck(self, intf=None): - if not self.exists: - raise FSError("filesystem has not been created") - - if not self.fsckProg: - return - - if not os.path.exists(self.device): - raise FSError("device does not exist") - - w = None - if intf: - w = intf.progressWindow(_("Checking"), - _("Checking filesystem on %s...") - % (self.device), - 100, pulse = True) - - try: - rc = util.execWithPulseProgress(self.fsckProg, - self._getCheckArgs(), - stdout="/dev/tty5", - stderr="/dev/tty5", - progress = w) - except Exception as e: - raise FSError("filesystem check failed: %s" % e) - finally: - if w: - w.pop() - - if rc >= 4: - raise FSError("filesystem check failed: %s" % rc) - - def loadModule(self): - """Load whatever kernel module is required to support this filesystem.""" - global kernel_filesystems - - if not self._modules or self.mountType in kernel_filesystems: - return - - for module in self._modules: - try: - rc = util.execWithRedirect("modprobe", [module], - stdout="/dev/tty5", stderr="/dev/tty5", - searchPath=1) - except Exception as e: - self.installer.log.error("Could not load kernel module %s: %s" % (module, e)) - self._supported = False - return - - if rc: - self.installer.log.error("Could not load kernel module %s" % module) - self._supported = False - return - - # If we successfully loaded a kernel module, for this filesystem, we - # also need to update the list of supported filesystems. - kernel_filesystems = get_kernel_filesystems() - - def mount(self, *args, **kwargs): - """ Mount this filesystem. - - Arguments: - - None - - Keyword Arguments: - - options -- mount options (overrides all other option strings) - chroot -- prefix to apply to mountpoint - mountpoint -- mountpoint (overrides self.mountpoint) - """ - options = kwargs.get("options", "") - chroot = kwargs.get("chroot", "/") - mountpoint = kwargs.get("mountpoint") - - if not self.exists: - raise FSError("filesystem has not been created") - - if not mountpoint: - mountpoint = self.mountpoint - - if not mountpoint: - raise FSError("no mountpoint given") - - if self.status: - return - - if not isinstance(self, NoDevFS) and not os.path.exists(self.device): - raise FSError("device %s does not exist" % self.device) - - # XXX os.path.join is FUBAR: - # - # os.path.join("/mnt/foo", "/") -> "/" - # - #mountpoint = os.path.join(chroot, mountpoint) - mountpoint = os.path.normpath("%s/%s" % (chroot, mountpoint)) - util.mkdirChain(mountpoint) - - # passed in options override default options - if not options or not isinstance(options, str): - options = self.options - - try: - rc = isys.mount(self.device, mountpoint, - fstype=self.mountType, - options=options, - bindMount=isinstance(self, BindFS)) - except Exception as e: - raise FSError("mount failed: %s" % e) - - if rc: - raise FSError("mount failed: %s" % rc) - - self._mountpoint = mountpoint - - def unmount(self): - """ Unmount this filesystem. """ - if not self.exists: - raise FSError("filesystem has not been created") - - if not self._mountpoint: - # not mounted - return - - if not os.path.exists(self._mountpoint): - raise FSError("mountpoint does not exist") - - rc = isys.umount(self._mountpoint, removeDir = False) - if rc: - raise FSError("umount failed") - - self._mountpoint = None - - def _getLabelArgs(self, label): - argv = [] - argv.extend(self.defaultLabelOptions) - argv.extend([self.device, label]) - return argv - - def writeLabel(self, label): - """ Create a label for this filesystem. """ - if not self.exists: - raise FSError("filesystem has not been created") - - if not self.labelfsProg: - return - - if not os.path.exists(self.device): - raise FSError("device does not exist") - - argv = self._getLabelArgs(label) - rc = util.execWithRedirect(self.labelfsProg, - argv, - stderr="/dev/tty5", - searchPath=1) - if rc: - raise FSError("label failed") - - self.label = label - self.notifyKernel() - - @property - def isDirty(self): - return False - - @property - def mkfsProg(self): - """ Program used to create filesystems of this type. """ - return self._mkfs - - @property - def fsckProg(self): - """ Program used to check filesystems of this type. """ - return self._fsck - - @property - def resizefsProg(self): - """ Program used to resize filesystems of this type. """ - return self._resizefs - - @property - def labelfsProg(self): - """ Program used to manage labels for this filesystem type. """ - return self._labelfs - - @property - def migratefsProg(self): - """ Program used to migrate filesystems of this type. """ - return self._migratefs - - @property - def migrationTarget(self): - return self._migrationTarget - - @property - def utilsAvailable(self): - # we aren't checking for fsck because we shouldn't need it - for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg]: - if not prog: - continue - - if not filter(lambda d: os.access("%s/%s" % (d, prog), os.X_OK), - os.environ["PATH"].split(":")): - return False - - return True - - @property - def supported(self): - return self._supported and self.utilsAvailable - - @property - def mountable(self): - return (self.mountType in kernel_filesystems) or \ - (os.access("/sbin/mount.%s" % (self.mountType,), os.X_OK)) - - @property - def defaultFormatOptions(self): - """ Default options passed to mkfs for this filesystem type. """ - # return a copy to prevent modification - return self._defaultFormatOptions[:] - - @property - def defaultMountOptions(self): - """ Default options passed to mount for this filesystem type. """ - # return a copy to prevent modification - return self._defaultMountOptions[:] - - @property - def defaultLabelOptions(self): - """ Default options passed to labeler for this filesystem type. """ - # return a copy to prevent modification - return self._defaultLabelOptions[:] - - @property - def defaultCheckOptions(self): - """ Default options passed to checker for this filesystem type. """ - # return a copy to prevent modification - return self._defaultCheckOptions[:] - - def _getOptions(self): - options = ",".join(self.defaultMountOptions) - if self.mountopts: - # XXX should we clobber or append? - options = self.mountopts - return options - - def _setOptions(self, options): - self.mountopts = options - - options = property(_getOptions, _setOptions) - - @property - def migratable(self): - """ Can filesystems of this type be migrated? """ - return bool(self._migratable and self.migratefsProg and - filter(lambda d: os.access("%s/%s" - % (d, self.migratefsProg,), - os.X_OK), - os.environ["PATH"].split(":")) and - self.migrationTarget) - - def _setMigrate(self, migrate): - if not migrate: - self._migrate = migrate - return - - if self.migratable and self.exists: - self._migrate = migrate - else: - raise ValueError("Cannot set migrate on non-migratable filesystem") - - migrate = property(lambda f: f._migrate, lambda f,m: f._setMigrate(m)) - - @property - def type(self): - _type = self._type - if self.migrate: - _type = self.migrationTarget - - return _type - - @property - def mountType(self): - if not self._mountType: - self._mountType = self._type - - return self._mountType - - # These methods just wrap filesystem-specific methods in more - # generically named methods so filesystems and formatted devices - # like swap and LVM physical volumes can have a common API. - def create(self, *args, **kwargs): - if self.exists: - raise FSError("Filesystem already exists") - - DeviceFormat.create(self, *args, **kwargs) - - return self.doFormat(*args, **kwargs) - - def setup(self, *args, **kwargs): - """ Mount the filesystem. - - THe filesystem will be mounted at the directory indicated by - self.mountpoint. - """ - return self.mount(**kwargs) - - def teardown(self, *args, **kwargs): - return self.unmount(*args, **kwargs) - - @property - def status(self): - # FIXME check /proc/mounts or similar - if not self.exists: - return False - return self._mountpoint is not None - - -class Ext2FS(FS): - """ ext2 filesystem. """ - _type = "ext2" - _mkfs = "mke2fs" - _modules = ["ext2"] - _resizefs = "resize2fs" - _labelfs = "e2label" - _fsck = "e2fsck" - _formattable = True - _supported = True - _resizable = True - _bootable = True - _linuxNative = True - _maxSize = 8 * 1024 * 1024 - _minSize = 0 - _defaultFormatOptions = [] - _defaultMountOptions = ["defaults"] - _defaultCheckOptions = ["-f", "-p", "-C", "0"] - _dump = True - _check = True - _migratable = True - _migrationTarget = "ext3" - _migratefs = "tune2fs" - _defaultMigrateOptions = ["-j"] - - @property - def minSize(self): - """ Minimum size for this filesystem in MB. """ - size = self._minSize - if self.exists and os.path.exists(self.device): - buf = util.execWithCapture(self.resizefsProg, - ["-P", self.device], - stderr="/dev/tty5") - size = None - for line in buf.splitlines(): - if "minimum size of the filesystem:" not in line: - continue - - (text, sep, minSize) = line.partition(": ") - - size = int(minSize) / 1024.0 - - if size is None: - self.installer.log.warning("failed to get minimum size for %s filesystem " - "on %s" % (self.mountType, self.device)) - size = self._minSize - - return size - - @property - def isDirty(self): - return isys.ext2IsDirty(self.device) - - @property - def resizeArgs(self): - argv = ["-p", self.device, "%dM" % (self.targetSize,)] - return argv - -register_device_format(Ext2FS) - - -class Ext3FS(Ext2FS): - """ ext3 filesystem. """ - _type = "ext3" - _defaultFormatOptions = ["-t", "ext3"] - _migrationTarget = "ext4" - _modules = ["ext3"] - _defaultMigrateOptions = ["-O", "extents"] - - @property - def migratable(self): - """ Can filesystems of this type be migrated? """ - return (flags.cmdline.has_key("ext4migrate") and - Ext2FS.migratable) - -register_device_format(Ext3FS) - - -class Ext4FS(Ext3FS): - """ ext4 filesystem. """ - _type = "ext4" - _bootable = False - _defaultFormatOptions = ["-t", "ext4"] - _migratable = False - _modules = ["ext4"] - -register_device_format(Ext4FS) - - -class FATFS(FS): - """ FAT filesystem. """ - _type = "vfat" - _mkfs = "mkdosfs" - _modules = ["vfat"] - _labelfs = "dosfslabel" - _fsck = "dosfsck" - _formattable = True - _maxSize = 1024 * 1024 - _defaultMountOptions = ["umask=0077", "shortname=winnt"] - -register_device_format(FATFS) - - -class BTRFS(FS): - """ btrfs filesystem """ - _type = "btrfs" - _mkfs = "mkfs.btrfs" - _modules = ["btrfs"] - _resizefs = "btrfsctl" - _formattable = True - _linuxNative = True - _bootable = False - _maxLabelChars = 256 - _supported = True - _dump = True - _check = True - _maxSize = 16 * 1024 * 1024 - - def _getFormatOptions(self, options=None): - argv = [] - if options and isinstance(options, list): - argv.extend(options) - argv.extend(self.defaultFormatOptions) - if self.label: - argv.extend(["-L", self.label]) - argv.append(self.device) - return argv - - @property - def resizeArgs(self): - argv = ["-r", "%dm" % (self.targetSize,), self.device] - return argv - -register_device_format(BTRFS) - -class XFS(FS): - """ XFS filesystem """ - _type = "xfs" - _mkfs = "mkfs.xfs" - _modules = ["xfs"] - _labelfs = "xfs_admin" - _defaultFormatOptions = ["-f"] - _defaultLabelOptions = ["-L"] - _maxLabelChars = 16 - _maxSize = 16 * 1024 * 1024 - _formattable = True - _linuxNative = True - _supported = True - _dump = True - _check = True - -register_device_format(XFS) - -class NTFS(FS): - """ ntfs filesystem. """ - _type = "ntfs" - _resizefs = "ntfsresize" - _fsck = "ntfsresize" - _resizable = True - _minSize = 1 - _maxSize = 16 * 1024 * 1024 - _defaultMountOptions = ["defaults"] - _defaultCheckOptions = ["-c"] - - @property - def minSize(self): - """ The minimum filesystem size in megabytes. """ - size = self._minSize - if self.exists and os.path.exists(self.device): - minSize = None - buf = util.execWithCapture(self.resizefsProg, - ["-m", self.device], - stderr = "/dev/tty5") - for l in buf.split("\n"): - if not l.startswith("Minsize"): - continue - try: - min = l.split(":")[1].strip() - minSize = int(min) + 250 - except Exception, e: - minSize = None - self.installer.log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e)) - - if minSize is None: - self.installer.log.warning("Unable to discover minimum size of filesystem " - "on %s" %(self.device,)) - else: - size = minSize - - return size - - @property - def resizeArgs(self): - # You must supply at least two '-f' options to ntfsresize or - # the proceed question will be presented to you. - argv = ["-ff", "-s", "%dM" % (self.targetSize,), self.device] - return argv - -register_device_format(NTFS) - - -# if this isn't going to be mountable it might as well not be here -class NFS(FS): - """ NFS filesystem. """ - _type = "nfs" - _modules = ["nfs"] - - def _deviceCheck(self, devspec): - if devspec is not None and ":" not in devspec: - raise ValueError("device must be of the form :") - - @property - def mountable(self): - return False - - def _setDevice(self, devspec): - self._deviceCheck(devspec) - self._device = devspec - - def _getDevice(self): - return self._device - - device = property(lambda f: f._getDevice(), - lambda f,d: f._setDevice(d), - doc="Full path the device this format occupies") - -register_device_format(NFS) - - -class NFSv4(NFS): - """ NFSv4 filesystem. """ - _type = "nfs4" - _modules = ["nfs4"] - -register_device_format(NFSv4) - - -class Iso9660FS(FS): - """ ISO9660 filesystem. """ - _type = "iso9660" - _formattable = False - _supported = True - _resizable = False - _bootable = False - _linuxNative = False - _dump = False - _check = False - _migratable = False - _defaultMountOptions = ["ro"] - -register_device_format(Iso9660FS) - - -class NoDevFS(FS): - """ nodev filesystem base class """ - _type = "nodev" - - def __init__(self, *args, **kwargs): - FS.__init__(self, *args, **kwargs) - self.exists = True - self.device = self.type - - def _setDevice(self, devspec): - self._device = devspec - -register_device_format(NoDevFS) - - -class DevPtsFS(NoDevFS): - """ devpts filesystem. """ - _type = "devpts" - _defaultMountOptions = ["gid=5", "mode=620"] - -register_device_format(DevPtsFS) - - -# these don't really need to be here -class ProcFS(NoDevFS): - _type = "proc" - -register_device_format(ProcFS) - - -class SysFS(NoDevFS): - _type = "sysfs" - -register_device_format(SysFS) - - -class TmpFS(NoDevFS): - _type = "tmpfs" - -register_device_format(TmpFS) - - -class BindFS(FS): - _type = "bind" - - @property - def mountable(self): - return True - -register_device_format(BindFS) diff --git a/pkgs/core/pomona/src/storage/formats/luks.py b/pkgs/core/pomona/src/storage/formats/luks.py deleted file mode 100644 index 25d9db4f1..000000000 --- a/pkgs/core/pomona/src/storage/formats/luks.py +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/python - -import os - -from ..errors import * -#from ..devicelibs import crypto -from . import DeviceFormat, register_device_format - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -class LUKS(DeviceFormat): - """ A LUKS device. """ - _type = "luks" - _name = "LUKS" - _udevTypes = ["crypto_LUKS"] - _formattable = True # can be formatted - _supported = False # is supported - _linuxNative = True # for clearpart - - def __init__(self, *args, **kwargs): - """ Create a LUKS instance. - - Keyword Arguments: - - device -- the path to the underlying device - name -- the name of the mapped device - uuid -- this device's UUID - passphrase -- device passphrase (string) - key_file -- path to a file containing a key (string) - cipher -- cipher mode string - key_size -- key size in bits - exists -- indicates whether this is an existing format - """ - DeviceFormat.__init__(self, *args, **kwargs) - self.cipher = kwargs.get("cipher") - self.key_size = kwargs.get("key_size") - self.mapName = kwargs.get("name") - - if not self.exists and not self.cipher: - self.cipher = "aes-xts-plain" - if not self.key_size: - # default to the max (512 bits) for aes-xts - self.key_size = 512 - - # FIXME: these should both be lists, but managing them will be a pain - self.__passphrase = kwargs.get("passphrase") - self._key_file = kwargs.get("key_file") - - if not self.mapName and self.exists and self.uuid: - self.mapName = "luks-%s" % self.uuid - elif not self.mapName and self.device: - self.mapName = "luks-%s" % os.path.basename(self.device) - - def _setPassphrase(self, passphrase): - """ Set the passphrase used to access this device. """ - self.__passphrase = passphrase - - passphrase = property(fset=_setPassphrase) - - @property - def hasKey(self): - return (self.__passphrase or - (self._key_file and os.access(self._key_file, os.R_OK))) - - @property - def configured(self): - """ To be ready we need a key or passphrase and a map name. """ - return self.hasKey and self.mapName - - @property - def status(self): - if not self.exists or not self.mapName: - return False - return os.path.exists("/dev/mapper/%s" % self.mapName) - - def probe(self): - """ Probe for any missing information about this format. - - cipher mode, key size - """ - raise NotImplementedError("Probe method not defined for LUKS") - - def setup(self, *args, **kwargs): - """ Open, or set up, the format. """ - if not self.configured: - raise LUKSError("luks device not configured") - - if self.status: - return - - DeviceFormat.setup(self, *args, **kwargs) - crypto.luks_open(self.device, self.mapName, - passphrase=self.__passphrase, - key_file=self._key_file) - - def teardown(self, *args, **kwargs): - """ Close, or tear down, the format. """ - if not self.exists: - raise LUKSError("format has not been created") - - if self.status: - log.debug("unmapping %s" % self.mapName) - crypto.luks_close(self.mapName) - - def create(self, *args, **kwargs): - """ Create the format. """ - if not self.hasKey: - raise LUKSError("luks device has no key/passphrase") - - DeviceFormat.create(self, *args, **kwargs) - crypto.luks_format(self.device, - passphrase=self.__passphrase, - key_file=self._key_file, - cipher=self.cipher, - key_size=self.key_size) - - self.uuid = crypto.luks_uuid(self.device) - self.exists = True - self.mapName = "luks-%s" % self.uuid - self.notifyKernel() - - def destroy(self, *args, **kwargs): - """ Create the format. """ - self.teardown() - DeviceFormat.destroy(self, *args, **kwargs) - - @property - def keyFile(self): - """ Path to key file to be used in /etc/crypttab """ - return self._key_file - - def addKeyFromFile(self, keyfile): - """ Add a new key from a file. - - Add the contents of the specified key file to an available key - slot in the LUKS header. - """ - if not self.exists: - raise LUKSError("Format has not been created") - - crypto.luks_add_key(self.device, - passphrase=self.__passphrase, - key_file=self._key_file, - new_key_file=keyfile) - - def addPassphrase(self, passphrase): - """ Add a new passphrase. - - Add the specified passphrase to an available key slot in the - LUKS header. - """ - if not self.exists: - raise LUKSError("Format has not been created") - - crypto.luks_add_key(self.device, - passphrase=self.__passphrase, - key_file=self._key_file, - new_passphrase=passphrase) - - def removeKeyFromFile(self, keyfile): - """ Remove a key contained in a file. - - Remove key contained in the specified key file from the LUKS - header. - """ - if not self.exists: - raise LUKSError("Format has not been created") - - crypto.luks_remove_key(self.device, - passphrase=self.__passphrase, - key_file=self._key_file, - del_key_file=keyfile) - - - def removePassphrase(self, passphrase): - """ Remove the specified passphrase from the LUKS header. """ - if not self.exists: - raise LUKSError("Format has not been created") - - crypto.luks_remove_key(self.device, - passphrase=self.__passphrase, - key_file=self._key_file, - del_passphrase=passphrase) - - -register_device_format(LUKS) diff --git a/pkgs/core/pomona/src/storage/formats/lvmpv.py b/pkgs/core/pomona/src/storage/formats/lvmpv.py deleted file mode 100644 index cccff87db..000000000 --- a/pkgs/core/pomona/src/storage/formats/lvmpv.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/python - -from parted import PARTITION_LVM - -from . import DeviceFormat, register_device_format -from ..errors import * -from ..devicelibs import lvm - -class LVMPhysicalVolume(DeviceFormat): - """ An LVM physical volume. """ - _type = "lvmpv" - _name = "physical volume (LVM)" - _udevTypes = ["LVM2_member"] - partedFlag = PARTITION_LVM - _formattable = True # can be formatted - _supported = True # is supported - _linuxNative = True # for clearpart - - def __init__(self, *args, **kwargs): - """ Create an LVMPhysicalVolume instance. - - Keyword Arguments: - - device -- path to the underlying device - uuid -- this PV's uuid (not the VG uuid) - vgName -- the name of the VG this PV belongs to - vgUuid -- the UUID of the VG this PV belongs to - peStart -- offset of first physical extent - exists -- indicates whether this is an existing format - - """ - DeviceFormat.__init__(self, *args, **kwargs) - self.vgName = kwargs.get("vgName") - self.vgUuid = kwargs.get("vgUuid") - # liblvm may be able to tell us this at some point, even - # for not-yet-created devices - self.peStart = kwargs.get("peStart", 0.1875) # in MB - - def probe(self): - """ Probe for any missing information about this device. """ - if not self.exists: - raise PhysicalVolumeError("format has not been created") - - #info = lvm.pvinfo(self.device) - #self.vgName = info['vg_name'] - #self.vgUuid = info['vg_uuid'] - - def create(self, *args, **kwargs): - """ Create the format. """ - DeviceFormat.create(self, *args, **kwargs) - # Consider use of -Z|--zero - # -f|--force or -y|--yes may be required - - # lvm has issues with persistence of metadata, so here comes the - # hammer... - DeviceFormat.destroy(self, *args, **kwargs) - - lvm.pvcreate(self.device) - self.exists = True - self.notifyKernel() - - def destroy(self, *args, **kwargs): - """ Destroy the format. """ - if not self.exists: - raise PhysicalVolumeError("format has not been created") - - if self.status: - raise PhysicalVolumeError("device is active") - - # FIXME: verify path exists? - try: - lvm.pvremove(self.device) - except LVMError: - DeviceFormat.destroy(self, *args, **kwargs) - - self.exists = False - self.notifyKernel() - - @property - def status(self): - # XXX hack - return (self.exists and self.vgName and - os.path.isdir("/dev/mapper/%s" % self.vgName)) - -register_device_format(LVMPhysicalVolume) diff --git a/pkgs/core/pomona/src/storage/formats/swap.py b/pkgs/core/pomona/src/storage/formats/swap.py deleted file mode 100644 index 487d3656b..000000000 --- a/pkgs/core/pomona/src/storage/formats/swap.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/python - -from parted import PARTITION_SWAP - -from . import DeviceFormat, register_device_format -from ..devicelibs import swap - -class SwapSpace(DeviceFormat): - """ Swap space """ - _type = "swap" - _name = None - _udevTypes = ["swap"] - partedFlag = PARTITION_SWAP - _formattable = True # can be formatted - _supported = True # is supported - _linuxNative = True # for clearpart - - def __init__(self, installer, *args, **kwargs): - """ Create a SwapSpace instance. - - Keyword Arguments: - - device -- path to the underlying device - uuid -- this swap space's uuid - label -- this swap space's label - priority -- this swap space's priority - exists -- indicates whether this is an existing format - - """ - self.installer = installer - DeviceFormat.__init__(self, self.installer, *args, **kwargs) - - self.priority = kwargs.get("priority") - self.label = kwargs.get("label") - - def _setPriority(self, priority): - if priority is None: - self._priority = None - return - - if not isinstance(priority, int) or not 0 <= priority <= 32767: - raise ValueError("swap priority must be an integer between 0 and 32767") - - self._priority = priority - - def _getPriority(self): - return self._priority - - priority = property(_getPriority, _setPriority, - doc="The priority of the swap device") - - def _getOptions(self): - opts = "" - if self.priority is not None: - opts += "pri=%d" % self.priority - - return opts - - def _setOptions(self, opts): - if not opts: - self.priority = None - return - - for option in opts.split(","): - (opt, equals, arg) = option.partition("=") - if equals and opt == "pri": - try: - self.priority = int(arg) - except ValueError: - self.installer.log.info("invalid value for swap priority: %s" % arg) - - options = property(_getOptions, _setOptions, - doc="The swap device's fstab options string") - - @property - def status(self): - """ Device status. """ - return self.exists and swap.swapstatus(self.device) - - def setup(self, *args, **kwargs): - """ Open, or set up, a device. """ - if not self.exists: - raise SwapSpaceError("format has not been created") - - if self.status: - return - - DeviceFormat.setup(self, *args, **kwargs) - swap.swapon(self.device, priority=self.priority) - - def teardown(self, *args, **kwargs): - """ Close, or tear down, a device. """ - if not self.exists: - raise SwapSpaceError("format has not been created") - - if self.status: - swap.swapoff(self.device) - - def create(self, *args, **kwargs): - """ Create the device. """ - if self.exists: - raise SwapSpaceError("format already exists") - - if self.status: - raise SwapSpaceError("device exists and is active") - - DeviceFormat.create(self, *args, **kwargs) - swap.mkswap(self.device, label=self.label) - self.exists = True - - -register_device_format(SwapSpace) diff --git a/pkgs/core/pomona/src/storage/partitioning.py b/pkgs/core/pomona/src/storage/partitioning.py deleted file mode 100644 index 0fb61d9d4..000000000 --- a/pkgs/core/pomona/src/storage/partitioning.py +++ /dev/null @@ -1,1059 +0,0 @@ -#!/usr/bin/python - -import os -import parted - -from constants import * -from errors import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -def doAutoPartition(installer): - if installer.dispatch.dir == DISPATCH_BACK: - installer.ds.storage.reset() - return - - disks = [] - devs = [] - - if installer.ds.storage.doAutoPart: - clearPartitions(installer) - (disks, devs) = _createFreeSpacePartitions(installer) - - if disks == []: - installer.intf.messageWindow(_("Error Partitioning"), - _("Could not find enough free space " - "for automatic partitioning, please " - "use another partitioning method.")) - return DISPATCH_BACK - - _schedulePartitions(installer, disks) - - # run the autopart function to allocate and grow partitions - try: - doPartitioning(installer) - - if installer.ds.storage.doAutoPart: - _scheduleLVs(installer, devs) - - # grow LVs - growLVM(installer) - except PartitioningWarning as msg: - installer.intf.messageWindow(_("Warnings During Automatic Partitioning"), - _("Following warnings occurred during automatic " - "partitioning:\n\n%s") % (msg,),) - log.warning(msg) - except PartitioningError as msg: - # restore drives to original state - installer.ds.storage.reset() - #installer.dispatch.skipStep("partition", skip = 0) - installer.intf.messageWindow(_("Error Partitioning"), - _("Could not allocate requested partitions: \n\n" - "%s.%s") % (msg, extra)) - return - - # now do a full check of the requests - (errors, warnings) = installer.ds.storage.sanityCheck() - if warnings: - for warning in warnings: - installer.log.warning(warning) - if errors: - errortxt = "\n".join(errors) - installer.intf.messageWindow(_("Automatic Partitioning Errors"), - _("The following errors occurred with your " - "partitioning:\n\n%s\n\n" - "This can happen if there is not enough " - "space on your hard drive(s) for the " - "installation.\n\n" - "Press 'OK' to choose a different partitioning option.") - % (errortxt,),) - - installer.ds.storage.reset() - #XXX return DISPATCH_BACK - return INSTALL_OK - -def doPartitioning(installer): - """ Allocate and grow partitions. - - When this function returns without error, all PartitionDevice - instances must have their parents set to the disk they are - allocated on, and their partedPartition attribute set to the - appropriate parted.Partition instance from their containing - disk. All req_xxxx attributes must be unchanged. - - Arguments: - - storage - Main anaconda Storage instance - - Keyword arguments: - - exclusiveDisks -- list of names of disks to use - - """ - storage = installer.ds.storage - disks = storage.disks - - exclusiveDisks = storage.clearDisks - if exclusiveDisks: - disks = [d for d in disks if d.name in exclusiveDisks] - - for disk in disks: - disk.setup() - - partitions = storage.partitions - for part in partitions: - part.req_bootable = False - if not part.exists: - # start over with flexible-size requests - part.req_size = part.req_base_size - - # FIXME: isn't there a better place for this to happen? - #try: - # bootDev = anaconda.platform.bootDevice() - #except DeviceError: - # bootDev = None - - #if bootDev: - # bootDev.req_bootable = True - - # FIXME: make sure non-existent partitions have empty parents list - allocatePartitions(installer, disks, partitions) - growPartitions(installer, disks, partitions) - # The number and thus the name of partitions may have changed now, - # allocatePartitions() takes care of this for new partitions, but not - # for pre-existing ones, so we update the name of all partitions here - for part in partitions: - part.updateName() - - # XXX hack -- if we created any extended partitions we need to add - # them to the tree now - for disk in disks: - extended = disk.partedDisk.getExtendedPartition() - if not extended: - continue - - extendedName = devicePathToName(extended.getDeviceNodeName()) - device = storage.devicetree.getDeviceByName(extendedName) - if device: - if not device.exists: - # created by us, update partedPartition - device.partedPartition = extended - continue - - # This is a little odd because normally instantiating a partition - # that does not exist means leaving self.parents empty and instead - # populating self.req_disks. In this case, we need to skip past - # that since this partition is already defined. - device = PartitionDevice(extendedName, parents=disk) - device.parents = [disk] - device.partedPartition = extended - storage.createDevice(device) - -def clearPartitions(installer): - """ Clear partitions and dependent devices from disks. - - Arguments: - - storage -- a storage.Storage instance - - Keyword arguments: - - None - - NOTES: - - - Needs some error handling, especially for the parted bits. - - """ - storage = installer.ds.storage - - # we are only interested in partitions that physically exist - partitions = [p for p in storage.partitions if p.exists] - disks = [] # a list of disks from which we've removed partitions - clearparts = [] # list of partitions we'll remove - for part in partitions: - # if we got a list of disks to clear, make sure this one's on it - if storage.clearDisks and part.disk.name not in storage.clearDisks: - continue - - # don't clear partitions holding install media - #if part.name in storage.protectedPartitions: - # continue - - # we don't want to fool with extended partitions, freespace - if part.partType not in (parted.PARTITION_NORMAL, parted.PARTITION_LOGICAL): - continue - - # XXX is there any argument for not removing incomplete devices? - # -- maybe some RAID devices - devices = storage.deviceDeps(part) - while devices: - installer.log.debug("Devices to remove: %s" % ([d.name for d in devices],)) - leaves = [d for d in devices if d.isleaf] - installer.log.debug("Leaves to remove: %s" % ([d.name for d in leaves],)) - for leaf in leaves: - storage.destroyDevice(leaf) - devices.remove(leaf) - - #installer.log.debug("Partitions left: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions]) - disk_name = os.path.basename(part.partedPartition.disk.device.path) - if disk_name not in disks: - disks.append(disk_name) - - clearparts.append(part) - - for part in clearparts: - storage.destroyDevice(part) - - # now remove any empty extended partitions - removeEmptyExtendedPartitions(installer) - -def removeEmptyExtendedPartitions(installer): - storage = installer.ds.storage - for disk in storage.disks: - #installer.log.debug("Checking whether disk %s has an empty extended" % disk.name) - extended = disk.partedDisk.getExtendedPartition() - logical_parts = disk.partedDisk.getLogicalPartitions() - #installer.log.debug("Extended is %s ; logicals is %s" % (extended, [p.getDeviceNodeName() for p in logical_parts])) - if extended and not logical_parts: - installer.log.debug("Removing empty extended partition from %s" % disk.name) - extended_name = devicePathToName(extended.getDeviceNodeName()) - extended = storage.devicetree.getDeviceByName(extended_name) - storage.destroyDevice(extended) - #disk.partedDisk.removePartition(extended.partedPartition) - -def _createFreeSpacePartitions(installer): - # get a list of disks that have at least one free space region of at - # least 100MB - disks = [] - for disk in installer.ds.storage.disks: - if disk.name not in installer.ds.storage.clearDisks: - continue - - partedDisk = disk.partedDisk - part = disk.partedDisk.getFirstPartition() - while part: - if not part.type & parted.PARTITION_FREESPACE: - part = part.nextPartition() - continue - - if part.getSize(unit="MB") > 100: - disks.append(disk) - break - - part = part.nextPartition() - - # create a separate pv partition for each disk with free space - devs = [] - for disk in disks: - if installer.ds.storage.encryptedAutoPart: - fmt_type = "luks" - else: - fmt_type = "lvmpv" - part = installer.ds.storage.newPartition(fmt_type=fmt_type, - size=1, grow=True, - disks=[disk]) - installer.ds.storage.createDevice(part) - devs.append(part) - - return (disks, devs) - -def _schedulePartitions(installer, disks): - # - # Convert storage.autoPartitionRequests into Device instances and - # schedule them for creation - # - # First pass is for partitions only. We'll do LVs later. - # - for request in installer.ds.storage.autoPartitionRequests: - if request.asVol: - continue - - if request.fstype is None: - request.fstype = installer.ds.storage.defaultFSType - - dev = installer.ds.storage.newPartition(fmt_type=request.fstype, - size=request.size, - grow=request.grow, - maxsize=request.maxSize, - mountpoint=request.mountpoint, - disks=disks, - weight=request.weight) - - # schedule the device for creation - installer.ds.storage.createDevice(dev) - - # make sure preexisting broken lvm/raid configs get out of the way - return - -def allocatePartitions(installer, disks, partitions): - """ Allocate partitions based on requested features. - - Non-existing partitions are sorted according to their requested - attributes, and then allocated. - - The basic approach to sorting is that the more specifically- - defined a request is, the earlier it will be allocated. See - the function partitionCompare for details on the sorting - criteria. - - The PartitionDevice instances will have their name and parents - attributes set once they have been allocated. - """ - #installer.log.debug("disks=%s ; partitions=%s" % (disks, partitions)) - new_partitions = [p for p in partitions if not p.exists] - new_partitions.sort(cmp=partitionCompare) - - # XXX is this needed anymore? - partedDisks = {} - for disk in disks: - if disk.path not in partedDisks.keys(): - partedDisks[disk.path] = disk.partedDisk #.duplicate() - - # remove all newly added partitions from the disk - installer.log.debug("Removing all non-preexisting from disk(s)") - for _part in new_partitions: - if _part.partedPartition: - if _part.isExtended: - continue # these get removed last - #_part.disk.partedDisk.removePartition(_part.partedPartition) - partedDisk = partedDisks[_part.disk.partedDisk.device.path] - installer.log.debug("Removing part %s (%s) from disk %s (%s)" % - (_part.partedPartition.path, - [p.path for p in _part.partedPartition.disk.partitions], - partedDisk.device.path, - [p.path for p in partedDisk.partitions])) - - partedDisk.removePartition(_part.partedPartition) - _part.partedPartition = None - _part.disk = None - - # remove empty extended so it doesn't interfere - extended = partedDisk.getExtendedPartition() - if extended and not partedDisk.getLogicalPartitions(): - installer.log.debug("Removing empty extended partition") - #partedDisk.minimizeExtendedPartition() - partedDisk.removePartition(extended) - - for _part in new_partitions: - if _part.partedPartition and _part.isExtended: - # ignore new extendeds as they are implicit requests - continue - - # obtain the set of candidate disks - req_disks = [] - if _part.disk: - # we have a already selected a disk for this request - req_disks = [_part.disk] - elif _part.req_disks: - # use the requested disk set - req_disks = _part.req_disks - else: - # no disks specified means any disk will do - req_disks = disks - - #installer.log.debug("allocating partition: %s ; disks: %s ; boot: %s ; " - # "primary: %s ; size: %dMB ; grow: %s ; max_size: %s" % - # (_part.name, req_disks, _part.req_bootable, _part.req_primary, - # _part.req_size, _part.req_grow, _part.req_max_size)) - free = None - use_disk = None - part_type = None - # loop through disks - for _disk in req_disks: - disk = partedDisks[_disk.path] - #for p in disk.partitions: - # installer.log.debug("disk %s: part %s" % (disk.device.path, p.path)) - sectorSize = disk.device.physicalSectorSize - best = None - - #installer.log.debug("Checking freespace on %s" % _disk.name) - - new_part_type = getNextPartitionType(disk) - if new_part_type is None: - # can't allocate any more partitions on this disk - installer.log.debug("No free partition slots on %s" % _disk.name) - continue - - if _part.req_primary and new_part_type != parted.PARTITION_NORMAL: - # we need a primary slot and none are free on this disk - installer.log.debug("No primary slots available on %s" % _disk.name) - continue - - best = getBestFreeSpaceRegion(installer, disk, - new_part_type, - _part.req_size, - best_free=free, - boot=_part.req_bootable) - - if best == free and not _part.req_primary and \ - new_part_type == parted.PARTITION_NORMAL: - # see if we can do better with a logical partition - installer.log.debug("Not enough free space for primary -- trying logical") - new_part_type = getNextPartitionType(disk, no_primary=True) - if new_part_type: - best = getBestFreeSpaceRegion(disk, - new_part_type, - _part.req_size, - best_free=free, - boot=_part.req_bootable) - - if best and free != best: - # now we know we are choosing a new free space, - # so update the disk and part type - #installer.log.debug("Updating use_disk to %s (%s), type: %s" - # % (_disk, _disk.name, new_part_type)) - part_type = new_part_type - use_disk = _disk - installer.log.debug("New free: %s (%d-%d / %dMB)" % (best.device.path, - best.start, - best.end, - best.getSize())) - free = best - - if free and _part.req_bootable: - # if this is a bootable partition we want to - # use the first freespace region large enough - # to satisfy the request - installer.log.debug("Found free space for bootable request") - break - - if free is None: - raise PartitioningError("Not enough free space on disks") - - _disk = use_disk - disk = _disk.partedDisk - - # create the extended partition if needed - # TODO: move to a function (disk, free) - if part_type == parted.PARTITION_EXTENDED: - installer.log.debug("Creating extended partition") - geometry = parted.Geometry(device=disk.device, - start=free.start, - length=free.length, - end=free.end) - extended = parted.Partition(disk=disk, - type=parted.PARTITION_EXTENDED, - geometry=geometry) - constraint = parted.Constraint(device=disk.device) - # FIXME: we should add this to the tree as well - disk.addPartition(extended, constraint) - - # end proposed function - - # now the extended partition exists, so set type to logical - part_type = parted.PARTITION_LOGICAL - - # recalculate freespace - installer.log.debug("Recalculating free space") - free = getBestFreeSpaceRegion(disk, - part_type, - _part.req_size, - boot=_part.req_bootable) - if not free: - raise PartitioningError("Not enough free space after " - "creating extended partition") - - # create minimum geometry for this request - # req_size is in MB - sectors_per_track = disk.device.biosGeometry[2] - length = (_part.req_size * (1024 * 1024)) / sectorSize - new_geom = parted.Geometry(device=disk.device, - start=max(sectors_per_track, free.start), - length=length) - - # create maximum and minimum geometries for constraint - start = max(0 , free.start - 1) - max_geom = parted.Geometry(device=disk.device, - start=start, - length=min(length + 1, disk.device.length - start)) - min_geom = parted.Geometry(device=disk.device, - start=free.start + 1, - length=length-1) - - - # create the partition and add it to the disk - partition = parted.Partition(disk=disk, - type=part_type, - geometry=new_geom) - constraint = parted.Constraint(maxGeom=max_geom, minGeom=min_geom) - disk.addPartition(partition=partition, - constraint=constraint) - installer.log.debug("Created partition %s of %dMB and added it to %s" % - (partition.getDeviceNodeName(), partition.getSize(), disk.device.path)) - - # this one sets the name - _part.partedPartition = partition - _part.disk = _disk - - # parted modifies the partition in the process of adding it to - # the disk, so we need to grab the latest version... - _part.partedPartition = disk.getPartitionByPath(_part.path) - -def growPartitions(installer, disks, partitions): - """ Grow all growable partition requests. - - All requests should know what disk they will be on by the time - this function is called. This is reflected in the - PartitionDevice's disk attribute. Note that the req_disks - attribute remains unchanged. - - The total available free space is summed up for each disk and - partition requests are allocated a maximum percentage of the - available free space on their disk based on their own base size. - - Each attempted size means calling allocatePartitions again with - one request's size having changed. - - After taking into account several factors that may limit the - maximum size of a requested partition, we arrive at a firm - maximum number of sectors by which a request can potentially grow. - - An initial attempt is made to allocate the full maximum size. If - this fails, we begin a rough binary search with a maximum of three - iterations to settle on a new size. - - Arguments: - - disks -- a list of all usable disks (DiskDevice instances) - partitions -- a list of all partitions (PartitionDevice - instances) - """ - #installer.log.debug("growPartitions: disks=%s, partitions=%s" % - # ([d.name for d in disks], [p.name for p in partitions])) - all_growable = [p for p in partitions if p.req_grow] - if not all_growable: - return - - # sort requests by base size in decreasing order - all_growable.sort(key=lambda p: p.req_size, reverse=True) - - installer.log.debug("Growable requests are %s" % [p.name for p in all_growable]) - - for disk in disks: - installer.log.debug("Growing requests on %s" % disk.name) - for p in disk.partedDisk.partitions: - installer.log.debug(" %s: %s (%dMB)" % (disk.name, p.getDeviceNodeName(), - p.getSize())) - sectorSize = disk.partedDisk.device.physicalSectorSize - # get a list of free space regions on the disk - free = disk.partedDisk.getFreeSpaceRegions() - if not free: - installer.log.debug("No free space on %s" % disk.name) - continue - - # sort the free regions in decreasing order of size - free.sort(key=lambda r: r.length, reverse=True) - disk_free = reduce(lambda x,y: x + y, [f.length for f in free]) - installer.log.debug("Total free: %d sectors ; largest: %d sectors (%dMB)" - % (disk_free, free[0].length, free[0].getSize())) - - # make a list of partitions currently allocated on this disk - # -- they're already sorted - growable = [] - disk_total = 0 - for part in all_growable: - #log.debug("checking if part %s (%s) is on this disk" % (part.name, - # part.disk.name)) - if part.disk == disk: - growable.append(part) - disk_total += part.partedPartition.geometry.length - installer.log.debug("Add %s (%dMB/%d sectors) to growable total" - % (part.name, part.partedPartition.getSize(), - part.partedPartition.geometry.length)) - installer.log.debug("Growable total is now %d sectors" % disk_total) - - # now we loop through the partitions... - # this first loop is to identify obvious chunks of free space that - # will be left over due to max size - leftover = 0 - limited = {} - unlimited_total = 0 - for part in growable: - # calculate max number of sectors this request can grow - req_sectors = part.partedPartition.geometry.length - share = float(req_sectors) / float(disk_total) - max_grow = (share * disk_free) - max_sectors = req_sectors + max_grow - limited[part.name] = False - - if part.req_max_size: - req_max_sect = (part.req_max_size * (1024 * 1024)) / sectorSize - if req_max_sect < max_sectors: - mb = ((max_sectors - req_max_sect) * sectorSize) / (1024*1024) - - installer.log.debug("Adding %dMB to leftovers from %s" - % (mb, part.name)) - leftover += (max_sectors - req_max_sect) - limited[part.name] = True - - if not limited[part.name]: - unlimited_total += req_sectors - - # now we loop through the partitions... - for part in growable: - # calculate max number of sectors this request can grow - req_sectors = part.partedPartition.geometry.length - share = float(req_sectors) / float(disk_total) - max_grow = (share * disk_free) - if not limited[part.name]: - leftover_share = float(req_sectors) / float(unlimited_total) - max_grow += leftover_share * leftover - max_sectors = req_sectors + max_grow - max_mb = (max_sectors * sectorSize) / (1024 * 1024) - - installer.log.debug("%s: base_size=%dMB, max_size=%sMB" % - (part.name, part.req_base_size, part.req_max_size)) - installer.log.debug("%s: current_size=%dMB (%d sectors)" % - (part.name, part.partedPartition.getSize(), - part.partedPartition.geometry.length)) - installer.log.debug("%s: %dMB (%d sectors, or %d%% of %d)" % - (part.name, max_mb, max_sectors, share * 100, disk_free)) - - installer.log.debug("Checking constraints on max size...") - # don't grow beyond the request's maximum size - if part.req_max_size: - installer.log.debug("max_size: %dMB" % part.req_max_size) - # FIXME: round down to nearest cylinder boundary - req_max_sect = (part.req_max_size * (1024 * 1024)) / sectorSize - if req_max_sect < max_sectors: - max_grow -= (max_sectors - req_max_sect) - max_sectors = req_sectors + max_grow - - # don't grow beyond the resident filesystem's max size - if part.format.maxSize > 0: - installer.log.debug("Format maxsize: %dMB" % part.format.maxSize) - # FIXME: round down to nearest cylinder boundary - fs_max_sect = (part.format.maxSize * (1024 * 1024)) / sectorSize - if fs_max_sect < max_sectors: - max_grow -= (max_sectors - fs_max_sect) - max_sectors = req_sectors + max_grow - - # we can only grow as much as the largest free region on the disk - if free[0].length < max_grow: - installer.log.debug("Largest free region: %d sectors (%dMB)" % - (free[0].length, free[0].getSize())) - # FIXME: round down to nearest cylinder boundary - max_grow = free[0].length - max_sectors = req_sectors + max_grow - - # Now, we try to grow this partition as close to max_grow - # sectors as we can. - # - # We could call allocatePartitions after modifying this - # request and saving the original value of part.req_size, - # or we could try to use disk.maximizePartition(). - max_size = (max_sectors * sectorSize) / (1024 * 1024) - orig_size = part.req_size - # try the max size to begin with - installer.log.debug("Attempting to allocate maximum size: %dMB" % max_size) - part.req_size = max_size - try: - allocatePartitions(installer, disks, partitions) - except PartitioningError, e: - installer.log.debug("Max size attempt failed: %s (%dMB)" % (part.name, - max_size)) - part.req_size = orig_size - else: - continue - - installer.log.debug("Starting binary search: size=%d max_size=%d" % (part.req_size, max_size)) - count = 0 - op_func = add - increment = max_grow - last_good_size = part.req_size - last_outcome = None - while count < 3: - last_size = part.req_size - increment /= 2 - req_sectors = op_func(req_sectors, increment) - part.req_size = (req_sectors * sectorSize) / (1024 * 1024) - installer.log.debug("Attempting size=%dMB" % part.req_size) - count += 1 - try: - allocatePartitions(disks, partitions) - except PartitioningError, e: - installer.log.debug("Attempt at %dMB failed" % part.req_size) - op_func = sub - last_outcome = False - else: - op_func = add - last_good_size = part.req_size - last_outcome = True - - if not last_outcome: - part.req_size = last_good_size - installer.log.debug("Backing up to size=%dMB" % part.req_size) - try: - allocatePartitions(disks, partitions) - except PartitioningError, e: - raise PartitioningError("Failed to grow partitions") - - # reset all requests to their original requested size - for part in partitions: - if part.exists: - continue - part.req_size = part.req_base_size - -def growLVM(installer): - """ Grow LVs according to the sizes of the PVs. """ - storage = installer.ds.storage - for vg in storage.vgs: - total_free = vg.freeSpace - if not total_free: - installer.log.debug("vg %s has no free space" % vg.name) - continue - - installer.log.debug("vg %s: %dMB free ; lvs: %s" % (vg.name, vg.freeSpace, - [l.lvname for l in vg.lvs])) - - # figure out how much to grow each LV - grow_amounts = {} - lv_total = vg.size - total_free - installer.log.debug("used: %dMB ; vg.size: %dMB" % (lv_total, vg.size)) - - # This first loop is to calculate percentage-based growth - # amounts. These are based on total free space. - lvs = vg.lvs - lvs.sort(cmp=lvCompare) - for lv in lvs: - if not lv.req_grow or not lv.req_percent: - continue - - portion = (lv.req_percent * 0.01) - grow = portion * vg.vgFree - new_size = lv.req_size + grow - if lv.req_max_size and new_size > lv.req_max_size: - grow -= (new_size - lv.req_max_size) - - if lv.format.maxSize and lv.format.maxSize < new_size: - grow -= (new_size - lv.format.maxSize) - - # clamp growth amount to a multiple of vg extent size - grow_amounts[lv.name] = vg.align(grow) - total_free -= grow - lv_total += grow - - # This second loop is to calculate non-percentage-based growth - # amounts. These are based on free space remaining after - # calculating percentage-based growth amounts. - - # keep a tab on space not allocated due to format or requested - # maximums -- we'll dole it out to subsequent requests - leftover = 0 - for lv in lvs: - installer.log.debug("Checking lv %s: req_grow: %s ; req_percent: %s" - % (lv.name, lv.req_grow, lv.req_percent)) - if not lv.req_grow or lv.req_percent: - continue - - portion = float(lv.req_size) / float(lv_total) - grow = portion * total_free - installer.log.debug("grow is %dMB" % grow) - - todo = lvs[lvs.index(lv):] - unallocated = reduce(lambda x,y: x+y, - [l.req_size for l in todo - if l.req_grow and not l.req_percent]) - extra_portion = float(lv.req_size) / float(unallocated) - extra = extra_portion * leftover - installer.log.debug("%s getting %dMB (%d%%) of %dMB leftover space" - % (lv.name, extra, extra_portion * 100, leftover)) - leftover -= extra - grow += extra - installer.log.debug("grow is now %dMB" % grow) - max_size = lv.req_size + grow - if lv.req_max_size and max_size > lv.req_max_size: - max_size = lv.req_max_size - - if lv.format.maxSize and max_size > lv.format.maxSize: - max_size = lv.format.maxSize - - installer.log.debug("max size is %dMB" % max_size) - max_size = max_size - leftover += (lv.req_size + grow) - max_size - grow = max_size - lv.req_size - installer.log.debug("lv %s gets %dMB" % (lv.name, vg.align(grow))) - grow_amounts[lv.name] = vg.align(grow) - - if not grow_amounts: - installer.log.debug("No growable lvs in vg %s" % vg.name) - continue - - # now grow the lvs by the amounts we've calculated above - for lv in lvs: - if lv.name not in grow_amounts.keys(): - continue - lv.size += grow_amounts[lv.name] - - # now there shouldn't be any free space left, but if there is we - # should allocate it to one of the LVs - vg_free = vg.freeSpace - installer.log.debug("vg %s has %dMB free" % (vg.name, vg_free)) - if vg_free: - for lv in lvs: - if not lv.req_grow: - continue - - if lv.req_max_size and lv.size == lv.req_max_size: - continue - - if lv.format.maxSize and lv.size == lv.format.maxSize: - continue - - # first come, first served - projected = lv.size + vg.freeSpace - if lv.req_max_size and projected > lv.req_max_size: - projected = lv.req_max_size - - if lv.format.maxSize and projected > lv.format.maxSize: - projected = lv.format.maxSize - - installer.log.debug("Giving leftover %dMB to %s" % (projected - lv.size, - lv.name)) - lv.size = projected - -def partitionCompare(part1, part2): - """ More specifically defined partitions come first. - - < 1 => x < y - 0 => x == y - > 1 => x > y - """ - ret = 0 - - if part1.req_base_weight: - ret -= part1.req_base_weight - - if part2.req_base_weight: - ret += part2.req_base_weight - - # bootable partitions to the front - ret -= cmp(part1.req_bootable, part2.req_bootable) * 1000 - - # more specific disk specs to the front of the list - ret += cmp(len(part1.parents), len(part2.parents)) * 500 - - # primary-only to the front of the list - ret -= cmp(part1.req_primary, part2.req_primary) * 200 - - # larger requests go to the front of the list - ret -= cmp(part1.size, part2.size) * 100 - - # fixed size requests to the front - ret += cmp(part1.req_grow, part2.req_grow) * 50 - - # potentially larger growable requests go to the front - if part1.req_grow and part2.req_grow: - if not part1.req_max_size and part2.req_max_size: - ret -= 25 - elif part1.req_max_size and not part2.req_max_size: - ret += 25 - else: - ret -= cmp(part1.req_max_size, part2.req_max_size) * 25 - - if ret > 0: - ret = 1 - elif ret < 0: - ret = -1 - - return ret - -def lvCompare(lv1, lv2): - """ More specifically defined lvs come first. - - < 1 => x < y - 0 => x == y - > 1 => x > y - """ - ret = 0 - - # larger requests go to the front of the list - ret -= cmp(lv1.size, lv2.size) * 100 - - # fixed size requests to the front - ret += cmp(lv1.req_grow, lv2.req_grow) * 50 - - # potentially larger growable requests go to the front - if lv1.req_grow and lv2.req_grow: - if not lv1.req_max_size and lv2.req_max_size: - ret -= 25 - elif lv1.req_max_size and not lv2.req_max_size: - ret += 25 - else: - ret -= cmp(lv1.req_max_size, lv2.req_max_size) * 25 - - if ret > 0: - ret = 1 - elif ret < 0: - ret = -1 - - return ret - -def getNextPartitionType(disk, no_primary=None): - """ Find the type of partition to create next on a disk. - - Return a parted partition type value representing the type of the - next partition we will create on this disk. - - If there is only one free primary partition and we can create an - extended partition, we do that. - - If there are free primary slots and an extended partition we will - recommend creating a primary partition. This can be overridden - with the keyword argument no_primary. - - Arguments: - - disk -- a parted.Disk instance representing the disk - - Keyword arguments: - - no_primary -- given a choice between primary and logical - partitions, prefer logical - - """ - part_type = None - extended = disk.getExtendedPartition() - supports_extended = disk.supportsFeature(parted.DISK_TYPE_EXTENDED) - logical_count = len(disk.getLogicalPartitions()) - max_logicals = disk.getMaxLogicalPartitions() - primary_count = disk.primaryPartitionCount - - if primary_count == disk.maxPrimaryPartitionCount and \ - extended and logical_count < max_logicals: - part_type = parted.PARTITION_LOGICAL - elif primary_count == (disk.maxPrimaryPartitionCount - 1) and \ - not extended and supports_extended: - # last chance to create an extended partition - part_type = parted.PARTITION_EXTENDED - elif no_primary and extended and logical_count < max_logicals: - # create a logical even though we could presumably create a - # primary instead - part_type = parted.PARTITION_LOGICAL - elif not no_primary: - # XXX there is a possiblity that the only remaining free space on - # the disk lies within the extended partition, but we will - # try to create a primary first - part_type = parted.PARTITION_NORMAL - - return part_type - -def getBestFreeSpaceRegion(installer, disk, part_type, req_size, - boot=None, best_free=None): - """ Return the "best" free region on the specified disk. - - For non-boot partitions, we return the largest free region on the - disk. For boot partitions, we return the first region that is - large enough to hold the partition. - - Partition type (parted's PARTITION_NORMAL, PARTITION_LOGICAL) is - taken into account when locating a suitable free region. - - For locating the best region from among several disks, the keyword - argument best_free allows the specification of a current "best" - free region with which to compare the best from this disk. The - overall best region is returned. - - Arguments: - - disk -- the disk (a parted.Disk instance) - part_type -- the type of partition we want to allocate - (one of parted's partition type constants) - req_size -- the requested size of the partition (in MB) - - Keyword arguments: - - boot -- indicates whether this will be a bootable partition - (boolean) - best_free -- current best free region for this partition - - """ - #installer.log.debug("getBestFreeSpaceRegion: disk=%s part_type=%d req_size=%dMB boot=%s best=%s" % - # (disk.device.path, part_type, req_size, boot, best_free)) - extended = disk.getExtendedPartition() - for _range in disk.getFreeSpaceRegions(): - if extended: - # find out if there is any overlap between this region and the - # extended partition - installer.log.debug("Looking for intersection between extended (%d-%d) and free (%d-%d)" % - (extended.geometry.start, extended.geometry.end, _range.start, _range.end)) - - # parted.Geometry.overlapsWith can handle this - try: - free_geom = extended.geometry.intersect(_range) - except ArithmeticError, e: - # this freespace region does not lie within the extended - # partition's geometry - free_geom = None - - if (free_geom and part_type == parted.PARTITION_NORMAL) or \ - (not free_geom and part_type == parted.PARTITION_LOGICAL): - installer.log.debug("Free region not suitable for request") - continue - - if part_type == parted.PARTITION_NORMAL: - # we're allocating a primary and the region is not within - # the extended, so we use the original region - free_geom = _range - else: - free_geom = _range - - installer.log.debug("Current free range on %s is %d-%d (%dMB)" % (disk.device.path, - free_geom.start, - free_geom.end, - free_geom.getSize())) - free_size = free_geom.getSize() - - if req_size <= free_size: - if not best_free or free_geom.length > best_free.length: - best_free = free_geom - - if boot: - # if this is a bootable partition we want to - # use the first freespace region large enough - # to satisfy the request - break - - return best_free - -def _scheduleLVs(installer, devs): - if installer.ds.storage.encryptedAutoPart: - pvs = [] - for dev in devs: - pv = LUKSDevice("luks-%s" % dev.name, - format=getFormat("lvmpv", device=dev.path), - size=dev.size, - parents=dev) - pvs.append(pv) - installer.ds.storage.createDevice(pv) - else: - pvs = devs - - # create a vg containing all of the autopart pvs - vg = installer.ds.storage.newVG(pvs=pvs) - installer.ds.storage.createDevice(vg) - - # - # Convert storage.autoPartitionRequests into Device instances and - # schedule them for creation. - # - # Second pass, for LVs only. - for request in installer.ds.storage.autoPartitionRequests: - if not request.asVol: - continue - - if request.fstype is None: - request.fstype = installer.ds.storage.defaultFSType - - # FIXME: move this to a function and handle exceptions - dev = installer.ds.storage.newLV(vg=vg, - fmt_type=request.fstype, - mountpoint=request.mountpoint, - grow=request.grow, - maxsize=request.maxSize, - size=request.size) - - # schedule the device for creation - installer.ds.storage.createDevice(dev) diff --git a/pkgs/core/pomona/src/storage/udev.py b/pkgs/core/pomona/src/storage/udev.py deleted file mode 100644 index a9a73774e..000000000 --- a/pkgs/core/pomona/src/storage/udev.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/python - -import os -import sys - -import util - -def udev_settle(timeout=None): - argv = ["settle"] - if timeout: - argv.append("--timeout=%d" % int(timeout)) - - util.execWithRedirect("udevadm", argv, stderr="/dev/null", searchPath=1) - -def udev_trigger(subsystem=None): - argv = ["trigger"] - if subsystem: - argv.append("--subsystem-match=%s" % subsystem) - - util.execWithRedirect("udevadm", argv, stderr="/dev/null", searchPath=1) - -def udev_get_block_devices(): - #udev_settle(timeout=30) - entries = [] - for path in enumerate_block_devices(): - entry = udev_get_block_device(path) - if entry: - entries.append(entry) - return entries - -def __is_blacklisted_blockdev(dev_name): - """Is this a blockdev we never want for an install?""" - if dev_name.startswith("loop") or dev_name.startswith("ram") or dev_name.startswith("fd"): - return True - - if os.path.exists("/sys/class/block/%s/device/model" %(dev_name,)): - model = open("/sys/class/block/%s/device/model" %(dev_name,)).read() - for bad in ("IBM *STMF KERNEL", "SCEI Flash-5", "DGC LUNZ"): - if model.find(bad) != -1: - return True - - return False - -def enumerate_block_devices(): - top_dir = "/sys/class/block" - devices = [] - for dev_name in os.listdir(top_dir): - if __is_blacklisted_blockdev(dev_name): - continue - full_path = os.path.join(top_dir, dev_name) - link_ref = os.readlink(full_path) - real_path = os.path.join(top_dir, link_ref) - sysfs_path = os.path.normpath(real_path) - devices.append(sysfs_path) - return devices - -def udev_get_block_device(sysfs_path): - if not os.path.exists(sysfs_path): - return None - - db_entry = sysfs_path[4:].replace("/", "\\x2f") - db_root = "/dev/.udev/db" - db_path = os.path.normpath("%s/%s" % (db_root, db_entry)) - if not os.access(db_path, os.R_OK): - return None - - entry = open(db_path).read() - dev = udev_parse_block_entry(entry) - if dev: - # XXX why do we do this? is /sys going to move during installation? - dev['sysfs_path'] = sysfs_path[4:] # strip off the leading '/sys' - dev = udev_parse_uevent_file(dev) - - # now add in the contents of the uevent file since they're handy - return dev - -def udev_parse_uevent_file(dev): - path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path']) - if not os.access(path, os.R_OK): - return dev - - with open(path) as f: - for line in f.readlines(): - (key, equals, value) = line.strip().partition("=") - if not equals: - continue - dev[key] = value - - return dev - -def udev_parse_block_entry(buf): - dev = {'name': None, - 'symlinks': []} - - for line in buf.splitlines(): - line.strip() - (tag, sep, val) = line.partition(":") - if not sep: - continue - - if tag == "N": - dev['name'] = val - elif tag == "S": - dev['symlinks'].append(val) - elif tag == "E": - if val.count("=") > 1 and val.count(" ") > 0: - # eg: LVM2_LV_NAME when querying the VG for its LVs - vars = val.split() - vals = [] - var_name = None - for (index, subval) in enumerate(vars): - (var_name, sep, var_val) = subval.partition("=") - if sep: - vals.append(var_val) - - dev[var_name] = vals - else: - (var_name, sep, var_val) = val.partition("=") - if not sep: - continue - - if var_val.count(" "): - # eg: DEVLINKS - var_val = var_val.split() - - dev[var_name] = var_val - - if dev.get("name"): - return dev - -# These are functions for retrieving specific pieces of information from -# udev database entries. -def udev_device_get_name(udev_info): - """ Return the best name for a device based on the udev db data. """ - return udev_info.get("DM_NAME", udev_info["name"]) - -def udev_device_get_format(udev_info): - """ Return a device's format type as reported by udev. """ - return udev_info.get("ID_FS_TYPE") - -def udev_device_get_uuid(udev_info): - """ Get the UUID from the device's format as reported by udev. """ - md_uuid = udev_info.get("MD_UUID") - uuid = udev_info.get("ID_FS_UUID") - # we don't want to return the array's uuid as a member's uuid - if uuid and not md_uuid == uuid: - return udev_info.get("ID_FS_UUID") - -def udev_device_get_label(udev_info): - """ Get the label from the device's format as reported by udev. """ - return udev_info.get("ID_FS_LABEL") - -def udev_device_is_dm(info): - """ Return True if the device is a device-mapper device. """ - return info.has_key("DM_NAME") - -def udev_device_is_md(info): - """ Return True is the device is an mdraid array device. """ - return info.has_key("MD_METADATA") - -def udev_device_is_cdrom(info): - """ Return True if the device is an optical drive. """ - # FIXME: how can we differentiate USB drives from CD-ROM drives? - # -- USB drives also generate a sdX device. - return info.get("ID_CDROM") == "1" - -def udev_device_is_disk(info): - """ Return True is the device is a disk. """ - has_range = os.path.exists("/sys/%s/range" % info['sysfs_path']) - return info.get("DEVTYPE") == "disk" or has_range - -def udev_device_is_partition(info): - has_start = os.path.exists("/sys/%s/start" % info['sysfs_path']) - return info.get("DEVTYPE") == "partition" or has_start - -def udev_device_get_sysfs_path(info): - return info['sysfs_path'] - -def udev_device_get_major(info): - return int(info["MAJOR"]) - -def udev_device_get_minor(info): - return int(info["MINOR"]) - -def udev_device_get_md_level(info): - return info["MD_LEVEL"] - -def udev_device_get_md_devices(info): - return int(info["MD_DEVICES"]) - -def udev_device_get_md_uuid(info): - return info["MD_UUID"] - -def udev_device_get_vg_name(info): - return info['LVM2_VG_NAME'] - -def udev_device_get_vg_uuid(info): - return info['LVM2_VG_UUID'] - -def udev_device_get_vg_size(info): - # lvm's decmial precision is not configurable, so we tell it to use - # KB and convert to MB here - return float(info['LVM2_VG_SIZE']) / 1024 - -def udev_device_get_vg_free(info): - # lvm's decmial precision is not configurable, so we tell it to use - # KB and convert to MB here - return float(info['LVM2_VG_FREE']) / 1024 - -def udev_device_get_vg_extent_size(info): - # lvm's decmial precision is not configurable, so we tell it to use - # KB and convert to MB here - return float(info['LVM2_VG_EXTENT_SIZE']) / 1024 - -def udev_device_get_vg_extent_count(info): - return int(info['LVM2_VG_EXTENT_COUNT']) - -def udev_device_get_vg_free_extents(info): - return int(info['LVM2_VG_FREE_COUNT']) - -def udev_device_get_vg_pv_count(info): - return int(info['LVM2_PV_COUNT']) - -def udev_device_get_pv_pe_start(info): - # lvm's decmial precision is not configurable, so we tell it to use - # KB and convert to MB here - return float(info['LVM2_PE_START']) / 1024 - -def udev_device_get_lv_names(info): - names = info['LVM2_LV_NAME'] - if not names: - names = [] - elif not isinstance(names, list): - names = [names] - return names - -def udev_device_get_lv_uuids(info): - uuids = info['LVM2_LV_UUID'] - if not uuids: - uuids = [] - elif not isinstance(uuids, list): - uuids = [uuids] - return uuids - -def udev_device_get_lv_sizes(info): - # lvm's decmial precision is not configurable, so we tell it to use - # KB and convert to MB here - sizes = info['LVM2_LV_SIZE'] - if not sizes: - sizes = [] - elif not isinstance(sizes, list): - sizes = [sizes] - - return [float(s) / 1024 for s in sizes] - -def udev_device_is_dmraid(info): - # Note that this function does *not* identify raid sets. - # Tests to see if device is parto of a dmraid set. - # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a - # string that describes the type of dmraid (isw_raid_member...), I don't - # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so - # dmraid will be everything that is raid and not linux_raid_member - #from formats.dmraid import DMRaidMember - #if info.has_key("ID_FS_TYPE") and \ - # info["ID_FS_TYPE"] in DMRaidMember._udevTypes: - # return True - # - return False - -def udev_device_get_dmraid_partition_disk(info): - try: - p_index = info["DM_NAME"].rindex("p") - except (KeyError, AttributeError, ValueError): - return None - - if not info["DM_NAME"][p_index+1:].isdigit(): - return None - - return info["DM_NAME"][:p_index] - -def udev_device_is_dmraid_partition(info, devicetree): - #diskname = udev_device_get_dmraid_partition_disk(info) - #dmraid_devices = devicetree.getDevicesByType("dm-raid array") - # - #for device in dmraid_devices: - # if diskname == device.name: - # return True - # - return False - -if __name__ == "__main__": - for device in udev_get_block_devices(): - print udev_device_get_name(device) - print " Label :", udev_device_get_label(device) - print " UUID :", udev_device_get_uuid(device) - print " Format :", udev_device_get_format(device) - print " Is disk :", udev_device_is_disk(device) - print " Is cdrom:", udev_device_is_cdrom(device) - print " Is part :", udev_device_is_partition(device) - print " Is dm :", udev_device_is_dm(device) - print " Is md :", udev_device_is_md(device) - #syspath = "/sys" + udev_device_get_sysfs_path(device) - #for (key, value) in udev_get_block_device(syspath).items(): - # print " (%s : %s)" % (key, value,) - print diff --git a/pkgs/core/pomona/src/text.py b/pkgs/core/pomona/src/text.py deleted file mode 100644 index 271931116..000000000 --- a/pkgs/core/pomona/src/text.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python - -import string - -from snack import * -from constants import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -class TextWindow: - def __init__(self, screen): - self.screen = screen - - def pop(self): - self.screen.popWindow() - self.screen.refresh() - - def refresh(self): - self.screen.refresh() - - -class WaitWindow(TextWindow): - def setText(self, text): - self.t.setText(text) - self.g.draw() - self.screen.refresh() - - def __init__(self, screen, title, text, width): - TextWindow.__init__(self, screen) - - if width is None: - width = 40 - if (len(text) < width): - width = len(text) - - self.t = TextboxReflowed(width, text) - - self.g = GridForm(self.screen, title, 1, 1) - self.g.add(self.t, 0, 0) - self.g.draw() - self.screen.refresh() - - -class OkCancelWindow: - def getrc(self): - return self.rc - - def __init__(self, screen, title, text): - rc = ButtonChoiceWindow(screen, title, text, buttons=[TEXT_OK_BUTTON, _("Cancel")]) - if rc == string.lower(_("Cancel")): - self.rc = 1 - else: - self.rc = 0 - - -class ExceptionWindow(TextWindow): - def __init__ (self, short, long=None, screen=None): - TextWindow.__init__(self, screen) - self.text = "%s\n\n" % short - self.buttons=[TEXT_OK_BUTTON] - - def run(self): - self.rc = ButtonChoiceWindow(self.screen, _("Exception Occurred"), - self.text, self.buttons, width=60) - - def getrc(self): - return 0 - - -class TextInterface: - def __init__(self, log): - self.log = log - self.screen = SnackScreen() - - self.setRootline(SCREEN_ROOTLINE) - self.setHelpline(SCREEN_HELPLINE) - - def __del__(self): - if self.screen: - self.screen.finish() - - def setRootline(self, msg): - self.screen.drawRootText (0, 0, string.center(msg, self.screen.width)) - self.log.debug("Set rootline text: %s" % msg) - - def setHelpline(self, msg): - self.screen.pushHelpLine(string.center(msg, self.screen.width)) - self.log.debug("Set helpline text: %s" % msg) - - - ### WINDOW DEFINITIONS ### - - def waitWindow(self, title, text, width=None): - return WaitWindow(self.screen, title, text, width) - - def exceptionWindow(self, short, long): - self.log.critical(short) - return ExceptionWindow(short, long, self.screen) - - def messageWindow(self, title, text, type="ok", default = None, - custom_icon=None, custom_buttons=[]): - if type == "ok": - ButtonChoiceWindow(self.screen, title, text, buttons=[TEXT_OK_BUTTON]) - - elif type == "yesno": - if default and default == "no": - btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON] - else: - btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON] - rc = ButtonChoiceWindow(self.screen, title, text, buttons=btnlist) - if rc == "yes": - return 1 - else: - return 0 - - elif type == "custom": - tmpbut = [] - for but in custom_buttons: - tmpbut.append(string.replace(but,"_","")) - rc = ButtonChoiceWindow(self.screen, title, text, width=60, buttons=tmpbut) - - idx = 0 - for b in tmpbut: - if string.lower(b) == rc: - return idx - idx = idx + 1 - return 0 - - else: - return OkCancelWindow(self.screen, title, text) diff --git a/pkgs/core/pomona/src/util.py b/pkgs/core/pomona/src/util.py deleted file mode 100644 index e9afb4d8b..000000000 --- a/pkgs/core/pomona/src/util.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/python - -import os -import stat - -from pyfire.executil import * - -def getArch(): - return "i386" - -def notify_kernel(path, action="change"): - """ Signal the kernel that the specified device has changed. """ - path = os.path.join(path, "uevent") - if not path.startswith("/sys/") or not os.access(path, os.W_OK): - raise ValueError("invalid sysfs path") - f = open(path, "a") - f.write("%s\n" % action) - f.close() - -def numeric_type(num): - """ Verify that a value is given as a numeric data type. - - Return the number if the type is sensible or raise ValueError - if not. - """ - if num is None: - num = 0 - elif not (isinstance(num, int) or \ - isinstance(num, long) or \ - isinstance(num, float)): - raise ValueError("value (%s) must be either a number or None" % num) - - return num - -## Create a directory path. Don't fail if the directory already exists. -# @param dir The directory path to create. -def mkdirChain(dir): - try: - os.makedirs(dir, 0755) - except OSError, (errno, msg): - try: - if errno == EEXIST and stat.S_ISDIR(os.stat(dir).st_mode): - return - except: - pass diff --git a/pkgs/core/pomona/src/windows.py b/pkgs/core/pomona/src/windows.py deleted file mode 100644 index 5fbc81955..000000000 --- a/pkgs/core/pomona/src/windows.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/python - -import sys - -from snack import * -from constants import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -def welcomeWindow(installer): - rc = installer.intf.messageWindow(_("%s") % PRODUCT_NAME, - _("Welcome to %s-v%s!\n\n") % (PRODUCT_NAME, PRODUCT_VERSION,)) - return DISPATCH_FORWARD - -def experimentalWindow(installer): - if installer.dispatch.dir == DISPATCH_BACK: - return DISPATCH_NOOP - - # Check if we are running a pre-release version - version = PRODUCT_VERSION - if not version.find("alpha") and \ - not version.find("beta") and \ - not version.find("rc"): - return DISPATCH_NOOP - - while 1: - rc = installer.intf.messageWindow( _("Warning! This is pre-release software!"), - _("Thank you for downloading this " - "pre-release of %s.\n\n" - "This is not a final " - "release and is not intended for use " - "on production systems. The purpose of " - "this release is to collect feedback " - "from testers, and it is not suitable " - "for day to day usage.\n\n" - "To report feedback, please visit:\n\n" - " %s\n\n" - "and file a report.\n") - % (PRODUCT_NAME, PRODUCT_URL), - type="custom", custom_buttons=[_("_Exit"), _("_Install anyway")]) - - if not rc: - rc = installer.intf.messageWindow(_("Rebooting System"), - _("Your system will now be rebooted..."), - type="custom", custom_buttons=[_("_Back"), _("_Reboot")]) - if rc: - sys.exit(0) - else: - break - -def finishedWindow(installer): - installer.intf.setHelpline(_("Press to exit")) - - rc = installer.intf.messageWindow(_("Complete"), - _("Congratulations, your %s installation is " - "complete.\n\n" - "Press to end the installation process.\n\n" - "For information on errata (updates and bug fixes), visit " - "%s.\n\n") % (PRODUCT_NAME, PRODUCT_URL,), - type="custom", custom_buttons=[_("Reboot")]) - - return INSTALL_OK - -def partmethodWindow(installer): - storage = installer.ds.storage - - if storage.checkNoDisks(): - sys.exit(0) - - # Resetting options - storage.doAutoPart = False -# installer.dispatch.skipStep("partition", skip=0) - - methods = [ _("Automatic partitioning"), _("Custom partitioning"),] - default = methods[0] # first should be autopartitioning - - (button, choice) = ListboxChoiceWindow(installer.intf.screen, - _("Partition Method"), - _("Installation requires partitioning of your hard drive. " - "The default option is suitable for most users. " - "You can also choose to create your own custom layout."), - methods, buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], - width = 60, default=default, height = len(methods)) - - if button == TEXT_BACK_CHECK: - return INSTALL_BACK - - if choice == 0: - installer.ds.storage.doAutoPart = True - #installer.dispatch.skipStep("partition", skip=1) - - installer.log.info("User has chosen \"%s\"" % methods[choice]) - - return INSTALL_OK - -def autopartitionWindow(installer): - storage = installer.ds.storage - while 1: - g = GridForm(installer.intf.screen, _("Device Selection"), 1, 6) - txt = TextboxReflowed(65, _("Which drive(s) do you want to use for this installation?\n\n" - "ALL DATA stored on the devices will be destroyed.")) - g.add(txt, 0, 0, (0, 0, 0, 0)) - - drivelist = CheckboxTree(height=4, scroll=1) - g.add(drivelist, 0, 4, (0, 1, 0, 0)) - - bb = ButtonBar(installer.intf.screen, [ TEXT_OK_BUTTON, TEXT_BACK_BUTTON ]) - g.add(bb, 0, 5, (0,1,0,0)) - - for disk in storage.disks: - if not storage.clearDisks or len(storage.clearDisks) < 1: - selected = 1 - else: - if disk in storage.clearDisks: # XXX never matches... - selected = 1 - else: - selected = 0 - - diskdesc = "%6s %8.0f MB (%s)" % (disk.name, disk.size, disk.model[:24],) - - drivelist.append(diskdesc, selected = selected) - - rc = g.run() - - installer.intf.screen.popWindow() - - if bb.buttonPressed(rc) == TEXT_BACK_CHECK: - return INSTALL_BACK - - if len(drivelist.getSelection()) > 0: - storage.clearDisks = map(lambda s: s.split()[0], drivelist.getSelection()) - else: - storage.clearDisks = [] - installer.intf.messageWindow(_("No Drives Selected"), - _("An error has occurred - no valid devices were " - "selected on which to create the new file system. " - "For the installation of %s, " - "you have to select at least one drive.") % PRODUCT_NAME, - type="ok") - - continue - - installer.log.info("User selected \"%s\"" % storage.clearDisks) - break - - return INSTALL_OK - -def reviewlayoutWindow(installer): - if installer.dispatch.dir == DISPATCH_BACK: - return DISPATCH_NOOP - - rc = installer.intf.messageWindow(_("Review Partition Layout"), - _("Review and modify partitioning layout?"), - type = "yesno") - if rc != 1: - #installer.dispatch.skipStep("partition", skip=1) - pass - - return INSTALL_OK - -def bootloaderWindow(installer): - bootloaders = [ _("Use Grand unified bootloader"), _("Install no bootloader"),] - default = bootloaders[0] # first should a bootloader - - (button, choice) = ListboxChoiceWindow(installer.intf.screen, - _("Bootloader"), - _("Which bootloader do you want to install?\n\n" - "NOTE: If you don't choose a bootloader the system " - "might not be bootable!"), - bootloaders, buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], - width = 60, default=default, height = len(bootloaders)) - - if button == TEXT_BACK_CHECK: - return INSTALL_BACK - - installer.log.info("User has chosen \"%s\"" % bootloaders[choice]) - # XXX skip step installbootloader here - - return INSTALL_OK