Hi, I have added SUSE support for "cobbler import", based on the red hat importer module. Only 2 new files were added. - the importer modules - an autoyast XML file in kickstarts/...
Patch attached and here: https://github.com/ugansert/Cobbler -- ciao, Uwe Gansert Uwe Gansert SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg) Business: http://www.suse.de/~ug
From bc83f0065e155f4fd7c3343f88d38184cc06f980 Mon Sep 17 00:00:00 2001 From: Uwe Gansert <u...@suse.de> Date: Tue, 5 Apr 2011 13:11:52 +0200 Subject: [PATCH] added support for suse-distro import --- cobbler/modules/manage_import_suse.py | 772 +++++++++++++++++++++++++++++++++ kickstarts/autoyast_sample.xml | 45 ++ 2 files changed, 817 insertions(+), 0 deletions(-) create mode 100644 cobbler/modules/manage_import_suse.py create mode 100644 kickstarts/autoyast_sample.xml diff --git a/cobbler/modules/manage_import_suse.py b/cobbler/modules/manage_import_suse.py new file mode 100644 index 0000000..802800e --- /dev/null +++ b/cobbler/modules/manage_import_suse.py @@ -0,0 +1,772 @@ +""" +-- +-- Copyright (c) 2011 Novell +-- Uwe Gansert <u...@suse.de> +-- +-- This software is licensed to you under the GNU General Public License, +-- version 2 (GPLv2). There is NO WARRANTY for this software, express or +-- implied, including the implied warranties of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 +-- along with this software; if not, see +-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. +-- +-- + +""" + +import os +import os.path +import shutil +import time +import sys +import glob +import traceback +import errno +from utils import popen2 +from shlex import shlex + + +import utils +from cexceptions import * +import templar + +import item_distro +import item_profile +import item_repo +import item_system + +from utils import _ + +# FIXME: add --quiet depending on if not --verbose? +RSYNC_CMD = "rsync -a %s '%s' %s --exclude-from=/etc/cobbler/rsync.exclude --progress" + +def register(): + """ + The mandatory cobbler module registration hook. + """ + return "manage/import" + + +class ImportSuseManager: + + def __init__(self,config,logger): + """ + Constructor + """ + self.logger = logger + self.config = config + self.api = config.api + self.distros = config.distros() + self.profiles = config.profiles() + self.systems = config.systems() + self.settings = config.settings() + self.repos = config.repos() + self.templar = templar.Templar(config) + + # required function for import modules + def what(self): + return "import/suse" + + # required function for import modules + def check_for_signature(self,path,cli_breed): + signatures = [ + 'suse' + ] + + #self.logger.info("scanning %s for a redhat-based distro signature" % path) + for signature in signatures: + d = os.path.join(path,signature) + if os.path.exists(d): + self.logger.info("Found a SUSE compatible signature: %s" % signature) + return (True,signature) + + if cli_breed and cli_breed in self.get_valid_breeds(): + self.logger.info("Warning: No distro signature for kernel at %s, using value from command line" % path) + return (True,None) + + return (False,None) + + # required function for import modules + def run(self,pkgdir,mirror,mirror_name,network_root=None,kickstart_file=None,rsync_flags=None,arch=None,breed=None,os_version=None): + self.pkgdir = pkgdir + self.mirror = mirror + self.mirror_name = mirror_name + self.network_root = network_root + self.kickstart_file = kickstart_file + self.rsync_flags = rsync_flags + self.arch = arch + self.breed = breed + self.os_version = os_version + + # some fixups for the XMLRPC interface, which does not use "None" + if self.arch == "": self.arch = None + if self.mirror == "": self.mirror = None + if self.mirror_name == "": self.mirror_name = None + if self.kickstart_file == "": self.kickstart_file = None + if self.os_version == "": self.os_version = None + if self.rsync_flags == "": self.rsync_flags = None + if self.network_root == "": self.network_root = None + + # If no breed was specified on the command line, set it to "suse" for this module + if self.breed == None: + self.breed = "suse" + + # debug log stuff for testing + #self.logger.info("self.pkgdir = %s" % str(self.pkgdir)) + #self.logger.info("self.mirror = %s" % str(self.mirror)) + #self.logger.info("self.mirror_name = %s" % str(self.mirror_name)) + #self.logger.info("self.network_root = %s" % str(self.network_root)) + #self.logger.info("self.kickstart_file = %s" % str(self.kickstart_file)) + #self.logger.info("self.rsync_flags = %s" % str(self.rsync_flags)) + #self.logger.info("self.arch = %s" % str(self.arch)) + #self.logger.info("self.breed = %s" % str(self.breed)) + #self.logger.info("self.os_version = %s" % str(self.os_version)) + + # both --import and --name are required arguments + + if self.mirror is None: + utils.die(self.logger,"import failed. no --path specified") + if self.mirror_name is None: + utils.die(self.logger,"import failed. no --name specified") + + # if --arch is supplied, validate it to ensure it's valid + + if self.arch is not None and self.arch != "": + self.arch = self.arch.lower() + if self.arch == "x86": + # be consistent + self.arch = "i386" + if self.arch in [ 'i486', 'i586', 'i686' ]: + self.arch = "i386" + if self.arch not in self.get_valid_arches(): + utils.die(self.logger,"arch must be one of: %s" % string.join(self.get_valid_arches(),", ")) + + # if we're going to do any copying, set where to put things + # and then make sure nothing is already there. + + self.path = os.path.normpath( "%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name) ) + self.rootdir = os.path.normpath( "%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name) ) + if os.path.exists(self.path) and self.arch is None: + # FIXME : Raise exception even when network_root is given ? + utils.die(self.logger,"Something already exists at this import location (%s). You must specify --arch to avoid potentially overwriting existing files." % self.path) + + # import takes a --kickstart for forcing selection that can't be used in all circumstances + + if self.kickstart_file and not self.breed: + utils.die(self.logger,"Kickstart file can only be specified when a specific breed is selected") + + if self.os_version and not self.breed: + utils.die(self.logger,"OS version can only be specified when a specific breed is selected") + + if self.breed and self.breed.lower() not in self.get_valid_breeds(): + utils.die(self.logger,"Supplied import breed is not supported by this module") + + # if --arch is supplied, make sure the user is not importing a path with a different + # arch, which would just be silly. + + if self.arch: + # append the arch path to the name if the arch is not already + # found in the name. + for x in self.get_valid_arches(): + if self.path.lower().find(x) != -1: + if self.arch != x : + utils.die(self.logger,"Architecture found on pathname (%s) does not fit the one given in command line (%s)"%(x,self.arch)) + break + else: + # FIXME : This is very likely removed later at get_proposed_name, and the guessed arch appended again + self.path += ("-%s" % self.arch) + + # make the output path and mirror content but only if not specifying that a network + # accessible support location already exists (this is --available-as on the command line) + + if self.network_root is None: + # we need to mirror (copy) the files + + utils.mkdir(self.path) + + # prevent rsync from creating the directory name twice + # if we are copying via rsync + + if not self.mirror.endswith("/"): + self.mirror = "%s/" % self.mirror + + if self.mirror.startswith("http://") or self.mirror.startswith("ftp://") or self.mirror.startswith("nfs://"): + + # http mirrors are kind of primative. rsync is better. + # that's why this isn't documented in the manpage and we don't support them. + # TODO: how about adding recursive FTP as an option? + + utils.die(self.logger,"unsupported protocol") + + else: + + # good, we're going to use rsync.. + # we don't use SSH for public mirrors and local files. + # presence of user@host syntax means use SSH + + spacer = "" + if not self.mirror.startswith("rsync://") and not self.mirror.startswith("/"): + spacer = ' -e "ssh" ' + rsync_cmd = RSYNC_CMD + if self.rsync_flags: + rsync_cmd = rsync_cmd + " " + self.rsync_flags + + # kick off the rsync now + + utils.run_this(rsync_cmd, (spacer, self.mirror, self.path), self.logger) + + else: + + # rather than mirroring, we're going to assume the path is available + # over http, ftp, and nfs, perhaps on an external filer. scanning still requires + # --mirror is a filesystem path, but --available-as marks the network path + + if not os.path.exists(self.mirror): + utils.die(self.logger, "path does not exist: %s" % self.mirror) + + # find the filesystem part of the path, after the server bits, as each distro + # URL needs to be calculated relative to this. + + if not self.network_root.endswith("/"): + self.network_root = self.network_root + "/" + self.path = os.path.normpath( self.mirror ) + valid_roots = [ "nfs://", "ftp://", "http://" ] + for valid_root in valid_roots: + if self.network_root.startswith(valid_root): + break + else: + utils.die(self.logger, "Network root given to --available-as must be nfs://, ftp://, or http://") + if self.network_root.startswith("nfs://"): + try: + (a,b,rest) = self.network_root.split(":",3) + except: + utils.die(self.logger, "Network root given to --available-as is missing a colon, please see the manpage example.") + + # now walk the filesystem looking for distributions that match certain patterns + + self.logger.info("adding distros") + distros_added = [] + # FIXME : search below self.path for isolinux configurations or known directories from TRY_LIST + os.path.walk(self.path, self.distro_adder, distros_added) + + # find out if we can auto-create any repository records from the install tree + + if self.network_root is None: + self.logger.info("associating repos") + # FIXME: this automagic is not possible (yet) without mirroring + self.repo_finder(distros_added) + + # find the most appropriate answer files for each profile object + + self.logger.info("associating kickstarts") + self.kickstart_finder(distros_added) + + # ensure bootloaders are present + self.api.pxegen.copy_bootloaders() + + return True + + # required function for import modules + def get_valid_arches(self): + return ["i386", "ia64", "ppc", "ppc64", "s390", "s390x", "x86_64", "x86",] + + # required function for import modules + def get_valid_breeds(self): + return ["suse",] + + # required function for import modules + def get_valid_os_versions(self): + return [] + + def get_valid_repo_breeds(self): + return ["yast", "rsync", "yum"] + + def get_release_files(self): + data = glob.glob(os.path.join(self.get_pkgdir(), "*release-*")) + data2 = [] + for x in data: + b = os.path.basename(x) +# FIXME +# if b.find("fedora") != -1 or \ +# b.find("redhat") != -1 or \ +# b.find("centos") != -1: +# data2.append(x) + return data2 + + def get_tree_location(self, distro): + """ + Once a distribution is identified, find the part of the distribution + that has the URL in it that we want to use for kickstarting the + distribution, and create a ksmeta variable $tree that contains this. + """ + + base = self.get_rootdir() + + if self.network_root is None: + dest_link = os.path.join(self.settings.webdir, "links", distro.name) + # create the links directory only if we are mirroring because with + # SELinux Apache can't symlink to NFS (without some doing) + if not os.path.exists(dest_link): + try: + os.symlink(base + "-" + distro.arch, dest_link) + except: + # this shouldn't happen but I've seen it ... debug ... + self.logger.warning("symlink creation failed: %(base)s, %(dest)s") % { "base" : base, "dest" : dest_link } + # how we set the tree depends on whether an explicit network_root was specified + tree = "http://@@http_server@@/cblr/links/%s" % (distro.name) + self.set_install_tree(distro, tree) + else: + # where we assign the kickstart source is relative to our current directory + # and the input start directory in the crawl. We find the path segments + # between and tack them on the network source path to find the explicit + # network path to the distro that Anaconda can digest. + tail = self.path_tail(self.path, base) + tree = self.network_root[:-1] + tail + self.set_install_tree(distro, tree) + + return + + def repo_finder(self, distros_added): + """ + This routine looks through all distributions and tries to find + any applicable repositories in those distributions for post-install + usage. + """ + + for distro in distros_added: + self.logger.info("traversing distro %s" % distro.name) + # FIXME : Shouldn't decide this the value of self.network_root ? + if distro.kernel.find("ks_mirror") != -1: + basepath = os.path.dirname(distro.kernel) + top = self.get_rootdir() + self.logger.info("descent into %s" % top) + # FIXME : The location of repo definition is known from breed + os.path.walk(top, self.repo_scanner, distro) + else: + self.logger.info("this distro isn't mirrored") + + def repo_scanner(self,distro,dirname,fnames): + """ + This is an os.path.walk routine that looks for potential yum repositories + to be added to the configuration for post-install usage. + """ + + matches = {} + for x in fnames: + if x == "base" or x == "repodata": + self.logger.info("processing repo at : %s" % dirname) + # only run the repo scanner on directories that contain a comps.xml + gloob1 = glob.glob("%s/%s/*comps*.xml" % (dirname,x)) + if len(gloob1) >= 1: + if matches.has_key(dirname): + self.logger.info("looks like we've already scanned here: %s" % dirname) + continue + self.logger.info("need to process repo/comps: %s" % dirname) + matches[dirname] = 1 + else: + self.logger.info("directory %s is missing xml comps file, skipping" % dirname) + continue + + def distro_adder(self,distros_added,dirname,fnames): + """ + This is an os.path.walk routine that finds distributions in the directory + to be scanned and then creates them. + """ + + # FIXME: If there are more than one kernel or initrd image on the same directory, + # results are unpredictable + + initrd = None + kernel = None + + # make sure we don't mismatch PAE and non-PAE types + pae_initrd = None + pae_kernel = None + + for x in fnames: + adtls = [] + + fullname = os.path.join(dirname,x) + if os.path.islink(fullname) and os.path.isdir(fullname): + if fullname.startswith(self.path): + # Prevent infinite loop with Sci Linux 5 + self.logger.warning("avoiding symlink loop") + continue + self.logger.info("following symlink: %s" % fullname) + os.path.walk(fullname, self.distro_adder, distros_added) + + if ( x.startswith("initrd") or x.startswith("ramdisk.image.gz") ) and x != "initrd.size": + if x.find("PAE") == -1: + initrd = os.path.join(dirname,x) + else: + pae_initrd = os.path.join(dirname, x) + + if ( x.startswith("vmlinu") or x.startswith("kernel.img") or x.startswith("linux") ) and x.find("initrd") == -1: + if x.find("PAE") == -1: + kernel = os.path.join(dirname,x) + else: + pae_kernel = os.path.join(dirname, x) + + # if we've collected a matching kernel and initrd pair, turn the in and add them to the list + if initrd is not None and kernel is not None and dirname.find("isolinux") == -1: + adtls.append(self.add_entry(dirname,kernel,initrd)) + kernel = None + initrd = None + elif pae_initrd is not None and pae_kernel is not None and dirname.find("isolinux") == -1: + adtls.append(self.add_entry(dirname,pae_kernel,pae_initrd)) + pae_kernel = None + pae_initrd = None + + for adtl in adtls: + distros_added.extend(adtl) + + def add_entry(self,dirname,kernel,initrd): + """ + When we find a directory with a valid kernel/initrd in it, create the distribution objects + as appropriate and save them. This includes creating xen and rescue distros/profiles + if possible. + """ + + proposed_name = self.get_proposed_name(dirname,kernel) + proposed_arch = self.get_proposed_arch(dirname) + + if self.arch and proposed_arch and self.arch != proposed_arch: + utils.die(self.logger,"Arch from pathname (%s) does not match with supplied one %s"%(proposed_arch,self.arch)) + + archs = self.learn_arch_from_tree() + if not archs: + if self.arch: + archs.append( self.arch ) + else: + if self.arch and self.arch not in archs: + utils.die(self.logger, "Given arch (%s) not found on imported tree %s"%(self.arch,self.get_pkgdir())) + if proposed_arch: + if archs and proposed_arch not in archs: + self.logger.warning("arch from pathname (%s) not found on imported tree %s" % (proposed_arch,self.get_pkgdir())) + return + + archs = [ proposed_arch ] + + if len(archs)>1: + if self.breed in [ "suse" ]: + self.logger.warning("directory %s holds multiple arches : %s" % (dirname, archs)) + return + self.logger.warning("- Warning : Multiple archs found : %s" % (archs)) + + distros_added = [] + + for pxe_arch in archs: + name = proposed_name + "-" + pxe_arch + existing_distro = self.distros.find(name=name) + + if existing_distro is not None: + self.logger.warning("skipping import, as distro name already exists: %s" % name) + continue + + else: + self.logger.info("creating new distro: %s" % name) + distro = self.config.new_distro() + + if name.find("-autoboot") != -1: + # this is an artifact of some EL-3 imports + continue + + distro.set_name(name) + distro.set_kernel(kernel) + distro.set_initrd(initrd) + distro.set_arch(pxe_arch) + distro.set_breed(self.breed) + distro.set_kernel_options("install=http://@@http_server@@/cblr/links/%s" % (name)) + # If a version was supplied on command line, we set it now + if self.os_version: + distro.set_os_version(self.os_version) + + self.distros.add(distro,save=True) + distros_added.append(distro) + + existing_profile = self.profiles.find(name=name) + + # see if the profile name is already used, if so, skip it and + # do not modify the existing profile + + if existing_profile is None: + self.logger.info("creating new profile: %s" % name) + #FIXME: The created profile holds a default kickstart, and should be breed specific + profile = self.config.new_profile() + else: + self.logger.info("skipping existing profile, name already exists: %s" % name) + continue + + # save our minimal profile which just points to the distribution and a good + # default answer file + + profile.set_name(name) + profile.set_distro(name) + profile.set_kickstart(self.kickstart_file) + + # depending on the name of the profile we can define a good virt-type + # for usage with koan + + if name.find("-xen") != -1: + profile.set_virt_type("xenpv") + elif name.find("vmware") != -1: + profile.set_virt_type("vmware") + else: + profile.set_virt_type("qemu") + + # save our new profile to the collection + + self.profiles.add(profile,save=True) + + # Create a rescue image as well, if this is not a xen distro + # but only for red hat profiles + + # this code disabled as it seems to be adding "-rescue" to + # distros that are /not/ rescue related, which is wrong. + # left as a FIXME for those who find this feature interesting. + #if name.find("-xen") == -1 and self.breed == "redhat": + # rescue_name = 'rescue-' + name + # existing_profile = self.profiles.find(name=rescue_name) + # + # if existing_profile is None: + # self.logger.info("creating new profile: %s" % rescue_name) + # profile = self.config.new_profile() + # else: + # continue + # + # profile.set_name(rescue_name) + # profile.set_distro(name) + # profile.set_virt_type("qemu") + # profile.kernel_options['rescue'] = None + # profile.kickstart = '/var/lib/cobbler/kickstarts/pxerescue.ks' + # + # self.profiles.add(profile,save=True) + + return distros_added + + def get_proposed_name(self,dirname,kernel=None): + """ + Given a directory name where we have a kernel/initrd pair, try to autoname + the distribution (and profile) object based on the contents of that path + """ + + if self.network_root is not None: + name = self.mirror_name + "-".join(self.path_tail(os.path.dirname(self.path),dirname).split("/")) + else: + # remove the part that says /var/www/cobbler/ks_mirror/name + name = "-".join(dirname.split("/")[5:]) + + if kernel is not None and kernel.find("PAE") != -1: + name = name + "-PAE" + if kernel is not None and kernel.find("xen") != -1: + name = name + "-xen" + + # we have our kernel in ../boot/<arch>/vmlinuz-xen and + # .../boot/<arch>/loader/vmlinuz + # + name = name.replace("-loader","") + name = name.replace("-boot","") + + # some paths above the media root may have extra path segments we want + # to clean up + name = name.replace("-os","") + name = name.replace("-tree","") + name = name.replace("srv-www-cobbler-", "") + name = name.replace("var-www-cobbler-", "") + name = name.replace("ks_mirror-","") + name = name.replace("--","-") + + for separator in [ '-' , '_' , '.' ] : + for arch in [ "i386" , "x86_64" , "ia64" , "ppc64", "ppc32", "ppc", "x86" , "s390x", "s390" , "386" , "amd" ]: + name = name.replace("%s%s" % ( separator , arch ),"") + + return name + + def get_proposed_arch(self,dirname): + """ + Given an directory name, can we infer an architecture from a path segment? + """ + if dirname.find("x86_64") != -1 or dirname.find("amd") != -1: + return "x86_64" + if dirname.find("ia64") != -1: + return "ia64" + if dirname.find("i386") != -1 or dirname.find("386") != -1 or dirname.find("x86") != -1: + return "i386" + if dirname.find("s390x") != -1: + return "s390x" + if dirname.find("s390") != -1: + return "s390" + if dirname.find("ppc64") != -1 or dirname.find("chrp") != -1: + return "ppc64" + if dirname.find("ppc32") != -1: + return "ppc" + if dirname.find("ppc") != -1: + return "ppc" + return None + + def arch_walker(self,foo,dirname,fnames): + """ + See docs on learn_arch_from_tree. + + The TRY_LIST is used to speed up search, and should be dropped for default importer + Searched kernel names are kernel-header, linux-headers-, kernel-largesmp, kernel-hugemem + + This method is useful to get the archs, but also to package type and a raw guess of the breed + """ + + # try to find a kernel header RPM and then look at it's arch. + for x in fnames: + if self.match_kernelarch_file(x): + for arch in self.get_valid_arches(): + if x.find(arch) != -1: + foo[arch] = 1 + for arch in [ "i686" , "amd64" ]: + if x.find(arch) != -1: + foo[arch] = 1 + + def kickstart_finder(self,distros_added): + """ + For all of the profiles in the config w/o a kickstart, use the + given kickstart file, or look at the kernel path, from that, + see if we can guess the distro, and if we can, assign a kickstart + if one is available for it. + """ + for profile in self.profiles: + distro = self.distros.find(name=profile.get_conceptual_parent().name) + if distro is None or not (distro in distros_added): + continue + + kdir = os.path.dirname(distro.kernel) + if self.kickstart_file == None: + for rpm in self.get_release_files(): + results = self.scan_pkg_filename(rpm) + # FIXME : If os is not found on tree but set with CLI, no kickstart is searched + if results is None: + self.logger.warning("No version found on imported tree") + continue + (flavor, major, minor) = results + version , ks = self.set_variance(flavor, major, minor, distro.arch) + if self.os_version: + if self.os_version != version: + utils.die(self.logger,"CLI version differs from tree : %s vs. %s" % (self.os_version,version)) + ds = self.get_datestamp() + distro.set_comment("%s.%s" % (version, int(minor))) + distro.set_os_version(version) + if ds is not None: + distro.set_tree_build_time(ds) + profile.set_kickstart(ks) + self.profiles.add(profile,save=True) + + self.configure_tree_location(distro) + self.distros.add(distro,save=True) # re-save + self.api.serialize() + + def configure_tree_location(self, distro): + """ + Once a distribution is identified, find the part of the distribution + that has the URL in it that we want to use for kickstarting the + distribution, and create a ksmeta variable $tree that contains this. + """ + + base = self.get_rootdir() + + if self.network_root is None: + dest_link = os.path.join(self.settings.webdir, "links", distro.name) + # create the links directory only if we are mirroring because with + # SELinux Apache can't symlink to NFS (without some doing) + if not os.path.exists(dest_link): + try: + os.symlink(base + "-" + distro.arch, dest_link) + except: + # this shouldn't happen but I've seen it ... debug ... + self.logger.warning("symlink creation failed: %(base)s, %(dest)s") % { "base" : base, "dest" : dest_link } + # how we set the tree depends on whether an explicit network_root was specified + tree = "http://@@http_server@@/cblr/links/%s" % (distro.name) + self.set_install_tree( distro, tree) + else: + # where we assign the kickstart source is relative to our current directory + # and the input start directory in the crawl. We find the path segments + # between and tack them on the network source path to find the explicit + # network path to the distro that Anaconda can digest. + tail = utils.path_tail(self.path, base) + tree = self.network_root[:-1] + tail + self.set_install_tree( distro, tree) + + def get_rootdir(self): + return self.rootdir + + def get_pkgdir(self): + if not self.pkgdir: + return None + return os.path.join(self.get_rootdir(),self.pkgdir) + + def set_install_tree(self, distro, url): + distro.ks_meta["tree"] = url + + def learn_arch_from_tree(self): + """ + If a distribution is imported from DVD, there is a good chance the path doesn't + contain the arch and we should add it back in so that it's part of the + meaningful name ... so this code helps figure out the arch name. This is important + for producing predictable distro names (and profile names) from differing import sources + """ + result = {} + # FIXME : this is called only once, should not be a walk + if self.get_pkgdir(): + os.path.walk(self.get_pkgdir(), self.arch_walker, result) + if result.pop("amd64",False): + result["x86_64"] = 1 + if result.pop("i686",False): + result["i386"] = 1 + return result.keys() + + def match_kernelarch_file(self, filename): + """ + Is the given filename a kernel filename? + """ + + if not filename.endswith("rpm") and not filename.endswith("deb"): + return False + for match in ["kernel-header", "kernel-source", "kernel-smp", "kernel-default", "kernel-desktop", "linux-headers-", "kernel-devel", "kernel-"]: + if filename.find(match) != -1: + return True + return False + + def scan_pkg_filename(self, rpm): + """ + Determine what the distro is based on the release package filename. + """ + + rpm = os.path.basename(rpm) + + return ("suse", 1, 1) + + def get_datestamp(self): + """ + Based on a RedHat tree find the creation timestamp + """ + base = self.get_rootdir() + if os.path.exists("%s/.discinfo" % base): + discinfo = open("%s/.discinfo" % base, "r") + datestamp = discinfo.read().split("\n")[0] + discinfo.close() + else: + return 0 + return float(datestamp) + + def set_variance(self, flavor, major, minor, arch): + """ + find the profile kickstart and set the distro breed/os-version based on what + we can find out from the rpm filenames and then return the kickstart + path to use. + """ + + os_version = "suse" + + kickbase = "/var/lib/cobbler/kickstarts" + return os_version, "autoyast_sample.xml" + +# ========================================================================== + +def get_import_manager(config,logger): + return ImportSuseManager(config,logger) diff --git a/kickstarts/autoyast_sample.xml b/kickstarts/autoyast_sample.xml new file mode 100644 index 0000000..728aaa3 --- /dev/null +++ b/kickstarts/autoyast_sample.xml @@ -0,0 +1,45 @@ +<!-- + + Copyright (c) 2011 Novell + Uwe Gansert u...@suse.de + + This software is licensed to you under the GNU General Public License, + version 2 (GPLv2). There is NO WARRANTY for this software, express or + implied, including the implied warranties of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + along with this software; if not, see + http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + +--> +<?xml version="1.0"?> +<!DOCTYPE profile> +<profile xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.suse.com/1.0/configns"> + <networking> + <keep_install_network config:type="boolean">true</keep_install_network> + </networking> + <software> + <patterns config:type="list"> + <pattern>base</pattern> + </patterns> + </software> + <users config:type="list"> + <user> + <encrypted config:type="boolean">false</encrypted> + <fullname>root</fullname> + <gid>0</gid> + <home>/root</home> + <password_settings> + <expire></expire> + <flag></flag> + <inact></inact> + <max></max> + <min></min> + <warn></warn> + </password_settings> + <shell>/bin/bash</shell> + <uid>0</uid> + <user_password>s3cr3t</user_password> + <username>root</username> + </user> + </users> +</profile> -- 1.7.3.4
_______________________________________________ Spacewalk-devel mailing list Spacewalk-devel@redhat.com https://www.redhat.com/mailman/listinfo/spacewalk-devel