Hi,
I've started to work in order to allow debian provisioning with
cobbler. I send attached two patches.
The first on is actually not strictly related to debian, and it's a
reorganization of the archs management,
to simplify it and ease smooth addition of other distros: debian calls
amd64 to x86_64, and the idea is
to keep the RedHat names as canonical ones.
The second one does actually allow to import the content of a debian
CD/DVD and create the corresponding
distro. It also creates the profile breeded as debian, although it
might not be usable yet.
There are a couple of open questions that might affect other parts of
cobbler or where just ideas are required.
- the kickstarts for debian. They are called "preseed", and are by far
much more complex than a standard
kickstart. Although not strictly required, it might be better to
have new names for both ks files and directories,
but I think that they can be easyly added to PXE boot options. To
make things worst, ubuntu does allow both
the standard debian preseed and kickstart files.
- the package repositories. Debian follows a quite different approach,
and a single tree can hold many versions
and different architectures. Allowing a cobbler distro to have
multiple architectures might reduce the disk usage
and simplify the repository updating. Due to this fact, a single
debian media can install multiple archs, complexing
a little bit to import the media.
These are the only two points I see on the close horizon, but there
are probably more. It anyone has concerns
or ideas, they are welcome. And if anyone can actually test the
deployment (when it matures a little bit), much better.
Javier Palacios
diff --git a/cobbler/action_import.py b/cobbler/action_import.py
index 9bb84d0..b1ce371 100644
--- a/cobbler/action_import.py
+++ b/cobbler/action_import.py
@@ -78,11 +78,10 @@ class Importer:
raise CX(_("import failed. no --name specified"))
if self.arch is not None:
self.arch = self.arch.lower()
- if self.arch not in [ "i386", "x86", "ia64", "x86_64", "s390x" ]:
- raise CX(_("arch must be x86, x86_64, s390x, or ia64"))
- if self.arch == "x86":
- # be consistent
- self.arch = "i386"
+ if self.arch in utils.archmaps.keys():
+ self.arch = utils.archmaps[self.arch]
+ if self.arch not in utils.validarchs:
+ raise CX(_("arch must be one of %s") % ",
".join(utils.validarchs))
mpath = os.path.join(self.settings.webdir, "ks_mirror",
self.mirror_name)
@@ -92,16 +91,11 @@ class Importer:
if self.arch:
# append the arch path to the name if the arch is not already
# found in the name.
- found = False
- for x in [ "ia64", "i386", "x86_64", "x86", "s390x" ]:
+ for x in utils.validarchs:
if self.mirror_name.lower().find(x) != -1:
- found = True
break
- if not found:
+ else:
self.mirror_name = self.mirror_name + "-" + self.arch
-
- if self.mirror_name is None:
- raise CX(_("import failed. no --name specified"))
# make the output path and mirror content but only if not specifying
that a network
# accessible support location already exists
@@ -537,9 +531,6 @@ class Importer:
def get_proposed_name(self,dirname,pxe_arch):
archname = pxe_arch
- if archname == "x86":
- # be consistent
- archname = "i386"
# FIXME: this is new, needs testing ...
if self.network_root is not None:
name = "-".join(self.path_tail(self.path,dirname).split("/"))
@@ -556,16 +547,9 @@ class Importer:
name = name.replace("ks_mirror-","")
name = name.replace("-pxeboot","")
name = name.replace("--","-")
- name = name.replace("-i386","")
- name = name.replace("_i386","")
- name = name.replace("-x86_64","")
- name = name.replace("_x86_64","")
- name = name.replace("-ia64","")
- name = name.replace("_ia64","")
- name = name.replace("-x86","")
- name = name.replace("_x86","")
- name = name.replace("-s390x","")
- name = name.replace("_s390x","")
+ for separator in [ '-' , '_' ] :
+ for arch in utils.validarchs:
+ name = name.replace("%s%s" % ( separator , arch ),"")
# ensure arch is on the end, regardless of path used.
name = name + "-" + archname
@@ -591,18 +575,14 @@ class Importer:
continue
if x.find("kernel-header") != -1:
print _("- kernel header found: %s") % x
- if x.find("i386") != -1:
- foo["result"] = "i386"
- return
- elif x.find("x86_64") != -1:
- foo["result"] = "x86_64"
- return
- elif x.find("ia64") != -1:
- foo["result"] = "ia64"
- return
- elif x.find("s390") != -1:
- foo["result"] = "s390x"
- return
+ for arch in utils.validarchs:
+ if x.find(arch) != -1:
+ foo["result"] = arch
+ return
+ for arch in utils.archmaps.keys():
+ if x.find(arch) != -1:
+ foo["result"] = utils.archmaps[arch]
+ return
# This extra code block is a temporary fix for rhel4.x 64bit [x86_64]
# distro ARCH identification-- L.M.
@@ -612,18 +592,14 @@ class Importer:
continue
if x.find("kernel-largesmp") != -1:
print _("- kernel header found: %s") % x
- if x.find("i386") != -1:
- foo["result"] = "i386"
- return
- elif x.find("x86_64") != -1:
- foo["result"] = "x86_64"
- return
- elif x.find("ia64") != -1:
- foo["result"] = "ia64"
- return
- elif x.find("s390") != -1:
- foo["result"] = "s390x"
- return
+ for arch in utils.validarchs:
+ if x.find(arch) != -1:
+ foo["result"] = arch
+ return
+ for arch in utils.archmaps.keys():
+ if x.find(arch) != -1:
+ foo["result"] = utils.archmaps[arch]
+ return
def learn_arch_from_tree(self,dirname):
"""
@@ -640,13 +616,11 @@ class Importer:
def get_pxe_arch(self,dirname):
t = dirname.lower()
- if t.find("x86_64") != -1:
- return "x86_64"
- if t.find("ia64") != -1:
- return "ia64"
- if t.find("i386") != -1 or t.find("386") != -1 or t.find("x86") != -1:
- return "i386"
- if t.find("s390") != -1:
- return "s390x"
+ for arch in utils.validarchs:
+ if t.find(arch) != -1:
+ return arch
+ for arch in utils.archmaps.keys():
+ if t.find(arch) != -1:
+ return utils.archmaps[arch]
return self.learn_arch_from_tree(dirname)
diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py
index ccd437b..0f62426 100644
--- a/cobbler/item_distro.py
+++ b/cobbler/item_distro.py
@@ -149,7 +149,7 @@ class Distro(item.Item):
This field is named "arch" because mainly on Linux, we only care about
the architecture, though if (in the future) new provisioning types
- are added, an arch value might be something like "bsd_x86".
+ are added, an arch value might be something like "bsd_i386".
Update: (7/2008) this is now used to build fake PXE trees for s390x
also
"""
diff --git a/cobbler/modules/cli_distro.py b/cobbler/modules/cli_distro.py
index 793b025..11a7c5c 100644
--- a/cobbler/modules/cli_distro.py
+++ b/cobbler/modules/cli_distro.py
@@ -46,7 +46,7 @@ class DistroFunction(commands.CobblerFunction):
def add_options(self, p, args):
if not self.matches_args(args,["dumpvars","remove","report","list"]):
- p.add_option("--arch", dest="arch", help="ex: x86, x86_64,
ia64")
+ p.add_option("--arch", dest="arch", help="ex: i386, x86_64,
ia64")
p.add_option("--breed", dest="breed", help="ex: redhat, debian,
suse")
if self.matches_args(args,["add"]):
p.add_option("--clobber", dest="clobber", help="allow add to
overwrite existing objects", action="store_true")
diff --git a/cobbler/pxegen.py b/cobbler/pxegen.py
index 7d12d95..80c6815 100644
--- a/cobbler/pxegen.py
+++ b/cobbler/pxegen.py
@@ -177,7 +177,7 @@ class PXEGen:
working_arch = distro.arch
if working_arch is None or working_arch == "":
- working_arch = "x86"
+ working_arch = "i386"
# for tftp only ...
if working_arch in [ "i386", "x86", "x86_64", "standard"]:
diff --git a/cobbler/utils.py b/cobbler/utils.py
index 758cfa2..77f671f 100644
--- a/cobbler/utils.py
+++ b/cobbler/utils.py
@@ -38,6 +38,9 @@ import signal
from cexceptions import *
import codes
+validarchs = [ "i386", "ia64", "x86_64", "s390x" ]
+archmaps = { "x86" : "i386" , "amd64" : "x86_68" }
+
CHEETAH_ERROR_DISCLAIMER="""
# There is a templating error preventing this file from rendering correctly.
#
diff --git a/cobbler/action_import.py b/cobbler/action_import.py
index 7672433..af228c6 100644
--- a/cobbler/action_import.py
+++ b/cobbler/action_import.py
@@ -37,6 +37,7 @@ WGET_CMD = "wget --mirror --no-parent --no-host-directories
--directory-prefix %
RSYNC_CMD = "rsync -a %s '%s' %s/ks_mirror/%s
--exclude-from=/etc/cobbler/rsync.exclude --progress"
TRY_LIST = [
+ "pool",
"Fedora", "Packages", "RedHat", "Client", "Server", "Centos", "CentOS",
"Fedora/RPMS", "RedHat/RPMS", "Client/RPMS", "Server/RPMS", "Centos/RPMS",
"CentOS/RPMS", "RPMS"
@@ -68,6 +69,7 @@ class Importer:
self.kickstart_file = kickstart_file
self.rsync_flags = rsync_flags
self.arch = arch
+ self.breed_guess = None
# ----------------------------------------------------------------------
@@ -79,7 +81,8 @@ class Importer:
if self.arch is not None:
self.arch = self.arch.lower()
if self.arch in utils.archmaps.keys():
- self.arch = utils.archmaps[self.arch]
+ if utils.archmaps[self.arch]:
+ self.arch = utils.archmaps[self.arch]
if self.arch not in utils.validarchs:
raise CX(_("arch must be one of %s") % ",
".join(utils.validarchs))
@@ -133,18 +136,17 @@ class Importer:
if not self.network_root.endswith("/"):
self.network_root = self.network_root + "/"
self.path = self.mirror
- found_root = False
valid_roots = [ "nfs://", "ftp://", "http://" ]
for valid_root in valid_roots:
if self.network_root.startswith(valid_root):
- found_root = True
+ break
+ else:
+ raise CX(_("Network root given to --available-as must be %s") %
", ".join(valid_roots))
if self.network_root.startswith("nfs://"):
try:
(a,b,rest) = self.network_root.split(":",3)
except:
raise CX(_("Network root given to --available-as is missing
a colon, please see the manpage example."))
- if not found_root:
- raise CX(_("Network root given to --available-as must be
nfs://, ftp://, or http://"))
self.processed_repos = {}
@@ -352,6 +354,10 @@ class Importer:
fullname = os.path.join(dirname,x)
if os.path.islink(fullname) and os.path.isdir(fullname):
+ if os.path.realpath(fullname) == os.path.realpath(dirname):
+ print _("- found self-refering link, probably debian based
distro")
+ self.breed_guess = "debian"
+ continue
print "- following symlink: %s" % fullname
os.path.walk(fullname, self.distro_adder, {})
@@ -504,6 +510,8 @@ class Importer:
distro.set_kernel(kernel)
distro.set_initrd(initrd)
distro.set_arch(pxe_arch)
+ if self.breed_guess :
+ distro.set_breed(self.breed_guess)
distro.source_repos = []
self.distros.add(distro,save=True)
self.distros_added.append(distro)
@@ -547,9 +555,12 @@ class Importer:
name = name.replace("ks_mirror-","")
name = name.replace("-pxeboot","")
name = name.replace("--","-")
- for separator in [ '-' , '_' ] :
+ for separator in [ '-' , '_' , '.' ] :
for arch in utils.validarchs:
name = name.replace("%s%s" % ( separator , arch ),"")
+ for separator in [ '-' , '_' , '.' ] :
+ for arch in utils.archmaps.keys():
+ name = name.replace("%s%s" % ( separator , arch ),"")
# ensure arch is on the end, regardless of path used.
name = name + "-" + archname
@@ -561,17 +572,15 @@ class Importer:
"""
# don't care about certain directories
- match = False
for x in TRY_LIST:
if dirname.find(x) != -1:
- match = True
- continue
- if not match:
+ break
+ else:
return
# try to find a kernel header RPM and then look at it's arch.
for x in fnames:
- if not x.endswith("rpm"):
+ if not x.endswith("rpm") and not x.endswith("deb"):
continue
if x.find("kernel-header") != -1:
print _("- kernel header found: %s") % x
@@ -580,15 +589,16 @@ class Importer:
foo["result"] = arch
return
for arch in utils.archmaps.keys():
- if x.find(arch) != -1:
- foo["result"] = utils.archmaps[arch]
- return
+ if utils.archmaps[arch]:
+ if x.find(arch) != -1:
+ foo["result"] = utils.archmaps[arch]
+ return
# This extra code block is a temporary fix for rhel4.x 64bit [x86_64]
# distro ARCH identification-- L.M.
# NOTE: eventually refactor to merge in with the above block
for x in fnames:
- if not x.endswith("rpm"):
+ if not x.endswith("rpm") and not x.endswith("deb"):
continue
if x.find("kernel-largesmp") != -1:
print _("- kernel header found: %s") % x
@@ -597,9 +607,10 @@ class Importer:
foo["result"] = arch
return
for arch in utils.archmaps.keys():
- if x.find(arch) != -1:
- foo["result"] = utils.archmaps[arch]
- return
+ if utils.archmaps[arch]:
+ if x.find(arch) != -1:
+ foo["result"] = utils.archmaps[arch]
+ return
def learn_arch_from_tree(self,dirname):
"""
@@ -608,10 +619,11 @@ class Importer:
figure out the arch name. This is important for producing predictable
distro names (and profile names)
from differing import sources
"""
- dirname2 = "/".join(dirname.split("/")[:-2]) # up two from images,
then down as many as needed
- print _("- scanning %s for architecture info") % dirname2
+ # FIXME : Some special handling for network_root might be required as
in get_proposed_name,
+ rootdir = "/".join(dirname.split("/")[:6]) # up two from images, then
down as many as needed
+ print _("- scanning %s for architecture info") % rootdir
result = { "result" : "i386" } # default, but possibly not correct ...
- os.path.walk(dirname2, self.arch_walker, result)
+ os.path.walk(rootdir, self.arch_walker, result)
return result["result"]
def get_pxe_arch(self,dirname):
@@ -620,7 +632,8 @@ class Importer:
if t.find(arch) != -1:
return arch
for arch in utils.archmaps.keys():
- if t.find(arch) != -1:
- return utils.archmaps[arch]
+ if utils.archmaps[arch]:
+ if t.find(arch) != -1:
+ return utils.archmaps[arch]
return self.learn_arch_from_tree(dirname)
diff --git a/cobbler/utils.py b/cobbler/utils.py
index 77f671f..fdbad2e 100644
--- a/cobbler/utils.py
+++ b/cobbler/utils.py
@@ -39,7 +39,8 @@ from cexceptions import *
import codes
validarchs = [ "i386", "ia64", "x86_64", "s390x" ]
-archmaps = { "x86" : "i386" , "amd64" : "x86_68" }
+# NOTE : archs keys mapping to empty strings are used only while replacing on
filenames
+archmaps = { "x86" : "i386" , "amd64" : "x86_68" , "386" : "" }
CHEETAH_ERROR_DISCLAIMER="""
# There is a templating error preventing this file from rendering correctly.
_______________________________________________
cobbler mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/cobbler