summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@redhat.com>2006-04-06 18:40:55 -0400
committerJim Meyering <jim@meyering.net>2006-04-06 18:40:55 -0400
commit828103b6c8fb975c4ec85e6b30ec3de12d37b8fc (patch)
tree63f0f24c9763666f60c243838856ad7eddc7197d
parentecdf6cbd431de42756f3928b883854d36367b634 (diff)
downloadthird_party-cobbler-828103b6c8fb975c4ec85e6b30ec3de12d37b8fc.tar.gz
third_party-cobbler-828103b6c8fb975c4ec85e6b30ec3de12d37b8fc.tar.xz
third_party-cobbler-828103b6c8fb975c4ec85e6b30ec3de12d37b8fc.zip
Misc 'TODO' items. This build has been tested somewhat but needs more. Man page now reflects new capabilities and optional parameters, including per-group, per-system, and per-distro kernel parameter customization.
-rw-r--r--Makefile3
-rw-r--r--TODO13
-rw-r--r--api.py41
-rwxr-xr-xbootconf8
-rw-r--r--bootconf.pod45
-rw-r--r--check.py2
-rw-r--r--config.py10
-rw-r--r--sync.py12
8 files changed, 94 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 4e6e435..7533c04 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,9 @@ all: manpage
manpage:
pod2man bootconf.pod > bootconf.1
+ -(\rm bootconf.1.gz)
gzip bootconf.1
- cp bootconf.1.gz /usr/share/man/man1
+ cp -f bootconf.1.gz /usr/share/man/man1
install:
echo "(install not implemented)"
diff --git a/TODO b/TODO
index 4951185..1dd7e4d 100644
--- a/TODO
+++ b/TODO
@@ -11,22 +11,25 @@ T - Optional kernel parameter input to replace defaults
resolved to give precendence to system, then group, then
distro, then defaults.
PARTIAL: input allowed and serialized but *NOT USED YET*
- - dlutter mentions directories for kernels might not resolve
- to full paths. Check into this and fix.
NICE TO HAVE
T - Move program writeable section of config to /var
to conform with FS rules
- - Make list show resolved values as currently set
+D - Make list show resolved values as currently set
for things like initrd, kernel, kickstart
rather than just the directories or partial filenames.
- Try pulling the kernel and initrd from the kickstart information?
+RANDOM IDEAS
+
+ - Support pxelinux's default directory
+ - Subnet creation shorthand
LEGEND
-T = DONE? BEING TESTED
-D = DONE
+T = DONE. SOME TESTING STILL TBA.
+D = DONE. LOOKS FINE.
P = PARTIAL
I = IN PROGRESS
+
diff --git a/api.py b/api.py
index 20d5a6b..f0c2a5a 100644
--- a/api.py
+++ b/api.py
@@ -22,7 +22,7 @@ class BootAPI:
self.utils = util.BootUtil(self,self.config)
# if the file already exists, load real data now
try:
- if not self.config.files_exist():
+ if self.config.files_exist():
self.config.deserialize()
except:
# traceback.print_exc()
@@ -30,7 +30,7 @@ class BootAPI:
try:
self.config.serialize()
except:
- # traceback.print_exc()
+ traceback.print_exc()
pass
if not self.config.files_exist():
self.config.serialize()
@@ -141,10 +141,9 @@ class Collection:
"""
def __str__(self):
buf = ""
- values = sorted(self.listing.values())
+ values = map(lambda(a): str(a), sorted(self.listing.values()))
if len(values) > 0:
- for v in values: buf = buf + str(v) + "\n"
- return buf
+ return "\n\n".join(values)
else:
return m("empty_list")
@@ -253,6 +252,7 @@ class Item:
def set_kernel_options(self,options_string):
self.kernel_options = options_string
+ return True
def to_datastruct(self):
raise "not implemented"
@@ -304,7 +304,22 @@ class Distro(Item):
}
def __str__(self):
- return "%s : kernel=%s | initrd=%s | opts=%s" % (self.name,self.kernel,self.initrd,self.kernel_options)
+ kstr = self.api.utils.find_kernel(self.kernel)
+ istr = self.api.utils.find_initrd(self.initrd)
+ if kstr is None:
+ kstr = "%s (NOT FOUND!)" % self.kernel
+ elif os.path.isdir(self.kernel):
+ kstr = "%s (FOUND BY SEARCH)" % kstr
+ if istr is None:
+ istr = "%s (NOT FOUND)" % self.initrd
+ elif os.path.isdir(self.initrd):
+ istr = "%s (FOUND BY SEARCH)" % istr
+ buf = ""
+ buf = buf + "distro : %s\n" % self.name
+ buf = buf + "kernel : %s\n" % kstr
+ buf = buf + "initrd : %s\n" % istr
+ buf = buf + "kernel opts : %s" % self.kernel_options
+ return buf
#---------------------------------------------
@@ -351,7 +366,12 @@ class Group(Item):
}
def __str__(self):
- return "%s : distro=%s | kickstart=%s | opts=%s" % (self.name, self.distro, self.kickstart, self.kernel_options)
+ buf = ""
+ buf = buf + "group : %s\n" % self.name
+ buf = buf + "distro : %s\n" % self.distro
+ buf = buf + "kickstart : %s\n" % self.kickstart
+ buf = buf + "kernel opts : %s" % self.kernel_options
+ return buf
#---------------------------------------------
@@ -402,6 +422,9 @@ class System(Item):
}
def __str__(self):
- return "%s : group=%s | opts=%s" % (self.name,self.group,self.kernel_options)
-
+ buf = ""
+ buf = buf + "system : %s\n" % self.name
+ buf = buf + "group : %s\n" % self.group
+ buf = buf + "kernel opts : %s" % self.kernel_options
+ return buf
diff --git a/bootconf b/bootconf
index 3a6865a..2a77dc0 100755
--- a/bootconf
+++ b/bootconf
@@ -137,7 +137,7 @@ class BootCLI:
commands = {
'--name' : lambda(a) : sys.set_name(a),
'--group' : lambda(a) : sys.set_group(a),
- '--kopts' : lambda(a) : sys.set_kernel_opts(a)
+ '--kopts' : lambda(a) : sys.set_kernel_options(a)
}
on_ok = lambda: self.api.get_systems().add(sys)
return self.apply_args(args,commands,on_ok,True)
@@ -151,7 +151,7 @@ class BootCLI:
'--name' : lambda(a) : group.set_name(a),
'--distro' : lambda(a) : group.set_distro(a),
'--kickstart' : lambda(a) : group.set_kickstart(a),
- '--kopts' : lambda(a) : group.set_kernel_opts(a)
+ '--kopts' : lambda(a) : group.set_kernel_options(a)
}
on_ok = lambda: self.api.get_groups().add(group)
return self.apply_args(args,commands,on_ok,True)
@@ -165,7 +165,7 @@ class BootCLI:
'--name' : lambda(a) : distro.set_name(a),
'--kernel' : lambda(a) : distro.set_kernel(a),
'--initrd' : lambda(a) : distro.set_initrd(a),
- '--kopts' : lambda(a) : distro.set_kopts(a)
+ '--kopts' : lambda(a) : distro.set_kernel_options(a)
}
on_ok = lambda: self.api.get_distros().add(distro)
return self.apply_args(args,commands,on_ok,True)
@@ -180,7 +180,7 @@ class BootCLI:
return False
for x in args:
try:
- key, value = x.split("=")
+ key, value = x.split("=",1)
value = value.replace('"','').replace("'",'')
except:
print m("bad_arg") % x
diff --git a/bootconf.pod b/bootconf.pod
index c4251af..f2d41c1 100644
--- a/bootconf.pod
+++ b/bootconf.pod
@@ -8,7 +8,7 @@ bootconf command [subcommand] [--arg1=] [--arg2=]
=head1 DESCRIPTION
-Configuration of a boot server involves a lot of things. Perhaps too many. These items include a tftpd server, a dhcpd server, syslinux, and a lot of copying files around and creating other config files. Bootconf makes these things simpler.
+Configuration of a boot server involves a lot of things. Perhaps too many. These items include a tftpd server, a dhcpd server, syslinux, and a lot of copying files around and creating other config files. Bootconf makes these things simpler and more flexible.
bootconf requires root access.
@@ -17,9 +17,8 @@ bootconf requires root access.
B<before you start...>
First install dhcpd, tftpd, and syslinux.
-You'll also need FTP, HTTP, or NFS to serve kickstarts (if you want them)
-And you'll also have to edit dhcpd.conf for your particular DHCP environment.
-Yes, DHCP is a required piece.
+You'll also need FTP, HTTP, or NFS to serve kickstarts (if you want kickstarts).Finally, you'll also have to edit dhcpd.conf for your particular DHCP environment.
+
yum install dhcp tftp-server syslinux
...
@@ -27,24 +26,24 @@ Yes, DHCP is a required piece.
B<bootconf check>
-This verifies that everything you need to set up is set up.
+This verifies that everything you need to set up is properly set up.
This will mention any missing services and obvious configuration errors.
-Errors? Correct any problems reported, then run check until there are none.
+Correct any problems reported, then run check until there are none.
-Do not forget to look at /etc/bootconf.conf and modify all parameters to your liking. Of particular note: The kernel_opts field is the default kernel options list for all netbooting systems. It can be overriden by distro, group, or system specific settings.
+Of particular note: The kernel_opts field in /etc/bootconf.conf is the default kernel options list for all netbooting systems. It can be overriden by distro, group, or system specific settings, though the defaults are probably good enough for most administrators.
B<bootconf distro add --name=distro_name --kernel=path --initrd=path [--kopts="string"]>
Defines a distribution as a matched pair of a kernel and an initrd, and
-gives it a name. This could be 'fc5-i386' or 'foosball-73', it's your name. Kernel options are inherited from the kernel_opts parameter in /etc/bootconf.conf, though you can override them.
+gives it a name. This could be 'fc5-i386' or 'foosball_rocks', it's your name. Kernel options are inherited from the kernel_opts parameter in /etc/bootconf.conf, though you can override some or all of them.
B<bootconf group add --name=group_name --distro=distro_name [--kickstart=url] [--kopts="string"]>
-Defines a provisioning group, which is a distro (you did define a distro, right?) and optionally a kickstart. Kickstarts are served up by URLs, so these need to be HTTP, NFS, or FTP URLs that point to a kickstart file. Kernel options are inherited from the distro, but you can optionally override them. If you don't want a kickstart, that's fine.
+Defines a provisioning group, which is a distro (you did define a distro, right?) and optionally a kickstart. Kickstarts are served up by URLs, so these need to be HTTP, NFS, or FTP URLs that point to a kickstart file. If you don't want a kickstart, leave that parameter out. Kernel options are inherited from the distro, but you can optionally override some or all of them.
B<bootconf system add --name=ip|mac|hostname --group=group_name [--kopts="string"]>
-Defines a system. A system can't have a free form name, it has to be a hostname that resolves to an IP, a MAC address, or an actual IP. The group parameter is the group name you used with "group add". Kernel options are inherited from the group, you probably don't want to override them, but you can.
+Defines a system, which is a representation of any netbootable system. A system can't have a free form name, it has to be a hostname that resolves to an IP, a MAC address, or an actual IP. Partial IP's (as in whole subnets) may be supported later. The group parameter is the group name you used with "group add", that is, what group the system belongs to. Kernel options are inherited from the group, and you probably don't want to override them, but you can override some or all of them.
B<bootconf distro list>
@@ -76,6 +75,32 @@ Applies the stored configuration to the system. If you have any configuration e
Usage of the dryrun option will show you the pending changes without actually making them.
+=head1 EXAMPLE
+
+B<bootconf check>
+
+B<bootconf distro add --name=rhel4u3 --kernel=/dir1/vmlinuz --initrd=/dir1/initrd.img>
+
+B<bootconf distro add --name=fc5 --kernel=/dir2/vmlinuz --initrd=/dir2/initrd.img>
+
+B<bootconf distro list>
+
+B<bootconf group add --name=fc5webservers --distro=fc5-i386 --kickstart=http://192.168.1.10/blah/fc5-webservers.ks --kopts="customization=blah">
+
+B<bootconf group add --name=rhel4u3dbservers --distro=rhel4u3 --kickstart=http://192.168.1.10/blah/rhel4u3-dbservers.ks>
+
+B<bootconf group list>
+
+B<bootconf system add --name=AA:BB:CC:DD:EE:FF --group=fc5-webservers>
+
+B<bootconf system add --name=AA:BB:CC:DD:EE:FE --group=rhel4u3-dbservers>
+
+B<bootconf system list>
+
+B<bootconf sync --dryrun>
+
+B<bootconf sync>
+
=head1 CONFIGURATION_FILES
bootconf uses /etc/bootconf.conf to store basic settings and /var/bootconf/bootconf.conf for it's internal state.
diff --git a/check.py b/check.py
index 8a156fc..18fe178 100644
--- a/check.py
+++ b/check.py
@@ -102,7 +102,5 @@ class BootCheck:
status.append(m("no_line") % (self.config.dhcpd_conf, 'filename "%s/pxelinux.0";' % self.config.tftpboot))
else:
status.append(m("no_exist") % self.config.dhcpd_conf)
- if not os.path.exists(self.config.kernel_root):
- status.append(m("no_dir2") % (self.config.kernel_root, 'kernel_root'))
diff --git a/config.py b/config.py
index 163c588..cf93214 100644
--- a/config.py
+++ b/config.py
@@ -42,7 +42,6 @@ class BootConfig:
Set some reasonable defaults in case no values are available
"""
def set_defaults(self):
- self.kernel_root = "/var/www/bootconf"
self.tftpboot = "/tftpboot"
self.dhcpd_conf = "/etc/dhcpd.conf"
self.tftpd_conf = "/etc/xinetd.d/tftp"
@@ -77,7 +76,6 @@ class BootConfig:
# idea: add list of properties to self.properties
# and use method_missing to write accessors???
data = {}
- data['kernel_root'] = self.kernel_root
data['tftpboot'] = self.tftpboot
data['dhcpd_conf'] = self.dhcpd_conf
data['tftpd_conf'] = self.tftpd_conf
@@ -91,7 +89,6 @@ class BootConfig:
"""
def config_from_hash(self,hash):
try:
- self.kernel_root = hash['kernel_root']
self.tftpboot = hash['tftpboot']
self.dhcpd_conf = hash['dhcpd_conf']
self.tftpd_conf = hash['tftpd_conf']
@@ -113,6 +110,7 @@ class BootConfig:
world['distros'] = self.get_distros().to_datastruct()
world['groups'] = self.get_groups().to_datastruct()
world['systems'] = self.get_systems().to_datastruct()
+ #print "DEBUG: %s" % (world)
return world
@@ -121,6 +119,7 @@ class BootConfig:
There are seperate hashes for the /etc and /var portions.
"""
def from_hash(self,hash,is_etc):
+ #print "DEBUG: %s" % hash
if is_etc:
self.config_from_hash(hash['config'])
else:
@@ -171,6 +170,7 @@ class BootConfig:
could use YAML later if we wanted.
"""
def deserialize(self):
+ #print "DEBUG: deserialize"
# -----
# load global config (pathing, urls, etc)...
@@ -179,6 +179,8 @@ class BootConfig:
raw_data = settings.next()
if raw_data is not None:
self.from_hash(raw_data,True)
+ else:
+ print "WARNING: no %s data?" % self.settings_file
except:
self.api.last_error = m("parse_error")
return False
@@ -190,6 +192,8 @@ class BootConfig:
raw_data = state.next()
if raw_data is not None:
self.from_hash(raw_data,False)
+ else:
+ print "WARNING: no %s data?" % self.state_file
except:
self.api.last_error = m("parse_error")
return False
diff --git a/sync.py b/sync.py
index 024b6dd..6ad9eb9 100644
--- a/sync.py
+++ b/sync.py
@@ -101,8 +101,8 @@ class BootSync:
# it's up to the user to make sure they are nicely served by their URLs
for g in self.api.get_groups().contents():
kickstart_path = self.api.utils.find_kickstart(g.kickstart)
- if kickstart_path is None or not os.path.isfile(kickstart_path):
- self.api.last_error = "Kickstart for group (%s) cannot be found and needs to be fixed: %s" % (g.name, g.kickstart)
+ if kickstart_path is None:
+ self.api.last_error = "Kickstart for group (%s) is not valid and needs to be fixed: %s" % (g.name, g.kickstart)
raise "error"
"""
@@ -176,7 +176,7 @@ class BootSync:
distro.kernel_options,
system.kernel_options
))
- nextline = " append %s initrd=%s" % (kopts,initrd_path)
+ nextline = " append %s initrd=%s" % (kopts,initrd_path)
if kickstart_path is not None and kickstart_path != "":
nextline = nextline + " ks=%s" % kickstart_path
self.tee(file, nextline)
@@ -246,7 +246,7 @@ class BootSync:
tokens=items.split(" ")
# deal with key/value pairs and single options alike
for token in tokens:
- key_value = tokens.split("=")
+ key_value = token.split("=")
if len(key_value) == 1:
internal[key_value[0]] = ""
else:
@@ -257,11 +257,11 @@ class BootSync:
data = internal[key]
if key == "ks" or key == "initrd" or key == "append":
# the user REALLY doesn't want to do this...
- next
+ continue
if data == "":
results.append(key)
else:
results.append("%s=%s" % (key,internal[key]))
# end result is a new fragment of a kernel options string
- return results.join(" ")
+ return " ".join(results)