summaryrefslogtreecommitdiffstats
path: root/pyanaconda/installclass.py
diff options
context:
space:
mode:
authorMartin Sivak <msivak@redhat.com>2010-05-11 17:31:06 +0200
committerMartin Sivak <msivak@redhat.com>2010-05-31 14:21:49 +0200
commit78421d4ed23ad58b021c4d9d1bae690b99c167fe (patch)
tree909c1b650afe9afea03ecf1a03b2d39d39cf72b7 /pyanaconda/installclass.py
parent40b979f28cfd73078d5dd58b8f7e97e76198a222 (diff)
downloadanaconda-78421d4ed23ad58b021c4d9d1bae690b99c167fe.tar.gz
anaconda-78421d4ed23ad58b021c4d9d1bae690b99c167fe.tar.xz
anaconda-78421d4ed23ad58b021c4d9d1bae690b99c167fe.zip
Structure the repo layout so it matches final structure better and make isys a real Python package.
Also updates the build and autotools stuff to work with the new structure
Diffstat (limited to 'pyanaconda/installclass.py')
-rw-r--r--pyanaconda/installclass.py329
1 files changed, 329 insertions, 0 deletions
diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
new file mode 100644
index 000000000..85076a3c7
--- /dev/null
+++ b/pyanaconda/installclass.py
@@ -0,0 +1,329 @@
+#
+# installclass.py: This is the prototypical class for workstation, server, and
+# kickstart installs. The interface to BaseInstallClass is *public* --
+# ISVs/OEMs can customize the install by creating a new derived type of this
+# class.
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+from distutils.sysconfig import get_python_lib
+import os, sys, iutil
+import isys
+import string
+import language
+import imputil
+import types
+
+from constants import *
+from product import *
+from storage.partspec import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+from flags import flags
+
+class BaseInstallClass(object):
+ # default to not being hidden
+ hidden = 0
+ pixmap = None
+ showMinimal = 1
+ showLoginChoice = 0
+ _description = ""
+ _descriptionFields = ()
+ name = "base"
+ pkgstext = ""
+ # default to showing the upgrade option
+ showUpgrade = True
+ bootloaderTimeoutDefault = None
+ bootloaderExtraArgs = ""
+
+ # list of of (txt, grplist) tuples for task selection screen
+ tasks = []
+
+ # don't select this class by default
+ default = 0
+
+ # by default, place this under the "install" category; it gets it's
+ # own toplevel category otherwise
+ parentClass = ( _("Install on System"), "install.png" )
+
+ def _get_description(self):
+ return _(self._description) % self._descriptionFields
+ description = property(_get_description)
+
+ def postAction(self, anaconda):
+ anaconda.backend.postAction(anaconda)
+
+ def setSteps(self, anaconda):
+ dispatch = anaconda.dispatch
+ dispatch.setStepList(
+ "language",
+ "keyboard",
+ "welcome",
+ "filtertype",
+ "filter",
+ "storageinit",
+ "findrootparts",
+ "betanag",
+ "cleardiskssel",
+ "parttype",
+ "autopartitionexecute",
+ "partition",
+ "storagedone",
+ "bootloadersetup",
+ "bootloader",
+ "network",
+ "timezone",
+ "accounts",
+ "reposetup",
+ "basepkgsel",
+ "tasksel",
+ "postselection",
+ "reipl",
+ "install",
+ "enablefilesystems",
+ "setuptime",
+ "preinstallconfig",
+ "installpackages",
+ "postinstallconfig",
+ "writeconfig",
+ "firstboot",
+ "instbootloader",
+ "dopostaction",
+ "postscripts",
+ "writeksconfig",
+ "methodcomplete",
+ "copylogs",
+ "setfilecon",
+ "complete"
+ )
+
+ if not BETANAG:
+ dispatch.skipStep("betanag", permanent=1)
+
+ if iutil.isEfi() or not iutil.isX86():
+ dispatch.skipStep("bootloader", permanent=1)
+
+ # allow backends to disable interactive package selection
+ if not anaconda.backend.supportsPackageSelection:
+ dispatch.skipStep("tasksel", skip = 1, permanent=1)
+ dispatch.skipStep("group-selection", skip = 1, permanent=1)
+
+ # allow install classes to turn off the upgrade
+ if not self.showUpgrade or not anaconda.backend.supportsUpgrades:
+ dispatch.skipStep("findrootparts", skip = 1)
+
+ # 'noupgrade' can be used on the command line to force not looking
+ # for partitions to upgrade. useful in some cases...
+ if flags.cmdline.has_key("noupgrade"):
+ dispatch.skipStep("findrootparts", skip = 1)
+
+ # upgrade will also always force looking for an upgrade.
+ if flags.cmdline.has_key("upgrade"):
+ dispatch.skipStep("findrootparts", skip = 0)
+
+ # allow interface backends to skip certain steps.
+ anaconda.intf.setSteps(anaconda)
+
+ # modifies the uri from installmethod.getMethodUri() to take into
+ # account any installclass specific things including multiple base
+ # repositories. takes a string or list of strings, returns a dict
+ # with string keys and list values {%repo: %uri_list}
+ def getPackagePaths(self, uri):
+ if not type(uri) == types.ListType:
+ uri = [uri,]
+
+ return {'base': uri}
+
+ def setPackageSelection(self, anaconda):
+ pass
+
+ def setGroupSelection(self, anaconda):
+ grps = anaconda.backend.getDefaultGroups(anaconda)
+ map(lambda x: anaconda.backend.selectGroup(x), grps)
+
+ def getBackend(self):
+ # this should be overriden in distro install classes
+ from backend import AnacondaBackend
+ return AnacondaBackend
+
+ def setDefaultPartitioning(self, storage, platform):
+ autorequests = [PartSpec(mountpoint="/", fstype=storage.defaultFSType,
+ size=1024, maxSize=50*1024, grow=True,
+ asVol=True),
+ PartSpec(mountpoint="/home", fstype=storage.defaultFSType,
+ size=100, grow=True, asVol=True, requiredSpace=50*1024)]
+
+ bootreq = platform.setDefaultPartitioning()
+ if bootreq:
+ autorequests.extend(bootreq)
+
+ (minswap, maxswap) = iutil.swapSuggestion()
+ autorequests.append(PartSpec(fstype="swap", size=minswap, maxSize=maxswap,
+ grow=True, asVol=True))
+
+ storage.autoPartitionRequests = autorequests
+
+ def configure(self, anaconda):
+ anaconda.bootloader.timeout = self.bootloaderTimeoutDefault
+ anaconda.bootloader.args.append(self.bootloaderExtraArgs)
+
+ def versionMatches(self, oldver):
+ pass
+
+ def productMatches(self, oldprod):
+ pass
+
+ def productUpgradable(self, oldprod, oldver):
+ return self.productMatches(oldprod) and self.versionMatches(oldver)
+
+ def __init__(self):
+ pass
+
+allClasses = []
+allClasses_hidden = []
+
+# returns ( className, classObject, classLogo ) tuples
+def availableClasses(showHidden=0):
+ global allClasses
+ global allClasses_hidden
+
+ def _ordering(first, second):
+ ((name1, obj, logo), priority1) = first
+ ((name2, obj, logo), priority2) = second
+
+ if priority1 < priority2:
+ return -1
+ elif priority1 > priority2:
+ return 1
+
+ if name1 < name2:
+ return -1
+ elif name1 > name2:
+ return 1
+
+ return 0
+
+ if not showHidden:
+ if allClasses: return allClasses
+ else:
+ if allClasses_hidden: return allClasses_hidden
+
+ path = []
+
+ for dir in ["installclasses",
+ "/tmp/updates/pyanaconda/installclasses",
+ "/tmp/product/pyanaconda/installclasses",
+ "%s/pyanaconda/installclasses" % get_python_lib(plat_specific=1) ]:
+ if os.access(dir, os.R_OK):
+ path.append(dir)
+
+ # append the location of installclasses to the python path so we
+ # can import them
+ sys.path = path + sys.path
+
+ files = []
+ for p in reversed(path):
+ files += os.listdir(p)
+
+ done = {}
+ list = []
+ for file in files:
+ if file[0] == '.': continue
+ if len (file) < 4:
+ continue
+ if file[-3:] != ".py" and file[-4:-1] != ".py":
+ continue
+ mainName = string.split(file, ".")[0]
+ if done.has_key(mainName): continue
+ done[mainName] = 1
+
+ try:
+ found = imputil.imp.find_module(mainName)
+ except:
+ log.warning ("module import of %s failed: %s" % (mainName, sys.exc_type))
+ continue
+
+ try:
+ loaded = imputil.imp.load_module(mainName, found[0], found[1], found[2])
+
+ obj = loaded.InstallClass
+
+ if obj.__dict__.has_key('sortPriority'):
+ sortOrder = obj.sortPriority
+ else:
+ sortOrder = 0
+
+ if obj.__dict__.has_key('arch'):
+ if obj.arch != iutil.getArch():
+ obj.hidden = 1
+
+ if obj.hidden == 0 or showHidden == 1:
+ list.append(((obj.name, obj, obj.pixmap), sortOrder))
+ except:
+ log.warning ("module import of %s failed: %s" % (mainName, sys.exc_type))
+ if flags.debug: raise
+ else: continue
+
+ list.sort(_ordering)
+ for (item, priority) in list:
+ if showHidden:
+ allClasses_hidden.append(item)
+ else:
+ allClasses.append(item)
+
+ if showHidden:
+ return allClasses_hidden
+ else:
+ return allClasses
+
+def getBaseInstallClass():
+ # figure out what installclass we should base on.
+ allavail = availableClasses(showHidden = 1)
+ avail = availableClasses(showHidden = 0)
+ if len(avail) == 1:
+ (cname, cobject, clogo) = avail[0]
+ log.info("using only installclass %s" %(cname,))
+ elif len(allavail) == 1:
+ (cname, cobject, clogo) = allavail[0]
+ log.info("using only installclass %s" %(cname,))
+
+ # Use the highest priority install class if more than one found.
+ elif len(avail) > 1:
+ (cname, cobject, clogo) = avail.pop()
+ log.info('%s is the highest priority installclass, using it' % cname)
+ elif len(allavail) > 1:
+ (cname, cobject, clogo) = allavail.pop()
+ log.info('%s is the highest priority installclass, using it' % cname)
+
+ # Default to the base installclass if nothing else is found.
+ else:
+ raise RuntimeError, "Unable to find an install class to use!!!"
+
+ return cobject
+
+baseclass = getBaseInstallClass()
+
+# we need to be able to differentiate between this and custom
+class DefaultInstall(baseclass):
+ def __init__(self):
+ baseclass.__init__(self)