summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cobbler/action_litesync.py6
-rw-r--r--cobbler/action_sync.py73
-rwxr-xr-xcobbler/cobbler.py7
-rw-r--r--cobbler/item_system.py120
-rw-r--r--cobbler/utils.py30
5 files changed, 148 insertions, 88 deletions
diff --git a/cobbler/action_litesync.py b/cobbler/action_litesync.py
index e3d63e6..8828daa 100644
--- a/cobbler/action_litesync.py
+++ b/cobbler/action_litesync.py
@@ -106,13 +106,15 @@ class BootLiteSync:
self.sync.validate_kickstart_for_specific_system(system)
def remove_single_system(self, name):
+ system_record = self.systems.find(name)
# rebuild system_list file in webdir
self.sync.write_listings()
# delete system YAML file in systems/$name in webdir
self.sync.rmfile(os.path.join(self.settings.webdir, "systems", name))
# delete contents of kickstarts_sys/$name in webdir
- filename = self.sync.get_pxe_filename(name)
- self.sync.rmtree(os.path.join(self.settings.webdir, "kickstarts_sys", filename))
+ if system_record.is_pxe_supported():
+ filename = self.sync.get_config_filename(system_record)
+ self.sync.rmtree(os.path.join(self.settings.webdir, "kickstarts_sys", filename))
# delete PXE Linux configuration file (which might be in one of two places)
itanic = False
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py
index d828f11..fa2f0a4 100644
--- a/cobbler/action_sync.py
+++ b/cobbler/action_sync.py
@@ -150,15 +150,11 @@ class BootSync:
system_definitions = ""
counter = 0
for system in self.systems:
- if not utils.is_mac(system.name):
- # can't do per-system dhcp features if the system
- # hostname is not a MAC, therefore the templating
- # gets to be pretty lame. The general rule here is
- # if you want to PXE IA64 boxes, you need to use
- # the MAC as the system name.
- continue
-
-
+ if not system.get_mac_address() != "":
+ # can't write a DHCP entry for this system
+ # FIXME: should this be a warning?
+ pass
+
counter = counter + 1
systxt = ""
if mode == "isc":
@@ -169,9 +165,9 @@ class BootSync:
if distro.arch == "ia64":
# can't use pxelinux.0 anymore
systxt = systxt + " filename \"/%s\";\n" % elilo
- systxt = systxt + " hardware ethernet %s;\n" % system.name
- if system.pxe_address != "":
- systxt = systxt + " fixed-address %s;\n" % system.pxe_address
+ systxt = systxt + " hardware ethernet %s;\n" % system.get_mac_address()
+ if system.get_ip_address() != None:
+ systxt = systxt + " fixed-address %s;\n" % system.get_ip_address()
systxt = systxt + " next-server %s;\n" % self.settings.next_server
systxt = systxt + "}\n"
@@ -184,9 +180,9 @@ class BootSync:
profile = self.profiles.find(system.profile)
distro = self.distros.find(profile.distro)
- if system.pxe_address != "":
+ if system.get_ip_address() != None:
if distro.arch.lower() == "ia64":
- systxt = "dhcp-host=net:ia64," + system.pxe_address + "\n"
+ systxt = "dhcp-host=net:ia64," + system.get_ip_address() + "\n"
# support for other arches needs modifications here
else:
systxt = ""
@@ -208,12 +204,12 @@ class BootSync:
# read 'man ethers' for format info
fh = open("/etc/ethers","w+")
for sys in self.systems:
- if not utils.is_mac(sys.name):
- # hopefully no one uses non-mac system ID's anymore, but I'm not sure.
- # these need to be deprecated
+ if sys.get_mac_address() == None:
+ # can't write this w/o a MAC address
+ # FIXME -- should this raise a warning?
continue
- if sys.pxe_address != "":
- fh.write(sys.name.upper() + "\t" + sys.pxe_address + "\n")
+ if sys.get_ip_address() != None:
+ fh.write(sys.get_mac_address().upper() + "\t" + sys.get_ip_address() + "\n")
fh.close()
def regen_hosts(self):
@@ -221,10 +217,10 @@ class BootSync:
# (other things may also make use of this later)
fh = open("/var/lib/cobbler/cobbler_hosts","w+")
for sys in self.systems:
- if not utils.is_mac(sys.name):
+ if sys.get_mac_address() == None:
continue
- if sys.hostname != "" and sys.pxe_address != "":
- fh.write(sys.pxe_address + "\t" + sys.hostname + "\n")
+ if sys.hostname != "" and sys.get_ip_address() != None:
+ fh.write(sys.get_ip_address() + "\t" + sys.hostname + "\n")
fh.close()
@@ -428,7 +424,7 @@ class BootSync:
distro = self.distros.find(profile.distro)
kickstart_path = utils.find_kickstart(profile.kickstart)
if kickstart_path and os.path.exists(kickstart_path):
- pxe_fn = self.get_pxe_filename(s.name)
+ pxe_fn = utils.get_config_filename(s)
copy_path = os.path.join(self.settings.webdir,
"kickstarts_sys", # system kickstarts go here
pxe_fn
@@ -510,7 +506,7 @@ class BootSync:
distro = self.distros.find(profile.distro)
if distro is None:
raise CX(_("profile %s references a missing distro %s") % { "profile" : system.profile, "distro" : profile.distro})
- f1 = self.get_pxe_filename(system.name)
+ f1 = utils.get_config_filename(system)
# tftp only
@@ -521,17 +517,17 @@ class BootSync:
if distro.arch == "ia64":
# elilo expects files to be named "$name.conf" in the root
# and can not do files based on the MAC address
- if system.pxe_address == "" or system.pxe_address is None or not utils.is_ip(system.pxe_address):
- raise CX(_("Itanium system object names must be MAC addresses"))
+ if system.get_ip_address() == None:
+ print _("Warning: Itanium system object (%s) needs an IP address to PXE") % system.name
- filename = "%s.conf" % self.get_pxe_filename(system.pxe_address)
+ filename = "%s.conf" % self.utils_config_filename(system)
f2 = os.path.join(self.settings.tftpboot, filename)
f3 = os.path.join(self.settings.webdir, "systems", f1)
- if system.netboot_enabled:
+ if system.netboot_enabled and system.is_pxe_supported():
if distro.arch in [ "x86", "x86_64", "standard"]:
self.write_pxe_file(f2,system,profile,distro,False)
if distro.arch == "ia64":
@@ -541,25 +537,6 @@ class BootSync:
self.rmfile(f2)
self.write_system_file(f3,system)
-
-
- def get_pxe_filename(self,name_input):
- """
- The configuration file for each system pxe uses is either
- a form of the MAC address of the hex version of the IP. Not sure
- about ipv6 (or if that works). The system name in the config file
- is either a system name, an IP, or the MAC, so figure it out, resolve
- the host if needed, and return the pxe directory name.
- """
- if name_input == "default":
- return "default"
- name = utils.find_system_identifier(name_input)
- if utils.is_ip(name):
- return utils.get_host_ip(name)
- elif utils.is_mac(name):
- return "01-" + "-".join(name.split(":")).lower()
- else:
- raise CX(_("System name for %s is not an MAC, IP, or resolvable host") % name)
def make_pxe_menu(self):
# only do this if there is NOT a system named default.
@@ -659,7 +636,7 @@ class BootSync:
if kickstart_path is not None and kickstart_path != "":
if system is not None and kickstart_path.startswith("/"):
- pxe_fn = self.get_pxe_filename(system.name)
+ pxe_fn = self.utils_config_filename(system)
kickstart_path = "http://%s/cblr/kickstarts_sys/%s/ks.cfg" % (self.settings.server, pxe_fn)
elif kickstart_path.startswith("/") or kickstart_path.find("/cobbler/kickstarts/") != -1:
kickstart_path = "http://%s/cblr/kickstarts/%s/ks.cfg" % (self.settings.server, profile.name)
diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py
index fda1772..0daaf85 100755
--- a/cobbler/cobbler.py
+++ b/cobbler/cobbler.py
@@ -471,8 +471,11 @@ class BootCLI:
'--kopts' : lambda(a) : sys.set_kernel_options(a),
'--ksmeta' : lambda(a) : sys.set_ksmeta(a),
'--hostname' : lambda(a) : sys.set_hostname(a),
- '--pxe-address' : lambda(a) : sys.set_ip_address(a),
- '--ip-address' : lambda(a) : sys.set_ip_address(a)
+ '--pxe-address' : lambda(a) : sys.set_ip_address(a), # deprecated
+ '--ip-address' : lambda(a) : sys.set_ip_address(a),
+ '--ip' : lambda(a) : sys.set_ip_address(a), # alias
+ '--mac-address' : lambda(a) : sys.set_mac_address(a),
+ '--mac' : lambda(a) : sys.set_mac_address(a) # alias
}
def on_ok():
self.api.systems().add(sys, with_copy=self.api.sync_flag)
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index cb6b5c8..ebfa03c 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -31,7 +31,8 @@ class System(item.Item):
self.profile = None # a name, not a reference
self.kernel_options = {}
self.ks_meta = {}
- self.pxe_address = ""
+ self.ip_address = "" # bad naming here, to the UI, this is usually 'ip-address'
+ self.mac_address = ""
self.netboot_enabled = 1
self.hostname = ""
@@ -40,31 +41,94 @@ class System(item.Item):
self.profile = self.load_item(seed_data, 'profile')
self.kernel_options = self.load_item(seed_data, 'kernel_options')
self.ks_meta = self.load_item(seed_data, 'ks_meta')
- self.pxe_address = self.load_item(seed_data, 'pxe_address')
+
+ # backwards compat, load --ip-address from two possible sources.
+ # the old --pxe-address was a bit of a misnomer, new value is --ip-address
+
+ oldvar = self.load_item(seed_data, 'pxe_address')
+ if oldvar == "": # newer version, yay
+ self.ip_address = self.load_item(seed_data, 'ip_address')
+ else:
+ self.ip_address = oldvar
+
self.netboot_enabled = self.load_item(seed_data, 'netboot_enabled', 1)
self.hostname = self.load_item(seed_data, 'hostname')
+ self.mac_address = self.load_item(seed_data, 'mac_address')
# backwards compatibility -- convert string entries to dicts for storage
+ # this allows for better usage from the API.
+
if type(self.kernel_options) != dict:
self.set_kernel_options(self.kernel_options)
if type(self.ks_meta) != dict:
self.set_ksmeta(self.ks_meta)
+ # backwards compatibility -- if name is an IP or a MAC, set appropriate fields
+ # this will only happen once, as part of an upgrade path ...
+ # Explanation -- older cobbler's figured out the MAC and IP
+ # from the system name, newer cobblers allow arbitrary naming but can tell when the
+ # name is an IP or a MAC and use that if that info is not supplied.
+
+ if self.mac_address == "" and utils.is_mac(self.name):
+ self.mac_address = self.name
+ elif self.ip_address == "" and utils.is_ip(self.name):
+ self.ip_address = self.name
+
return self
def set_name(self,name):
"""
- A name can be a resolvable hostname (it instantly resolved and replaced with the IP),
- any legal ipv4 address, or any legal mac address. ipv6 is not supported yet but _should_ be.
- See utils.py
+ In Cobbler 0.4.9, any name given is legal, but if it's not an IP or MAC, --ip-address of --mac-address must
+ be given for PXE options to work.
"""
- if name == "default":
- self.name="default"
- return True
- new_name = utils.find_system_identifier(name)
- if not new_name:
- raise CX(_("system name must be an MAC address, IP, or resolvable host"))
- self.name = name # we check it add time, but store the original value.
+
+ # set appropriate fields if the name implicitly is a MAC or IP.
+ # if the name is a hostname though, don't intuit that, as that's hard to determine
+
+ if utils.is_mac(self.name):
+ self.mac_address = self.name
+ elif utils.is_ip(self.name):
+ self.ip_address = self.name
+ self.name = name
+
+ return True
+
+ def get_mac_address(self):
+ """
+ Get the mac address, which may be implicit in the object name or explicit with --mac-address.
+ Use the explicit location first.
+ """
+ if self.mac_address != "":
+ return self.mac_address
+ elif utils.is_mac(self.name):
+ return self.name
+ else:
+ # no one ever set it, but that might be ok depending on usage.
+ return None
+
+ def get_ip_address(self):
+ """
+ Get the IP address, which may be implicit in the object name or explict with --ip-address.
+ Use the explicit location first.
+ """
+ if self.ip_address != "": # misnomer
+ return self.ip_address
+ elif utils.is_ip(self.name):
+ return self.name
+ else:
+ # no one ever set it, but that might be ok depending on usage.
+ return None
+
+ def is_pxe_supported(self):
+ """
+ Can only add system PXE records if a MAC or IP address is available, else it's a koan
+ only record. Actually Itanium goes beyond all this and needs the IP all of the time
+ though this is enforced elsewhere (action_sync.py).
+ """
+ mac = self.get_mac_address()
+ ip = self.get_ip_address()
+ if mac is None or ip is None:
+ return False
return True
def set_hostname(self,hostname):
@@ -72,21 +136,24 @@ class System(item.Item):
return True
def set_ip_address(self,address):
- # allow function to use more sensical name
- return self.set_pxe_address(address)
-
- def set_pxe_address(self,address):
"""
Assign a IP or hostname in DHCP when this MAC boots.
Only works if manage_dhcp is set in /var/lib/cobbler/settings
"""
- # restricting to address as IP only in dhcpd.conf is probably
- # incorrect ... some people may want to pin the hostname instead.
- # doing so, however, doesn't allow dhcpd.conf to be managed
- # by cobbler (since elilo can't do MAC addresses) -- this is
- # covered in the man page.
- self.pxe_address = address
- return True
+ if utils.is_ip(address):
+ self.ip_address = address
+ return True
+ raise CX(_("invalid format for IP address"))
+
+ def set_mac_address(self,address):
+ if utils.is_mac(address):
+ self.mac_address = address
+ return True
+ raise CX(_("invalid format for MAC address"))
+
+ def set_ip_address(self,address):
+ # backwards compatibility for API users:
+ return self.set_ip_address(address)
def set_profile(self,profile_name):
"""
@@ -135,7 +202,7 @@ class System(item.Item):
'profile' : self.profile,
'kernel_options' : self.kernel_options,
'ks_meta' : self.ks_meta,
- 'pxe_address' : self.pxe_address,
+ 'ip_address' : self.ip_address,
'netboot_enabled' : self.netboot_enabled,
'hostname' : self.hostname,
}
@@ -145,7 +212,10 @@ class System(item.Item):
buf = buf + _("profile : %s\n") % self.profile
buf = buf + _("kernel options : %s\n") % self.kernel_options
buf = buf + _("ks metadata : %s\n") % self.ks_meta
- buf = buf + _("ip address : %s\n") % self.pxe_address
+ buf = buf + _("ip address : %s\n") % self.get_ip_address()
+ buf = buf + _("mac address : %s\n") % self.get_mac_address()
+ buf = buf + _("pxe info set? : %s\n") % self.is_pxe_supported()
+ buf = buf + _("pxe id : %s\n") % self.get_system_identifier()
buf = buf + _("hostname : %s\n") % self.hostname
return buf
diff --git a/cobbler/utils.py b/cobbler/utils.py
index 9868975..de810be 100644
--- a/cobbler/utils.py
+++ b/cobbler/utils.py
@@ -40,17 +40,25 @@ def get_host_ip(ip):
results = out.read()
return results.split(" ")[-1][0:8]
-def find_system_identifier(strdata):
- """
- If the input is a MAC or an IP, return that.
- If it's not, resolve the hostname and return the IP.
- pxe bootloaders don't work in hostnames
- """
- if is_mac(strdata):
- return strdata.upper()
- if is_ip(strdata):
- return strdata
- return resolve_ip(strdata)
+def get_config_filename(sys):
+ """
+ The configuration file for each system pxe uses is either
+ a form of the MAC address of the hex version of the IP. If none
+ of that is available, just use the given name, though the name
+ given will be unsuitable for PXE configuration (For this, check
+ system.is_pxe_supported()). This same file is used to store
+ system config information in the Apache tree, so it's still relevant.
+ """
+ if sys.name == "default":
+ return "default"
+ mac = sys.get_mac_address()
+ ip = sys.get_ip_address()
+ if mac != None:
+ return "01-" + "-".join(mac.split(":")).lower()
+ elif ip != None:
+ return utils.get_host_ip(ip)
+ else:
+ return sys.name
def is_ip(strdata):