summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api.py39
-rwxr-xr-xbootconf111
-rw-r--r--check.py88
-rw-r--r--msg.py110
-rw-r--r--sync.py14
-rw-r--r--test.py10
-rw-r--r--util.py79
7 files changed, 302 insertions, 149 deletions
diff --git a/api.py b/api.py
index 30793f2..e55cb4e 100644
--- a/api.py
+++ b/api.py
@@ -8,6 +8,8 @@ import traceback
import config
import util
import sync
+import check
+from msg import *
class BootAPI:
@@ -24,7 +26,7 @@ class BootAPI:
self.config.deserialize()
except:
# traceback.print_exc()
- util.warning("Could not parse config file, recreating")
+ util.warning(m("no_cfg"))
try:
self.config.serialize()
except:
@@ -83,7 +85,7 @@ class BootAPI:
See if all preqs for network booting are operational
"""
def check(self):
- return self.utils.check_install()
+ return check.BootCheck(self).run()
"""
Update the system with what is specified in the config file
@@ -132,10 +134,10 @@ class Collection:
"""
def add(self,ref):
if ref is None or not ref.is_valid():
- self.last_error = "Referenced parameter is not valid"
+ if self.api.last_error is None or self.api.last_error == "":
+ self.api.last_error = m("bad_param")
return False
self.listing[ref.name] = ref
- # removed auto serialization ... now the API must call it explicitly.
return True
"""
@@ -148,7 +150,7 @@ class Collection:
for v in values: buf = buf + str(v) + "\n"
return buf
else:
- return "(Empty)"
+ return m("empty_list")
def contents(self):
return self.listing.values()
@@ -174,12 +176,12 @@ class Distros(Collection):
# first see if any Groups use this distro
for k,v in self.api.config.groups.listing.items():
if v.distro == name:
- self.last_error = "Cannot delete, this distro is referenced by a group"
+ self.api.last_error = m("orphan_group")
return False
if name in self.listing:
del self.listing[name]
return True
- self.last_error = "Cannot delete a distro that does not exist"
+ self.api.last_error = m("delete_nothing")
return False
@@ -204,12 +206,12 @@ class Groups(Collection):
def remove(self,name):
for k,v in self.api.config.systems.listing.items():
if v.group == name:
- self.last_error = "Cannot delete, this group is referenced by a system"
+ self.api.last_error = m("orphan_system")
return False
if name in self.listing:
del self.listing[name]
return True
- self.last_error = "Cannot delete a group that does not exist"
+ self.api.last_error = m("delete_nothing")
return False
@@ -234,7 +236,7 @@ class Systems(Collection):
if name in self.listing:
del self.listing[name]
return True
- self.last_error = "Cannot delete a system that does not exist"
+ self.api.last_error = m("delete_nothing")
return False
@@ -273,12 +275,14 @@ class Distro(Item):
if self.api.utils.find_kernel(kernel):
self.kernel = kernel
return True
+ self.api.last_error = m("no_kernel")
return False
def set_initrd(self,initrd):
if self.api.utils.find_initrd(initrd):
self.initrd = initrd
return True
+ self.api.last_error = m("no_initrd")
return False
def is_valid(self):
@@ -314,19 +318,20 @@ class Group(Item):
if self.api.get_distros().find(distro_name):
self.distro = distro_name
return True
- self.last_error = "Specified distro doesn't exist"
+ self.last_error = m("no_distro")
return False
def set_kickstart(self,kickstart):
if self.api.utils.find_kickstart(kickstart):
self.kickstart = kickstart
return True
- self.last_error = "Specified kickstart doesn't exist"
+ self.last_error = m("no_kickstart")
return False
def is_valid(self):
for x in (self.name, self.distro, self.kickstart):
- if x is None: return False
+ if x is None:
+ return False
return True
def to_ds(self):
@@ -359,6 +364,7 @@ class System(Item):
def set_name(self,name):
new_name = self.api.utils.find_system_identifier(name)
if new_name is None or new_name == False:
+ self.api.last_error = m("bad_sys_name")
return False
self.name = name # we check it add time, but store the original value.
return True
@@ -370,8 +376,11 @@ class System(Item):
return False
def is_valid(self):
- for x in (self.name, self.group):
- if x is None: return False
+ if self.name is None:
+ self.api.last_error = m("bad_sys_name")
+ return False
+ if self.group is None:
+ return False
return True
def to_ds(self):
diff --git a/bootconf b/bootconf
index 1b7c887..ef79c3a 100755
--- a/bootconf
+++ b/bootconf
@@ -14,6 +14,7 @@ import traceback
import api
import util
+from msg import *
class BootCLI:
@@ -60,20 +61,24 @@ class BootCLI:
Run the command line
"""
def run(self):
- return self.curry_args(self.args[1:], self.toplevel_commands)
+ rc = self.curry_args(self.args[1:], self.toplevel_commands)
+ if not rc:
+ self.api.show_error()
+ return rc
+
"""
Print out abbreviated help if user gives bad syntax
"""
def usage(self):
- print "for help, run 'bootconf help'"
+ print m("usage")
return False
"""
Print out tediously wrong help: 'bootconf help'
"""
def help(self,args):
- print open("help.txt").read()
+ print m("help")
return False
"""
@@ -102,13 +107,8 @@ class BootCLI:
commands = {
'--name' : lambda(a): sys.set_name(a)
}
- results = {
- True : lambda: self.api.get_systems().remove(sys),
- False : lambda: self.api.show_error()
- }
- rc = self.apply_args(args,commands,results)
- if rc: self.api.serialize()
- return rc
+ on_ok = lambda: self.api.get_systems().remove(sys)
+ return self.apply_args(args,commands,on_ok,True)
"""
Delete a group: 'bootconf group remove --name=foo'
@@ -118,13 +118,8 @@ class BootCLI:
commands = {
'--name' : lambda(a): group.set_name(a)
}
- results = {
- True : lambda: self.api.get_groups().remove(group),
- False : lambda: self.api.show_error()
- }
- rc = self.apply_args(args,commands,results)
- if rc: self.api.serialize()
- return rc
+ on_ok = lambda: self.api.get_groups.remove(group)
+ return self.apply_args(args,commands,on_ok,True)
"""
Delete a distro: 'bootconf distro remove --name='foo'
@@ -132,15 +127,10 @@ class BootCLI:
def distro_remove(self,args):
distro = self.api.new_distro()
commands = {
- '--name' : lambda(a): distro.set_name(a)
- }
- results = {
- True : lambda: self.api.get_distros().remove(distro),
- False : lambda: self.api.show_error()
+ '--name' : lambda(a): distro.set_name(a)
}
- rc = self.apply_args(args,commands,results)
- if rc: self.api.serialize()
- return rc
+ on_ok = lambda: self.api.get_distros().remove(distro)
+ return self.apply_args(args,commands,on_ok,True)
"""
Create/Edit a system: 'bootconf system edit --name='foo' ...
@@ -151,13 +141,8 @@ class BootCLI:
'--name' : lambda(a) : sys.set_name(a),
'--group' : lambda(a) : sys.set_group(a)
}
- results = {
- True : lambda : self.api.get_systems().add(sys),
- False : lambda : self.api.show_error()
- }
- rc = self.apply_args(args,commands,results)
- if rc: self.api.serialize()
- return rc
+ on_ok = lambda: self.api.get_systems().add(sys)
+ return self.apply_args(args,commands,on_ok,True)
"""
Create/Edit a group: 'bootconf group edit --name='foo' ...
@@ -169,13 +154,8 @@ class BootCLI:
'--distro' : lambda(a) : group.set_distro(a),
'--kickstart' : lambda(a) : group.set_kickstart(a)
}
- results = {
- True : lambda : self.api.get_groups().add(group),
- False : lambda : self.api.show_error()
- }
- rc = self.apply_args(args,commands,results)
- if rc: self.api.serialize()
- return rc
+ on_ok = lambda: self.api.get_groups().add(group)
+ return self.apply_args(args,commands,on_ok,True)
"""
Create/Edit a distro: 'bootconf distro edit --name='foo' ...
@@ -187,33 +167,35 @@ class BootCLI:
'--kernel' : lambda(a) : distro.set_kernel(a),
'--initrd' : lambda(a) : distro.set_initrd(a)
}
- results = {
- True : lambda : self.api.get_distros().add(distro),
- False : lambda : self.api.show_error()
- }
- rc = self.apply_args(args,commands,results)
- if rc: self.api.serialize()
- return rc
+ on_ok = lambda: self.api.get_distros().add(distro)
+ return self.apply_args(args,commands,on_ok,True)
"""
Instead of getopt...
Parses arguments of the form --foo=bar, see group_edit for example
"""
- def apply_args(self,args,input_routines,results):
+ def apply_args(self,args,input_routines,on_ok,serialize):
+ if len(args) == 0:
+ print m("no_args")
+ return False
for x in args:
try:
key, value = x.split("=")
+ value = value.replace('"','').replace("'",'')
except:
- print "Syntax error in argument"
- return results[False]()
+ print m("bad_arg") % x
+ return False
if key in input_routines:
if not input_routines[key](value):
- print "Argument value rejected: %s" % key
- return results[False]()
+ print m("reject_arg") % key
+ return False
else:
- print "Unmatched argument: %s" % key
- return results[False]()
- return results[True]()
+ print m("weird_arg") % key
+ return False
+ rc = on_ok()
+ if rc and serialize:
+ self.api.serialize()
+ return rc
"""
Helper function to make subcommands a bit more friendly.
@@ -221,12 +203,16 @@ class BootCLI:
"""
def curry_args(self, args, commands):
if args is None or len(args) == 0:
- return self.usage()
+ print m("help")
+ return False
if args[0] in commands:
rc = commands[args[0]](args[1:])
+ if not rc:
+ return False
else:
- rc = self.usage()
- return rc
+ print m("unknown_cmd") % args[0]
+ return False
+ return True
"""
Sync the config file with the system config: 'bootconf sync [--dryrun]'
@@ -237,8 +223,6 @@ class BootCLI:
status = self.api.sync(dry_run=True)
else:
status = self.api.sync(dry_run=False)
- if not status:
- print self.api.last_error
return status
"""
@@ -247,14 +231,12 @@ class BootCLI:
def check(self,args):
status = self.api.check()
if status is None:
- print self.api.last_error
return False
elif len(status) == 0:
- # FIXME: rewrite this text.
- print "\nNo setup problems found, though we can't tell if /etc/dhcpd.conf is totally correct, so that's left as an exercise for the reader. Network boot infrastructure configuration via other 'bootconf' commands should be good to go, though you should correct any errors found as a result of running 'bootconf sync' as well. Next look over /etc/bootconf.conf and edit any global settings that are 'wrong'. Ensure that dhcpd and tftpd are started after you are done, but they do not need to be started now. Note: making changes to /etc/dhcpd.conf always requires a restart of dhcpd. Good luck!\n"
+ print m("check_ok")
return True
else:
- print "The following items need to be corrected:"
+ print m("need_to_fix")
for i,x in enumerate(status):
print "#%d: %s" % (i,x)
return False
@@ -277,10 +259,9 @@ class BootCLI:
def system(self,args):
return self.curry_args(args, self.system_commands)
-
if __name__ == "__main__":
if os.getuid() != 0:
- print "bootconf must be run as root"
+ print m("need_root")
sys.exit(1)
if BootCLI(sys.argv).run():
sys.exit(0)
diff --git a/check.py b/check.py
new file mode 100644
index 0000000..b3c8ae9
--- /dev/null
+++ b/check.py
@@ -0,0 +1,88 @@
+# Validates a system is configured for network booting
+#
+# Michael DeHaan <mdehaan@redhat.com>
+
+# FUTURE: Apache checking
+# FUTURE: Check to see what's running
+
+import os
+import sys
+import re
+
+from msg import *
+
+class BootCheck:
+
+ def __init__(self, api):
+ self.api = api
+ self.config = self.api.config
+
+ """
+ Returns None if there are no errors, otherwise returns a list
+ of things to correct prior to running bootconf 'for real'.
+ FIXME: this needs to be more tolerant of non-default paths
+ """
+ def run(self):
+ status = []
+ self.check_dhcpd_bin(status)
+ self.check_pxelinux_bin(status)
+ self.check_tftpd_bin(status)
+ self.check_tftpd_dir(status)
+ self.check_tftpd_conf(status)
+ self.check_dhcpd_conf(status)
+ return status
+
+ def check_dhcpd_bin(self,status):
+ if not os.path.exists(self.config.dhcpd_bin):
+ status.append(m("no_dhcpd"))
+
+ def check_pxelinux_bin(self,status):
+ if not os.path.exists(self.config.pxelinux):
+ status.append(m("no_pxelinux"))
+
+ def check_tftpd_bin(self,status):
+ if not os.path.exists(self.config.tftpd_bin):
+ status.append(m("no_tftpd"))
+
+ def check_tftpd_dir(self,status):
+ if not os.path.exists(self.config.tftpboot):
+ status.append(m("no_dir") % self.config.tftpboot)
+
+ def check_tftpd_conf(self,status):
+ if os.path.exists(self.config.tftpd_conf):
+ f = open(self.config.tftpd_conf)
+ re_1 = re.compile(r'default:.*off')
+ re_2 = re.compile(r'disable.*=.*yes')
+ found_bootdir = False
+ for line in f.readlines():
+ if re_1.search(line):
+ status.append(m("chg_attrib") % ('default','on',self.config.tftpd_conf))
+ if re_2.search(line):
+ status.append(m("chg_attrib") % ('disable','no',self.config.tftpd_conf))
+ if line.find("-s %s" % self.config.tftpboot) != -1:
+ found_bootdir = True
+ if not found_bootdir:
+ status.append(m("chg_attrib") % ('server_args',"-s %s" % self.config.tftpboot, self.config.tftpd_conf))
+ else:
+ status.append(m("no_exist") % self.tftpd_conf)
+
+ def check_dhcpd_conf(self,status):
+ if os.path.exists(self.config.dhcpd_conf):
+ match_next = False
+ match_file = False
+ f = open(self.config.dhcpd_conf)
+ for line in f.readlines():
+ if line.find("next-server") != -1:
+ match_next = True
+ if line.find("filename") != -1:
+ match_file = True
+ if not match_next:
+ status.append(m("no_line") % (self.config.dhcpd_conf, 'next-server ip-address'))
+ if not match_file:
+ 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'))
+ if not os.path.exists(self.config.kickstart_root):
+ status.append(m("no_dir2") % (self.config.kickstart_root, 'kickstart_root'))
diff --git a/msg.py b/msg.py
new file mode 100644
index 0000000..1301a6b
--- /dev/null
+++ b/msg.py
@@ -0,0 +1,110 @@
+# Messages used by bootconf.
+# Just consolidated here so they're not in the source.
+# No plans on localization any time soon.
+#
+# Michael DeHaan <mdehaan@redhat.com>
+
+msg_table = {
+ "no_args" : "this command requires arguments.",
+ "missing_options" : "cannot add, all parameters have not been set",
+ "unknown_cmd" : "bootconf doesn't understand '%s'",
+ "bad_arg" : "expecting an equal sign in argument '%s'",
+ "reject_arg" : "the value of parameter '%s' is not valid",
+ "weird_arg" : "this command doesn't take a parameter named '%s'",
+ "bad_sys_name" : "system name must be a MAC, IP, or resolveable host",
+ "run_check" : "run 'bootconf check' and fix errors before running sync",
+ "usage" : "for help, run 'bootconf help'",
+ "need_to_fix" : "the following items need to be corrected:",
+ "need_root" : "bootconf must be run as root",
+ "no_dhcpd" : "can't find dhcpd, try 'yum install dhcpd'",
+ "no_pxelinux" : "can't find pxelinux, try 'yum install pxelinux'",
+ "no_tftpd" : "can't find tftpd, try 'yum install tftpd'",
+ "no_dir" : "can't find %s, need to create it",
+ "chg_attrib" : "need to change '%s' to '%s' in '%s'",
+ "no_exist" : "%s does not exist",
+ "no_line" : "file '%s' should have a line '%s' somewhere",
+ "no_dir2" : "can't find %s for %s in bootconf.conf",
+ "no_cfg" : "could not find bootconf.conf, recreating",
+ "bad_param" : "at least one parameter is missing for this function",
+ "empty_list" : "(Empty)",
+ "orphan_group" : "could not delete, distro is referenced by a group",
+ "orphan_system" : "could not delete, group is referenced by a system",
+ "delete_nothing" : "can't delete something that doesn't exist",
+ "no_distro" : "distro does not exist",
+ "no_group" : "group does not exist",
+ "no_kickstart" : "kickstart file not found",
+ "no_kernel" : "the kernel needs to be a directory containing a kernel, or a full path. Kernels must be named just 'vmlinuz' or in the form 'vmlinuz-AA.BB.CC-something'",
+ "no_initrd" : "the initrd needs to be a directory containing an initrd, or a full path. Initrds must be named just 'initrd.img' or in the form 'initrd-AA.BB.CC-something.img",
+ "check_ok" : """
+No setup problems found, though we can't tell if /etc/dhcpd.conf is totally correct, so that's left as an exercise for the reader. Network boot infrastructure configuration via other 'bootconf' commands should be good to go, though you should correct any errors found as a result of running 'bootconf sync' as well. Next look over /etc/bootconf.conf and edit any global settings that are 'wrong'. Ensure that dhcpd and tftpd are started after you are done, but they do not need to be started now. Note: making changes to /etc/dhcpd.conf always requires a restart of dhcpd. Good luck!
+""",
+ "help" : """
+bootconf is a simple network boot configuration tool.
+It helps you set up Linux networks for PXE booting.
+
+***INSTRUCTIONS****
+
+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.
+
+
+ yum install dhcp tftp-server syslinux
+ ...
+ vi /etc/dhcpd.conf
+
+Verify that everything you need is set up.
+This will mention missing/stopped services and configuration errors.
+Errors? Correct any problems it reports, then run it again.
+
+ bootconf check
+
+Define your distributions, and give them names
+A good example would be 'fc5-i386' or 'fc5-x86_64'
+Paths should be on a mounted filesystem.
+
+ bootconf distro add --name="distro1" --kernel=path --initrd=path
+
+Define your provisioning "groups", and give them names too.
+Groups might be called 'webservers' or 'qamachines' or 'desktops'.
+Each group needs to know it's distribution.
+Kickstart can be done over NFS, FTP, or HTTP url, or just 'off'.
+
+ bootconf group add --name="group1" --distro="name1" --kickstart=url|off
+
+Now add your systems to groups
+
+ bootconf system add --name=mac|ipaddr|hostname --group="group1"
+
+Should you want to review things...
+
+ bootconf distros list
+ bootconf groups list
+ bootconf systems list
+
+Should you need to delete anything ...
+
+ bootconf distro remove --name="distro1"
+ bootconf group remove --name="group1"
+ bootconf system remove --name=ipaddr|mac|hostname
+
+Too much work? If you're brave, you can also edit '/etc/bootconf.conf'
+Make a backup first.
+
+ vi /etc/bootconf.conf
+
+Now make all of that bootable (immediately)
+
+ bootconf sync -dryrun # for the paranoid
+ bootconf sync
+
+That's it!
+ """
+}
+
+def m(key):
+ if key in msg_table:
+ return msg_table[key]
+ else:
+ return "?%s?" % key
+
diff --git a/sync.py b/sync.py
index be1a858..dfa2691 100644
--- a/sync.py
+++ b/sync.py
@@ -12,6 +12,7 @@ import re
import shutil
import IPy
+from msg import *
class BootSync:
@@ -25,11 +26,11 @@ class BootSync:
"""
def sync(self,dry_run=False):
if dry_run:
- print "dryrun hasn't been implemented yet. Try not using dryrun at your own risk."
+ print "WARNING: dryrun hasn't been implemented yet. Try not using dryrun at your own risk."
sys.exit(1)
- results = self.api.utils.check_install()
+ results = self.api.check()
if results != []:
- self.api.last_error = "Rerun 'bootconf check' and correct problems before proceeding."
+ self.api.last_error = m("run_check")
return False
try:
self.copy_pxelinux()
@@ -38,7 +39,7 @@ class BootSync:
self.validate_kickstarts()
self.build_pxelinux_tree()
except:
- #traceback.print_exc() # <-- remove later
+ traceback.print_exc()
return False
return True
@@ -56,8 +57,8 @@ class BootSync:
for d in self.api.get_distros().contents():
kernel = self.api.utils.find_kernel(d.kernel) # full path
initrd = self.api.utils.find_initrd(d.initrd) # full path
- print "KERNEL SRC = %s" % kernel
- print "INITRD SRC = %s" % initrd
+ print "DEBUG: kernel = %s" % kernel
+ print "DEBUG: initrd = %s" % initrd
if kernel is None:
self.api.last_error = "Kernel for distro (%s) cannot be found and needs to be fixed: %s" % (d.name, d.kernel)
raise "error"
@@ -130,4 +131,3 @@ class BootSync:
# at least those that work with open-uri
# possibly file permissions...
-
diff --git a/test.py b/test.py
index 7210222..ded4cdb 100644
--- a/test.py
+++ b/test.py
@@ -209,14 +209,22 @@ class TestSerialization(BootTest):
class TestCheck(BootTest):
def test_check(self):
- pass
+ # we can't know if it's supposed to fail in advance
+ # (ain't that the halting problem), but it shouldn't ever
+ # throw exceptions.
+ self.api.check()
class TestSync(BootTest):
def test_dry_run(self):
+ # WARNING: dry run isn't implemented yet, so no test
+ # we don't want to run a real 'sync' in an automated context
pass
def test_real_run(self):
+ # testing sync could mess up a valid install, so unless
+ # a re-homing option is added, don't write a test for this
+ # it wouldn't be comprehensive anyway
pass
if __name__ == "__main__":
diff --git a/util.py b/util.py
index 73c22c0..c990461 100644
--- a/util.py
+++ b/util.py
@@ -92,7 +92,7 @@ class BootUtil:
in a given directory that matches a given pattern. Used for
auto-booting the latest kernel in a directory.
"""
- def find_highest_files(self,directory,regex):
+ def find_highest_files(self,directory,unversioned,regex):
files = self.find_matching_files(directory, regex)
get_numbers = re.compile(r'(\d+).(\d+).(\d+)')
def sort(a,b):
@@ -105,16 +105,25 @@ class BootUtil:
elif av[2]<bv[2]: return -1
elif av[2]>bv[2]: return 1
return 0
- files = sorted(files, sort)
- return files[-1]
-
+ if len(files) > 0:
+ return sorted(files, sort)[-1]
+ else:
+ # couldn't find a highest numbered file, but maybe there
+ # is just a 'vmlinuz' or an 'initrd.img' in this directory?
+ last_chance = os.path.join(directory,unversioned)
+ if os.path.exists(last_chance):
+ return last_chance
+ return None
+
def find_kernel(self,path):
if os.path.isfile(path):
filename = os.path.basename(path)
if self.re_kernel.match(filename):
return path
+ if filename == "vmlinuz":
+ return path
elif os.path.isdir(path):
- return self.find_highest_files(path,self.re_kernel)
+ return self.find_highest_files(path,"vmlinuz",self.re_kernel)
return None
def find_initrd(self,path):
@@ -123,8 +132,10 @@ class BootUtil:
filename = os.path.basename(path)
if self.re_initrd.match(filename):
return path
+ if filename == "initrd.img" or filename == "initrd":
+ return path
elif os.path.isdir(path):
- return self.find_highest_files(path,self.re_initrd)
+ return self.find_highest_files(path,"initrd.img",self.re_initrd)
return None
def find_kickstart(self,path):
@@ -138,61 +149,7 @@ class BootUtil:
return joined
return None
- """
- Returns None if there are no errors, otherwise returns a list
- of things to correct prior to running bootconf 'for real'.
- FIXME: this needs to be more tolerant of non-default paths
- FIXME: this should check self.api.configuration variables
- """
- def check_install(self):
- status = []
- if os.getuid() != 0:
- print "Cannot run this as non-root user"
- return None
- if not os.path.exists(self.config.dhcpd_bin):
- status.append("can't find dhcpd, try 'yum install dhcpd'")
- if not os.path.exists(self.config.pxelinux):
- status.append("can't find %s, try 'yum install pxelinux'" % self.pxelinux)
- if not os.path.exists(self.config.tftpboot):
- status.append("can't find %s, need to create it" % self.config.tftpboot)
- if not os.path.exists(self.config.tftpd_bin):
- status.append("can't find tftpd, need to 'yum install tftp-server'")
- if os.path.exists(self.config.tftpd_conf):
- f = open(self.config.tftpd_conf)
- re_1 = re.compile(r'default:.*off')
- re_2 = re.compile(r'disable.*=.*yes')
- found_bootdir = False
- for line in f.readlines():
- if re_1.search(line):
- status.append("set default to 'on' in %s" % self.config.tftpd_conf)
- if re_2.search(line):
- status.append("set disable to 'no' in %s" % self.config.tftpd_conf)
- if line.find("-s %s" % self.config.tftpboot) != -1:
- found_bootdir = True
- if not found_bootdir:
- status.append("server_args should be \"-s %s\"' in %s" % (self.config.tftpboot,self.config.tftpd_conf))
- else:
- status.append("%s does not exist" % self.tftpd_conf)
- if os.path.exists(self.config.dhcpd_conf):
- match_next = False
- match_file = False
- f = open(self.config.dhcpd_conf)
- for line in f.readlines():
- if line.find("next-server") != -1:
- match_next = True
- if line.find("filename") != -1:
- match_file = True
- if not match_next:
- status.append("%s needs a 'next-server ip-address;' somewhere." % self.config.dhcpd_conf)
- if not match_file:
- status.append("%s needs a 'filename \"%s/pxelinux.0\";' somewhere." % (self.config.dhcpd_conf, self.config.tftpboot))
- else:
- status.append("can't find %s" % self.config.dhcpd_conf)
- if not os.path.exists(self.config.kernel_root):
- status.append("Nothing exists at %s, edit bootconf.conf to change kernel_root or create directory" % self.config.kernel_root)
- if not os.path.exists(self.config.kickstart_root):
- status.append("Nothing exists at %s, edit bootconf.conf to change kickstart_root or create directory, also verify that kickstart_url serves up the contents of this directory!" % self.config.kickstart_root)
- return status
+
def sync(self,dryrun=False):
# FIXME: IMPLEMENT