This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 3.x development tree".
The branch, master has been updated via eb3ed8cc26b7c49deffe18e37bb5ab50ce8b568a (commit) via 9ede014f870957202a1eb3bd686b93e197c8d378 (commit) via e3df4e6669058446c21756605ba8f171ffa17abd (commit) via 619a97539e25a74d2805c865f2bdd8277f468dbd (commit) via 6021e4c067378a8e36e0d41422aa5631dfa97b4b (commit) via de4798da12159f6260b063dc62bc35372dc5d214 (commit) via 3cd9c6fe9b223f1bffd60aab5af557069a281292 (commit) via 943e97c2ae7ef56f54f0f66a3b2f69d4fd69212f (commit) via 626726a4694862325176d8037bbf94f513f6c319 (commit) via 518a2e480f8bd5c78d56c247b1d02f20819c066e (commit) via e438028cc02a3b46032f3cc02e738a5d20ca1dc6 (commit) via a6da9ed587e7ca95a222882f8f393ebc7c331c79 (commit) via b8fa92505c569a8e2000c6282e4c5c29bc9a34b2 (commit) via c4d64061c8f30d22e25aededffead67d74764cfd (commit) via 5b2e3ecb89ce111ed962097e47cd58eddff10f23 (commit) via 5f532b07fd39b5ca455da7f394c0941ebba2496e (commit) via d31938469658e280b163406b57fa9d79985f02cc (commit) via f54dfeacb4aff9c425ad1f68497d3613a9ccd0c6 (commit) via 1f39708dbd0e7a6cf9918efa44b4238ee858e7c3 (commit) from d52f669049883f3e85df5168f50ff59cd86d444c (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit eb3ed8cc26b7c49deffe18e37bb5ab50ce8b568a Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Sep 16 00:16:01 2010 +0200
xorg-x11-xinit: Fix build dependencies.
commit 9ede014f870957202a1eb3bd686b93e197c8d378 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Sep 16 00:15:38 2010 +0200
xorg-x11-fonts: Fix build dependencies.
commit e3df4e6669058446c21756605ba8f171ffa17abd Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 23:43:29 2010 +0200
naoki: Add feature to find weak symbols.
Closes #71.
commit 619a97539e25a74d2805c865f2bdd8277f468dbd Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 22:22:32 2010 +0200
naoki: Remove toolchain version from naoki.conf.
commit 6021e4c067378a8e36e0d41422aa5631dfa97b4b Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 22:20:48 2010 +0200
naoki: Fix feature to ignore dependency resolution errors on command line.
commit de4798da12159f6260b063dc62bc35372dc5d214 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 19:40:18 2010 +0200
python-pyaspects: Convert to new package format.
commit 3cd9c6fe9b223f1bffd60aab5af557069a281292 Merge: 943e97c a6da9ed Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 19:38:16 2010 +0200
Merge remote branch 'ms/installer' into next
commit 943e97c2ae7ef56f54f0f66a3b2f69d4fd69212f Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 19:33:40 2010 +0200
naoki: Package man pages of "type" 2 and 3 to development packages.
commit 626726a4694862325176d8037bbf94f513f6c319 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 19:31:42 2010 +0200
naoki: Add support for a unique package id.
commit 518a2e480f8bd5c78d56c247b1d02f20819c066e Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Sep 15 00:35:42 2010 +0200
naoki: Improve sorting and choosing of packages.
Add PKG_EPOCH which overseeds the version and release informations.
commit e438028cc02a3b46032f3cc02e738a5d20ca1dc6 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Sep 14 23:24:25 2010 +0200
naoki: Cleanup pkgs/Constants.
commit a6da9ed587e7ca95a222882f8f393ebc7c331c79 Merge: b8fa925 e86c7a1 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Aug 26 11:17:31 2010 +0200
Merge commit 'stevee/x-fixes' into installer
commit b8fa92505c569a8e2000c6282e4c5c29bc9a34b2 Merge: 5f532b0 c4d6406 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Aug 26 11:16:27 2010 +0200
Merge branch 'X' into installer
commit c4d64061c8f30d22e25aededffead67d74764cfd Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Aug 26 11:16:00 2010 +0200
kernel: Enable EDD.
commit 5b2e3ecb89ce111ed962097e47cd58eddff10f23 Merge: 86dabf4 aebdc8e Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Aug 25 17:15:24 2010 +0200
Merge commit 'stevee/x-server' into X
commit 5f532b07fd39b5ca455da7f394c0941ebba2496e Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Aug 25 12:56:31 2010 +0200
Remove the old pomona installer.
commit d31938469658e280b163406b57fa9d79985f02cc Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Aug 25 12:52:45 2010 +0200
python-pyaspects: Renamed 'pyaspects' to its correct name.
commit f54dfeacb4aff9c425ad1f68497d3613a9ccd0c6 Merge: 86dabf4 1f39708 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Aug 25 12:47:48 2010 +0200
Merge commit 'stevee/pyaspects' into installer
commit 1f39708dbd0e7a6cf9918efa44b4238ee858e7c3 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Aug 24 19:48:37 2010 +0200
pyaspects: New package.
-----------------------------------------------------------------------
Summary of changes: config/naoki.conf | 6 - naoki/__init__.py | 2 +- naoki/build.py | 6 +- naoki/dependencies.py | 5 + naoki/environ.py | 8 +- naoki/packages.py | 50 +- pkgs/Constants | 164 +- pkgs/Functions | 3 + pkgs/Templates | 2 + pkgs/core/kernel/config | 10 +- pkgs/core/pomona/pomona.nm | 64 - pkgs/core/pomona/src/Makefile | 51 - pkgs/core/pomona/src/Makefile.inc | 31 - pkgs/core/pomona/src/console.py | 17 - pkgs/core/pomona/src/constants.py | 60 - pkgs/core/pomona/src/datastore.py | 13 - pkgs/core/pomona/src/dispatch.py | 56 - pkgs/core/pomona/src/exception.py | 151 -- pkgs/core/pomona/src/isys/Makefile | 51 - pkgs/core/pomona/src/isys/isys.c | 62 - pkgs/core/pomona/src/isys/isys.h | 5 - pkgs/core/pomona/src/isys/isys.py | 79 - pkgs/core/pomona/src/isys/mount.c | 186 -- pkgs/core/pomona/src/isys/mount.h | 13 - pkgs/core/pomona/src/keyboard.py | 131 -- pkgs/core/pomona/src/lang-table | 3 - pkgs/core/pomona/src/language.py | 109 - pkgs/core/pomona/src/log.py | 45 - pkgs/core/pomona/src/partition.py | 394 ---- pkgs/core/pomona/src/po/Makefile | 58 - pkgs/core/pomona/src/po/da.po | 2422 -------------------- pkgs/core/pomona/src/po/de.po | 2177 ------------------ pkgs/core/pomona/src/po/pomona.pot | 2161 ----------------- pkgs/core/pomona/src/pomona | 54 - pkgs/core/pomona/src/pomona.py | 113 - pkgs/core/pomona/src/pychecker-false-positives | 7 - pkgs/core/pomona/src/runpychecker.sh | 61 - pkgs/core/pomona/src/storage/__init__.py | 1176 ---------- pkgs/core/pomona/src/storage/deviceaction.py | 352 --- pkgs/core/pomona/src/storage/devicelibs/crypto.py | 109 - pkgs/core/pomona/src/storage/devicelibs/lvm.py | 115 - pkgs/core/pomona/src/storage/devicelibs/swap.py | 85 - pkgs/core/pomona/src/storage/devices.py | 1698 -------------- pkgs/core/pomona/src/storage/devicetree.py | 536 ----- pkgs/core/pomona/src/storage/errors.py | 107 - pkgs/core/pomona/src/storage/formats/__init__.py | 318 --- pkgs/core/pomona/src/storage/formats/fs.py | 929 -------- pkgs/core/pomona/src/storage/formats/luks.py | 187 -- pkgs/core/pomona/src/storage/formats/lvmpv.py | 85 - pkgs/core/pomona/src/storage/formats/swap.py | 112 - pkgs/core/pomona/src/storage/partitioning.py | 1059 --------- pkgs/core/pomona/src/storage/udev.py | 305 --- pkgs/core/pomona/src/text.py | 131 -- pkgs/core/pomona/src/util.py | 45 - pkgs/core/pomona/src/windows.py | 180 -- .../python-pyaspects.nm} | 17 +- pkgs/core/xorg-x11-fonts/xorg-x11-fonts.nm | 2 +- pkgs/core/xorg-x11-xinit/xorg-x11-xinit.nm | 3 +- tools/functions-packager-find | 44 + tools/packager | 4 +- 60 files changed, 244 insertions(+), 16185 deletions(-) delete mode 100644 pkgs/core/pomona/pomona.nm delete mode 100644 pkgs/core/pomona/src/Makefile delete mode 100644 pkgs/core/pomona/src/Makefile.inc delete mode 100644 pkgs/core/pomona/src/console.py delete mode 100644 pkgs/core/pomona/src/constants.py delete mode 100644 pkgs/core/pomona/src/datastore.py delete mode 100644 pkgs/core/pomona/src/dispatch.py delete mode 100644 pkgs/core/pomona/src/exception.py delete mode 100644 pkgs/core/pomona/src/isys/Makefile delete mode 100644 pkgs/core/pomona/src/isys/isys.c delete mode 100644 pkgs/core/pomona/src/isys/isys.h delete mode 100644 pkgs/core/pomona/src/isys/isys.py delete mode 100644 pkgs/core/pomona/src/isys/mount.c delete mode 100644 pkgs/core/pomona/src/isys/mount.h delete mode 100644 pkgs/core/pomona/src/keyboard.py delete mode 100644 pkgs/core/pomona/src/lang-table delete mode 100644 pkgs/core/pomona/src/language.py delete mode 100644 pkgs/core/pomona/src/log.py delete mode 100644 pkgs/core/pomona/src/partition.py delete mode 100644 pkgs/core/pomona/src/po/Makefile delete mode 100644 pkgs/core/pomona/src/po/da.po delete mode 100644 pkgs/core/pomona/src/po/de.po delete mode 100644 pkgs/core/pomona/src/po/pomona.pot delete mode 100644 pkgs/core/pomona/src/pomona delete mode 100644 pkgs/core/pomona/src/pomona.py delete mode 100644 pkgs/core/pomona/src/pychecker-false-positives delete mode 100755 pkgs/core/pomona/src/runpychecker.sh delete mode 100644 pkgs/core/pomona/src/storage/__init__.py delete mode 100644 pkgs/core/pomona/src/storage/deviceaction.py delete mode 100644 pkgs/core/pomona/src/storage/devicelibs/__init__.py delete mode 100644 pkgs/core/pomona/src/storage/devicelibs/crypto.py delete mode 100644 pkgs/core/pomona/src/storage/devicelibs/lvm.py delete mode 100644 pkgs/core/pomona/src/storage/devicelibs/swap.py delete mode 100644 pkgs/core/pomona/src/storage/devices.py delete mode 100644 pkgs/core/pomona/src/storage/devicetree.py delete mode 100644 pkgs/core/pomona/src/storage/errors.py delete mode 100644 pkgs/core/pomona/src/storage/formats/__init__.py delete mode 100644 pkgs/core/pomona/src/storage/formats/fs.py delete mode 100644 pkgs/core/pomona/src/storage/formats/luks.py delete mode 100644 pkgs/core/pomona/src/storage/formats/lvmpv.py delete mode 100644 pkgs/core/pomona/src/storage/formats/swap.py delete mode 100644 pkgs/core/pomona/src/storage/partitioning.py delete mode 100644 pkgs/core/pomona/src/storage/udev.py delete mode 100644 pkgs/core/pomona/src/text.py delete mode 100644 pkgs/core/pomona/src/util.py delete mode 100644 pkgs/core/pomona/src/windows.py copy pkgs/core/{pychecker/pychecker.nm => python-pyaspects/python-pyaspects.nm} (84%)
Difference in files: diff --git a/config/naoki.conf b/config/naoki.conf index 274dc91..822a4ae 100644 --- a/config/naoki.conf +++ b/config/naoki.conf @@ -21,12 +21,6 @@ version = %(epoch)s.0-prealpha2 slogan = "Gluttony"
-[toolchain] - -; Counter of toolchain version -version = 6 - - [sources]
; Where do we get the tarballs from? diff --git a/naoki/__init__.py b/naoki/__init__.py index a70a057..7ffff0b 100644 --- a/naoki/__init__.py +++ b/naoki/__init__.py @@ -75,7 +75,7 @@ class Naoki(object): if not p: raise Exception, "Could not find package: %s" % name
- p = build.Build(p) + p = build.Build(p, ignore_dependency_errors=args.ignore_dependency_errors) jobs.add(p)
#return builder.run(ignore_dependency_errors=args.ignore_dependency_errors) diff --git a/naoki/build.py b/naoki/build.py index befab33..9bc7d92 100644 --- a/naoki/build.py +++ b/naoki/build.py @@ -11,7 +11,7 @@ from exception import *
class Build(object): - def __init__(self, package): + def __init__(self, package, **kwargs): self.package = package
# Generate a random, but unique id @@ -30,6 +30,8 @@ class Build(object): "ignore_dependency_errors" : False, }
+ self.settings.update(kwargs) + def __repr__(self): return "<%s %s-%s:%s>" % \ (self.__class__.__name__, self.id, self.package.name, self.arch.name) @@ -58,7 +60,7 @@ class Build(object): else: raise
- e = environ.Build(self.package) + e = environ.Build(self.package, build_id="%s" % self.id)
# Extract all tools for package in self.dependency_set.packages: diff --git a/naoki/dependencies.py b/naoki/dependencies.py index 7f21b22..f5dd46b 100644 --- a/naoki/dependencies.py +++ b/naoki/dependencies.py @@ -93,6 +93,11 @@ class DependencySet(object): if item in self._items: return
+ # Packages conflict + if item.name in [i.name for i in self._items]: + logging.debug("Cannot add package with same name but different version: %s" % item) + return + for provides in item.get_provides(): self.add_provides(provides)
diff --git a/naoki/environ.py b/naoki/environ.py index fd14efc..ee5fc62 100644 --- a/naoki/environ.py +++ b/naoki/environ.py @@ -267,8 +267,9 @@ class _Environment(object):
class Build(_Environment): - def __init__(self, package): + def __init__(self, package, build_id=None): self.package = package + self.build_id = build_id
_Environment.__init__(self, self.package.arch)
@@ -288,7 +289,10 @@ class Build(_Environment):
def variables(self): v = _Environment.variables(self) - v.update({ "BUILDROOT" : "/%s" % self.buildroot }) + v.update({ + "BUILDROOT" : "/%s" % self.buildroot, + "BUILD_ID" : self.build_id or "", + }) return v
def build(self, *args, **kwargs): diff --git a/naoki/packages.py b/naoki/packages.py index 3b09e90..51b3253 100644 --- a/naoki/packages.py +++ b/naoki/packages.py @@ -15,6 +15,27 @@ import util
from constants import *
+def version_compare_epoch(e1, e2): + return cmp(e1, e2) + +def version_compare_version(v1, v2): + return cmp(v1, v2) + +def version_compare_release(r1, r2): + return cmp(r1, r2) + +def version_compare((e1, v1, r1), (e2, v2, r2)): + + ret = version_compare_epoch(e1, e2) + if not ret == 0: + return ret + + ret = version_compare_version(v1, v2) + if not ret == 0: + return ret + + return version_compare_release(r1, r2) +
class Package(object): def __repr__(self): @@ -26,6 +47,10 @@ class Package(object): # raise NotImplementedError
@property + def epoch(self): + return int(self._info.get("PKG_EPOCH", 0)) + + @property def name(self): return self._info["PKG_NAME"]
@@ -140,11 +165,30 @@ class BinaryPackage(Package): logging.debug("Successfully initialized %s" % self)
def __repr__(self): - return "<%s %s-%s-%s>" % \ - (self.__class__.__name__, self.name, self.version, self.release) + return "<%s %s:%s-%s-%s>" % \ + (self.__class__.__name__, self.epoch, self.name, self.version, + self.release)
def __cmp__(self, other): - return cmp(self.id, other.id) + # Packages are equal + if self.id == other.id: + return 0 + + # if packages differ names return in alphabetical order + if not self.name == other.name: + return cmp(self.name, other.name) + + ret = version_compare((self.epoch, self.version, self.release), + (other.epoch, other.version, other.release)) + + if ret == 0: + logging.debug("%s is equal to %s" % (self, other)) + elif ret < 0: + logging.debug("%s is more recent than %s" % (other, self)) + elif ret > 0: + logging.debug("%s is more recent than %s" % (self, other)) + + return ret
def _readfile(self, name): f = io.CpioArchive(self.filename) diff --git a/pkgs/Constants b/pkgs/Constants index 7cdb680..8f5c980 100644 --- a/pkgs/Constants +++ b/pkgs/Constants @@ -5,80 +5,142 @@ # ###############################################################################
-PKG_VARIABLES = PKG_BUILD_DEPS PKG_DEPS PKG_DESCRIPTION PKG_FILES PKG_GROUP \ - PKG_MAINTAINER PKG_LICENSE PKG_PROVIDES PKG_REL PKG_SUMMARY PKG_URL \ - PKG_VER - +# If we are running in a chroot, we map all directories to $(BASEDIR), otherwise +# BASEDIR will be the absolute path (for gathering information from the source +# packages) ifeq "$(CHROOT)" "1" BASEDIR = /usr/src endif
-THISAPP = $(PKG_NAME)-$(PKG_VER) - -DIR_APP = $(DIR_SRC)/$(THISAPP) -DIR_DL = $(BASEDIR)/cache -DIR_PATCHES = $(DIR_SOURCE)/patches -DIR_SRC = $(ROOT)/usr/src -DIR_TMP = /tmp -DIR_SOURCE = $(CURDIR) +# Set default directories +DIR_APP = $(DIR_SRC)/$(THISAPP) +DIR_DL = $(BASEDIR)/cache DIR_PACKAGES = /usr/src/packages/$(PKG_ARCH) -DIR_TOOLS = $(BASEDIR)/tools -DIR_LOGS = $(BASEDIR)/logs +DIR_PATCHES = $(DIR_SOURCE)/patches +DIR_SRC = /usr/src +DIR_TMP = /tmp +DIR_SOURCE = $(CURDIR) +DIR_TOOLS = $(BASEDIR)/tools
-BUILD_HOST ?= $(shell cat /proc/sys/kernel/hostname) +# Directory where to search for object files +VPATH = $(DIR_DL)
-VPATH = $(DIR_DL) +# Paths to scripts +DO_EXTRACT = $(DIR_TOOLS)/extractor +DO_QUALITY_AGENT = $(DIR_TOOLS)/quality-agent + +############################################################################### +# +# Build environment +# +###############################################################################
-PKG_OBJECTS = $(PKG_TARBALL) -PKG_PATCHES = $(foreach patch,$(wildcard $(DIR_SOURCE)/patches/*.patch),$(notdir $(patch))) -OBJECTS = $(PKG_OBJECTS) +# Export CFLAGS + CXXFLAGS +export CFLAGS +export CXXFLAGS
-PKG_NAME_REAL = $(notdir $(CURDIR)) -PKG_PACKAGES = $(PKG_NAME_REAL) -PKG_PACKAGES_FILES = $(foreach package,$(PKG_PACKAGES),$(call DO_PACKAGE_FILENAME,$(package))) +# Options that get passed to configure by default +CONFIGURE_OPTIONS = \ + --prefix=/usr
+############################################################################### +# +# Packager variables +# +############################################################################### +# Variables that get exported (and expanded for the sub-packages) to the +# packager process +PKG_VARIABLES = \ + CONTROL_PREIN \ + CONTROL_PREUN \ + CONTROL_POSTIN \ + CONTROL_POSTUN \ + \ + PKG_ARCH \ + PKG_BUILD_DEPS \ + PKG_DEPS \ + PKG_DESCRIPTION \ + PKG_FILES \ + PKG_GROUP \ + PKG_MAINTAINER \ + PKG_LICENSE \ + PKG_PROVIDES \ + PKG_REL \ + PKG_SUMMARY \ + PKG_URL \ + PKG_VER + +# Variables that exported to the packager process +# These reflect settings from the build system +export BUILD_DATE ?= $(shell date -u) +export BUILD_HOST ?= $(shell cat /proc/sys/kernel/hostname) +export BUILD_ID + +############################################################################### +# +# Package variables +# +############################################################################### +# +# Constants +# + +# The suffix of the package name PKG_SUFFIX = -$(PKG_VER)-$(DISTRO_SNAME)$(DISTRO_EPOCH)-$(PKG_ARCH).$(PKG_REL).ipk
-DO_EXTRACT = $(DIR_TOOLS)/extractor -DO_PATCHES = cd $(DIR_APP) && $(DIR_TOOLS)/patch $(foreach patch,$(PKG_PATCHES),$(DIR_PATCHES)/$(patch)) -DO_QUALITY_AGENT = $(DIR_TOOLS)/quality-agent +# +# Variables +#
-PKG_BUILD_DEPS += gcc glibc-devel kernel-headers -PKG_DEPS += +# The actual package name (the name of the directory) +PKG_NAME_REAL = $(notdir $(CURDIR)) +PKG_NAME = $(PKG_NAME_REAL)
-CONFIGURE_OPTIONS = --prefix=/usr +# Shortcut to package name + version +THISAPP = $(PKG_NAME)-$(PKG_VER)
-ifeq "$(TARGET_MACHINE)" "x86_64" - LINKER = /lib64/ld-linux-x86-64.so.2 -else - LINKER = /lib/ld-linux.so.2 -endif +# All packages depend on gcc and headers by default. +PKG_BUILD_DEPS+= gcc glibc-devel kernel-headers +PKG_DEPS +=
-STAGE_PACKAGE_TARGETS = $(call reverse,$(PKG_PACKAGES_FILES)) -ifeq "$(TOOLCHAIN)" "1" - STAGE_DONE = $(ROOT)/$(PKG_NAME_REAL) -else - STAGE_DONE = $(ROOT)/.done -endif +# All PKG_OBJECTS are downloaded. This is in most cases the tarball. +PKG_OBJECTS = $(PKG_TARBALL) +OBJECTS = $(PKG_OBJECTS)
-PKG_DEFAULT_FILES = $(wildcard *.default) -PKG_DEFAULT_FILES += $(wildcard default/*) -PKG_INIT_FILES = $(wildcard *.init) -PKG_INIT_FILES += $(wildcard init/*.conf) -PKG_PAM_FILES = $(wildcard *.pam) -PKG_PAM_FILES += $(wildcard pam.d/*) +# List of packages to build +PKG_PACKAGES = $(PKG_NAME_REAL) + +# +# Macros +#
-export CFLAGS CXXFLAGS BUILD_HOST +# Abstract variable that translates the package names to a list of filenames +PKG_PACKAGES_FILES = $(foreach package,$(PKG_PACKAGES),$(call DO_PACKAGE_FILENAME,$(package))) + +# Automatically detect all patches in "patches" +PKG_PATCHES = \ + $(foreach patch,$(wildcard $(DIR_PATCHES)/*.patch),$(notdir $(patch)))
-export PKG_NAME PKG_VER PKG_REL PKG_MAINTAINER PKG_GROUP PKG_URL PKG_LICENSE -export PKG_SUMMARY PKG_DESCRIPTION=$(strip $(PKG_DESCRIPTION)) -export PKG_DEPS PKG_BUILD_DEPS +# Dynamic command that applies all patches +DO_PATCHES = cd $(DIR_APP) && $(DIR_TOOLS)/patch $(foreach patch,$(PKG_PATCHES),$(DIR_PATCHES)/$(patch))
-export CONTROL_PREIN CONTROL_PREUN CONTROL_POSTIN CONTROL_POSTUN +# Get a list of files that are installed automatically +PKG_DEFAULT_FILES = $(wildcard *.default) +PKG_DEFAULT_FILES += $(wildcard default/*) +PKG_INIT_FILES = $(wildcard *.init) +PKG_INIT_FILES += $(wildcard init/*.conf) +PKG_PAM_FILES = $(wildcard *.pam) +PKG_PAM_FILES += $(wildcard pam.d/*)
+############################################################################### +# +# Quality agent +# +############################################################################### + +export QUALITY_AGENT_PERMIT_NOT_FULL_RELRO export QUALITY_AGENT_RPATH_ALLOW_ORIGIN export QUALITY_AGENT_WHITELIST_EXECSTACK export QUALITY_AGENT_WHITELIST_NX export QUALITY_AGENT_WHITELIST_RPATH export QUALITY_AGENT_WHITELIST_SONAME -export QUALITY_AGENT_PERMIT_NOT_FULL_RELRO diff --git a/pkgs/Functions b/pkgs/Functions index 4dce5aa..258a02f 100644 --- a/pkgs/Functions +++ b/pkgs/Functions @@ -130,6 +130,9 @@ define DO_INSTALL $(DO_FILELIST) endef
+STAGE_PACKAGE_TARGETS = $(call reverse,$(PKG_PACKAGES_FILES)) +STAGE_DONE = $(ROOT)/.done + define STAGE_PREPARE $(if $(PKG_TARBALL),cd $(DIR_SRC) && $(DO_EXTRACT) $(DIR_DL)/$(PKG_TARBALL))
diff --git a/pkgs/Templates b/pkgs/Templates index 54f7e79..fd291cd 100644 --- a/pkgs/Templates +++ b/pkgs/Templates @@ -22,6 +22,8 @@ define PKG_FILES-$(PKG_NAME_REAL)-devel /usr/share/aclocal */lib/*.so /usr/share/*/cmake + /usr/share/man/man2 + /usr/share/man/man3 /usr/share/vala endef
diff --git a/pkgs/core/kernel/config b/pkgs/core/kernel/config index 5a43916..1ffdbae 100644 --- a/pkgs/core/kernel/config +++ b/pkgs/core/kernel/config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.34.1 -# Wed Aug 25 14:38:31 2010 +# Thu Aug 26 09:14:53 2010 # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -3279,6 +3279,7 @@ CONFIG_UIO_NETX=m CONFIG_X86_PLATFORM_DEVICES=y # CONFIG_ACER_WMI is not set CONFIG_ASUS_LAPTOP=m +# CONFIG_DELL_LAPTOP is not set CONFIG_DELL_WMI=m CONFIG_FUJITSU_LAPTOP=m # CONFIG_FUJITSU_LAPTOP_DEBUG is not set @@ -3309,10 +3310,11 @@ CONFIG_ACPI_CMPC=m # # Firmware Drivers # -# CONFIG_EDD is not set +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set CONFIG_FIRMWARE_MEMMAP=y -# CONFIG_DELL_RBU is not set -# CONFIG_DCDBAS is not set +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m CONFIG_DMIID=y # CONFIG_ISCSI_IBFT_FIND is not set
diff --git a/pkgs/core/pomona/pomona.nm b/pkgs/core/pomona/pomona.nm deleted file mode 100644 index 4c256f5..0000000 --- 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 http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# 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 41c9fc4..0000000 --- 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 http://www.gnu.org/licenses/. # -# # -############################################################################### - -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 26f9eb9..0000000 --- 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 http://www.gnu.org/licenses/. # -# # -############################################################################### - -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 7fbb49f..0000000 --- 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 9009486..0000000 --- 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 = _(" <F1> for help | <Tab> between elements | <Space> selects | <F12> 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 eed9fa7..0000000 --- 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 26c404f..0000000 --- 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 36fd2b0..0000000 --- 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 680ae05..0000000 --- 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 http://www.gnu.org/licenses/. # -# # -############################################################################### - -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 08684fa..0000000 --- a/pkgs/core/pomona/src/isys/isys.c +++ /dev/null @@ -1,62 +0,0 @@ - - -#include <Python.h> - -#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 4757e4c..0000000 --- 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 ffc2c97..0000000 --- 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 6b0f175..0000000 --- a/pkgs/core/pomona/src/isys/mount.c +++ /dev/null @@ -1,186 +0,0 @@ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <fcntl.h> - -#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 b505322..0000000 --- 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 <sys/mount.h> /* 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 3044626..0000000 --- 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 a4f15fd..0000000 --- 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 bdbe5d4..0000000 --- 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 aee3e5d..0000000 --- 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 3acd670..0000000 --- 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 f33dfe6..0000000 --- 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 49920d7..0000000 --- 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 hbrolarsen@aktinet.de\n" -"Language-Team: da@li.org\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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <return> to reboot your system.\n" -msgstr "" -"Du har ikke RAM nok til at installere %s på denne maskine.\n" -"Tast <return> 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 "" -" <Space> select | <F2> select default | <F4> delete | <F12> next screen>" -msgstr "<Mellemrum> vælg | <F2> vælg standard | <F4> slet | <F12> 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 <Enter> to end the installation process.\n" -"\n" -msgstr "" -"Tryk <enter> for at afslutte installationsprocessen.\n" -"\n" - -#: ../tui_complete.py:26 -msgid "<Enter> to exit" -msgstr "<Enter> 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 "<Not Applicable>" -msgstr "<Ikke brugbar>" - -#: ../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 "<Space>,<+>,<-> selection | <F2> Add drive | <F12> next screen" -msgstr "" -"<Mellemrum>,<+>,<-> valg | <F1> Tilføj drev | <F12> 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 "" -" <F1> for help | <Tab> between elements | <Space> selects | <F12> next screen" -msgstr "" -" <F1> for hjælp | <Tab> imellem punkter | <Mellemrum> vælg | <F12> næste side" - -#: ../tui.py:240 -msgid "" -" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next " -"screen" -msgstr "" -" <Tab>/<Alt-Tab> imellem punkter | <Mellemrum> vælger | <F12> 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 c03b398..0000000 --- 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 michael.tremer@ipfire.org, 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 michael.tremer@ipfire.org\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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <return> to reboot your system.\n" -msgstr "" -"Sie haben nicht genug Arbeitsspeicher um %s auf diesem System zu " -"installieren.\n" -"\n" -"Drücken Sie <Neustart> 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 "" -" <Space> select | <F2> select default | <F4> delete | <F12> next screen>" -msgstr "<Leertaste>,<+>,<-> Auswahl | <F2> Laufwerk hinzufügen | <F12> 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 <Enter> to end the installation process.\n" -"\n" -msgstr "" -"Drücken Sie <Enter> um den Installationprozess zu beenden.\n" -"\n" - -#: ../tui_complete.py:26 -msgid "<Enter> to exit" -msgstr "<Enter> 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 "<Not Applicable>" -msgstr "<Nicht verfügbar>" - -#: ../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 "<Space>,<+>,<-> selection | <F2> Add drive | <F12> next screen" -msgstr "<Leertaste>,<+>,<-> Auswahl | <F2> Laufwerk hinzufügen | <F12> 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 "" -" <F1> for help | <Tab> between elements | <Space> selects | <F12> next screen" -msgstr "" - -#: ../tui.py:240 -msgid "" -" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> 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 d1757a5..0000000 --- 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 EMAIL@ADDRESS, 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 EMAIL@ADDRESS\n" -"Language-Team: LANGUAGE LL@li.org\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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <Enter> 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 <return> 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 "" -" <Space> select | <F2> select default | <F4> delete | <F12> 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 <Enter> to end the installation process.\n" -"\n" -msgstr "" - -#: ../tui_complete.py:26 -msgid "<Enter> 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 "<Not Applicable>" -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 "<Space>,<+>,<-> selection | <F2> Add drive | <F12> 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 "" -" <F1> for help | <Tab> between elements | <Space> selects | <F12> next screen" -msgstr "" - -#: ../tui.py:240 -msgid "" -" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> 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 75c9ce5..0000000 --- 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 http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# # -# 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 <<EOF - - The installer program has finished with exit code ${ret}. - - Please reboot your system or do some debugging work :P - -EOF -sleep 1h diff --git a/pkgs/core/pomona/src/pomona.py b/pkgs/core/pomona/src/pomona.py deleted file mode 100644 index 9348d25..0000000 --- a/pkgs/core/pomona/src/pomona.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python - -import imputil -import os -import sys - -from datastore import DataStore -from dispatch import Dispatcher -from exception import handleException -from text import TextInterface -from log import Logger - -from constants import * - -import gettext -_ = lambda x: gettext.ldgettext("pomona", x) - -class Installer: - def __init__(self): - self.log = Logger() - - self.dispatch = None - self.ds = None - self.intf = TextInterface(self.log) - self.window = None - - def __call__(self): - if self.window: - self.window.pop() - - step = self.dispatch.nextStep() - while step: - self.log.info("") - self.log.info("---------- Running step "%s" ----------" % step[0]) - - if type(step[1]) == type(_): - (name, function) = step - self.log.debug(""%s" is called directly (%s)" % (name, function,)) - rc = function(self) - if rc in [DISPATCH_BACK, DISPATCH_FORWARD]: - self.dispatch.dir = rc - else: - (file, classes) = step - substep = 0 - while substep < len(classes): - while 1: - try: - found = imputil.imp.find_module(file) - loaded = imputil.imp.load_module(classes[substep], - found[0], found[1], - found[2]) - nextWindow = loaded.__dict__[classes[substep]] - break - except ImportError, e: - rc = self.intf.messageWindow(_("Error!"), - _("An error occurred when attempting " - "to load an pomona interface " - "component.\n\nclassName = %s\n\n" - "Error: %s") % (classes[substep],e), - type="custom", custom_buttons=[_("Exit"), _("Retry")]) - if rc == 0: - sys.exit(0) - - self.window = nextWindow() - rc = self.window(self) - - #if rc == INSTALL_NOOP: - # rc = lastrc - - if rc == INSTALL_BACK: - #step = step - 1 - self.dispatch.dir = DISPATCH_BACK - elif rc == INSTALL_OK: - #step = step + 1 - self.dispatch.dir = DISPATCH_FORWARD - - substep += 1 - - step = self.dispatch.nextStep() - - - -if __name__ == "__main__": - # Set up environment - if not os.environ.has_key("LANG"): - os.environ["LANG"] = "en_US.UTF-8" - os.environ['HOME'] = '/tmp' - os.environ['LC_NUMERIC'] = 'C' - - installer = Installer() - - sys.excepthook = lambda type, value, tb, installer=installer: \ - handleException(installer, (type, value, tb)) - - # Display some information - installer.window = \ - installer.intf.waitWindow(_("Installer"), _("Setting up installer..."),) - installer.log.info("Going on to install %s-v%s (%s)..." % \ - (PRODUCT_NAME, PRODUCT_VERSION, PRODUCT_SLOGAN,)) - - # Applying classes to installer - installer.dispatch = Dispatcher(installer) - installer.ds = DataStore(installer) - - try: - installer() - except SystemExit, code: - pass - except: - handleException(installer, sys.exc_info()) - - del installer.intf - del installer diff --git a/pkgs/core/pomona/src/pychecker-false-positives b/pkgs/core/pomona/src/pychecker-false-positives deleted file mode 100644 index a800d13..0000000 --- a/pkgs/core/pomona/src/pychecker-false-positives +++ /dev/null @@ -1,7 +0,0 @@ -deleted -filter -setattr -^$ -^Warnings...$ -^pomona.py:[0-9]*: Catching a non-Exception object (SystemExit)$ -Note this last line must never end with a newline \ No newline at end of file diff --git a/pkgs/core/pomona/src/runpychecker.sh b/pkgs/core/pomona/src/runpychecker.sh deleted file mode 100755 index fa65ad5..0000000 --- a/pkgs/core/pomona/src/runpychecker.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# This script will check pomona for any pychecker warning using a set of -# options minimizing false positives, in combination with filtering of any -# warning regularexpressions listed in pychecker-false-positives. -# -# If any warnings our found they will be stored in pychecker-log and printed -# to stdout and this script will exit with a status of 1, if no (non filtered) -# warnings are found it exits with a status of 0 - -FALSE_POSITIVES=pychecker-false-positives -NON_STRICT_OPTIONS="--no-deprecated --no-returnvalues --no-abstract" - -usage () { - echo "usage: `basename $0` [--strict] [--help]" - exit $1 -} - -while [ $# -gt 0 ]; do - case $1 in - --strict) - NON_STRICT_OPTIONS="" - ;; - --help) - usage 0 - ;; - *) - echo "Error unknown option: $1" - usage 1 - esac - shift -done - -if [ "`tail -c 1 pychecker-false-positives`" == "`echo`" ]; then - echo "Error $FALSE_POSITIVES ends with an enter." - echo "Error the last line of $FALSE_POSITIVES should never have an enter!" - exit 1 -fi - -export PYTHONPATH="isys" - -#for file in *.py isys/*.py; do FILES="${FILES} ${file}"; done -FILES=$(find . -name "*.py") - -pychecker --only --limit 1000 \ - --maxlines 500 --maxargs 20 --maxbranches 80 --maxlocals 60 --maxreturns 20 \ - --no-callinit --no-local --no-shadow --no-shadowbuiltin \ - --no-import --no-miximport --no-pkgimport --no-reimport \ - --no-argsused --no-varargsused --no-override \ - $NON_STRICT_OPTIONS $FILES | \ - egrep -v "`cat $FALSE_POSITIVES | tr '\n' '|'`" > 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 2a0da0b..0000000 --- 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 <Enter> 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 <Enter> 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 <Enter> 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("<device "): - continue - - line = line[len("<device "):-len("</device>\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 9361b52..0000000 --- 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 e69de29..0000000 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 52c9edd..0000000 --- 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 http://www.gnu.org/licenses/. -# -# Author(s): Dave Lehman dlehman@redhat.com -# Martin Sivak msivak@redhat.com -# - -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 20fa02a..0000000 --- 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 6c45d7d..0000000 --- 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 3628054..0000000 --- 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 8d3a1e1..0000000 --- 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 7a02dc0..0000000 --- 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 f73f138..0000000 --- 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 2eace61..0000000 --- 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 <host>:<path>") - - @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 25d9db4..0000000 --- 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 cccff87..0000000 --- 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 487d365..0000000 --- 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 0fb61d9..0000000 --- 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 a9a7377..0000000 --- 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 2719311..0000000 --- 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 e9afb4d..0000000 --- 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 5fbc819..0000000 --- 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 <Enter> to exit")) - - rc = installer.intf.messageWindow(_("Complete"), - _("Congratulations, your %s installation is " - "complete.\n\n" - "Press <Enter> 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 diff --git a/pkgs/core/python-pyaspects/python-pyaspects.nm b/pkgs/core/python-pyaspects/python-pyaspects.nm new file mode 100644 index 0000000..bd4bb79 --- /dev/null +++ b/pkgs/core/python-pyaspects/python-pyaspects.nm @@ -0,0 +1,52 @@ +############################################################################### +# # +# 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 http://www.gnu.org/licenses/. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pyaspects +PKG_VER = 0.4.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Languages +PKG_URL = http://github.com/baris/pyaspects/downloads +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Module to provide aspect-oriented programming. + +PKG_BUILD_DEPS+= python-devel + +define PKG_DESCRIPTION + PyAspects is a project to ease aspect-oriented programming \ + in Python language. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_BUILD + cd $(DIR_APP) && python setup.py build +endef + +define STAGE_INSTALL + cd $(DIR_APP) && python setup.py install --root=$(BUILDROOT) +endef diff --git a/pkgs/core/xorg-x11-fonts/xorg-x11-fonts.nm b/pkgs/core/xorg-x11-fonts/xorg-x11-fonts.nm index d8ec50d..84d0fe4 100644 --- a/pkgs/core/xorg-x11-fonts/xorg-x11-fonts.nm +++ b/pkgs/core/xorg-x11-fonts/xorg-x11-fonts.nm @@ -34,7 +34,7 @@ PKG_URL = http://www.x.org/ PKG_LICENSE = MIT PKG_SUMMARY = X.Org X11 fonts.
-PKG_BUILD_DEPS+= pkg-config xorg-x11-font-utils +PKG_BUILD_DEPS+= /usr/bin/mkfontscale perl pkg-config xorg-x11-font-utils-devel PKG_DEPS += fontconfig
define PKG_DESCRIPTION diff --git a/pkgs/core/xorg-x11-xinit/xorg-x11-xinit.nm b/pkgs/core/xorg-x11-xinit/xorg-x11-xinit.nm index a169307..74d2175 100644 --- a/pkgs/core/xorg-x11-xinit/xorg-x11-xinit.nm +++ b/pkgs/core/xorg-x11-xinit/xorg-x11-xinit.nm @@ -34,8 +34,7 @@ PKG_URL = http://www.x.org PKG_LICENSE = MIT PKG_SUMMARY = X.Org X11 X Window System xinit startup scripts.
-PKG_BUILD_DEPS+= autoconf automake pkg-config -PKG_DEPS += libX11 +PKG_BUILD_DEPS+= autoconf automake libX11-devel pkg-config
define PKG_DESCRIPTION X.Org X11 X Window System xinit startup scripts. diff --git a/tools/functions-packager-find b/tools/functions-packager-find index 197cdb0..e89831a 100644 --- a/tools/functions-packager-find +++ b/tools/functions-packager-find @@ -36,6 +36,7 @@ function find_requires() {
# Others local others=$(find_python_requires ${dirs}) + others="${others} $(find_weak_symbols_requires ${dirs})"
# Get provides, because packages should not depend on features they provide # by themselves. @@ -45,6 +46,7 @@ function find_requires() { local require local requires for require in $(listsort ${interpreters} ${neededs} ${links} ${others}); do + [ "${require:0:3}" = "ld-" ] && continue listmatch ${require} ${provides} || requires="${requires} ${require}" done
@@ -63,6 +65,7 @@ function find_provides() {
# Others local others=$(find_python_provides ${dirs}) + others="${others} $(find_weak_symbols_provides ${dirs})"
listsort ${sonames} ${others} } @@ -148,3 +151,44 @@ function find_python_requires() { fi done } + +function find_weak_symbols_provides() { + local dirs=$@ + + local file + local soname + local symbol + for file in $(find_elf_files ${dirs}); do + soname=$(file_get_soname ${file}) + [ -z "${soname}" ] && continue + + for symbol in $(objdump -p ${file} | grep -E "^[0-9]+" | awk '{ print $4 }'); do + [ "${symbol}" = "${soname}" ] && continue + + echo "${soname}(${symbol})" + done + done | sort -u +} + +function find_weak_symbols_requires() { + local dirs=$@ + + local file + for file in $(find_elf_files ${dirs}); do + objdump -p ${file} | awk 'BEGIN { START=0; LIBNAME=""; } + /^$/ { START=0; } + /^Dynamic Section:$/ { START=1; } + (START==1) && /NEEDED/ { + print $2; + } + (START==2) && /^[A-Za-z]/ { START=3; } + /^Version References:$/ { START=2; } + (START==2) && /required from/ { + sub(/:/, "", $3); + LIBNAME=$3; + } + (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) { + print LIBNAME "(" $4 ")"; + }' + done | sort -u +} diff --git a/tools/packager b/tools/packager index 1318e9e..6bd50b5 100755 --- a/tools/packager +++ b/tools/packager @@ -55,8 +55,10 @@ function create_metafile() {
VERSION="${PACKAGER_VERSION}"
+# Build information +BUILD_DATE="${BUILD_DATE}" BUILD_HOST="${BUILD_HOST}" -BUILD_DATE="$(date -u)" +BUILD_ID="${BUILD_ID}"
# Version info PKG_NAME="${PKG_NAME}"
hooks/post-receive -- IPFire 3.x development tree