-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
First and foremost, the bonding stuff discussed today sounds great and
is something that I'd be interested in helping with and using.
Before we dig too far into that, however, I want to post up something
I've been meaning to finish for the past month or so but just haven't
had the time to flesh it out completely. I'd like to get it applied
(assuming others think it's a good patch :D) before we go tearing up the
interface code even more.
The attached patch adds support for generic interface names, and as a
side-effect allows an arbitrary number of interfaces to be assigned to a
system. This work looks to be a pre-requisite for the bonding examples
anyways, so it should prove useful.
More information is available in the commit log of the patch.
As always, suggestions / gripes / feedback / patches are welcome!
- --
John Eckersberg
Systems Administrator, CIS
Red Hat, Inc.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora -
http://enigmail.mozdev.org
iEYEARECAAYFAkjZlPIACgkQdxt4pd4ztYuBegCfTgcny9hdoLovwWD/UU+QPOwW
QBEAoICMHcU/ji+0teuihbNitB1Pwr+k
=ZuJ9
-----END PGP SIGNATURE-----
From f39dbead3f8f9f6de9b734e1856e66e8035e2f04 Mon Sep 17 00:00:00 2001
From: John Eckersberg <jeckersb(a)redhat.com>
Date: Tue, 23 Sep 2008 20:41:53 -0400
Subject: [PATCH] * Add new functions __get_default_interface and set_default_interface
to the System class.
* Add new setting 'default_interface' to automatically name the
interface used when creating new systems. Defaults to 'intf0' for
backwards compatibility. I suspect most people will want to set
this to 'eth0'.
* Modify the printable method of System to always print the default
interface first and mark it as the default
* Modify cli_system to add two new options:
* --delete-interface
* --default-interface
* Whatever interface is set as the default cannot be deleted.
These changes allow for an arbitrary number of interfaces to be added
to a system, as well as allows for the interfaces to be named
something more meaningful than intf0-7.
TODO
----
*** The WebUI is NOT updated by this patch and needs fixed! ***
* Allow default_interface to be set at profile level
* Add method to fetch system interfaces over XMLRPC. I want to query
my cobbler server in my Puppet exernal nodes script to build out
interface configuration. YMMV.
---
cobbler/item_system.py | 69 +++++++++++++++++++++++++++-------------
cobbler/modules/cli_system.py | 19 ++++++++---
cobbler/settings.py | 1 +
config/settings | 5 +++
4 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index c83e74b..4d8796a 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -45,6 +45,7 @@ class System(item.Item):
self.kernel_options_post = {}
self.ks_meta = {}
self.interfaces = {}
+ self.default_interface = self.settings.default_interface
self.netboot_enabled = True
self.depth = 2
self.mgmt_classes = []
@@ -61,12 +62,10 @@ class System(item.Item):
def delete_interface(self,name):
"""
- Used to remove an interface. Not valid for intf0.
+ Used to remove an interface. Not valid for the default interface.
"""
- if name == "intf0":
- raise CX(_("the first interface cannot be deleted"))
- if self.interfaces.has_key(name):
- del self.interfaces[name]
+ if self.interfaces.has_key(name) and self.default_interface != name:
+ del self.interfaces[name]
else:
# NOTE: raising an exception here would break the WebUI as currently
implemented
return False
@@ -74,9 +73,8 @@ class System(item.Item):
def __get_interface(self,name):
-
- if name not in [ "intf0", "intf1", "intf2",
"intf3", "intf4", "intf5", "intf6",
"intf7" ]:
- raise CX(_("internal error: invalid key for interface lookup or storage,
must be 'intfX' where x is 0..7"))
+ if name is None:
+ return self.__get_default_interface()
if not self.interfaces.has_key(name):
self.interfaces[name] = {
@@ -91,6 +89,12 @@ class System(item.Item):
}
return self.interfaces[name]
+ def __get_default_interface(self):
+ if self.default_interface != "":
+ return self.__get_interface(self.default_interface)
+ else:
+ raise CX(_("no default interface defined"))
+
def from_datastruct(self,seed_data):
# load datastructures from previous and current versions of cobbler
@@ -110,6 +114,7 @@ class System(item.Item):
self.netboot_enabled = self.load_item(seed_data, 'netboot_enabled',
True)
self.server = self.load_item(seed_data, 'server',
'<<inherit>>')
self.mgmt_classes = self.load_item(seed_data, 'mgmt_classes',
[])
+ self.default_interface = self.load_item(seed_data,
'default_interface', self.settings.default_interface)
# virt specific
self.virt_path = self.load_item(seed_data, 'virt_path',
'<<inherit>>')
@@ -182,7 +187,7 @@ class System(item.Item):
Set the name. If the name is a MAC or IP, and the first MAC and/or IP is not
defined, go ahead
and fill that value in.
"""
- intf = self.__get_interface("intf0")
+ intf = self.__get_default_interface()
if self.name not in ["",None] and self.parent not in
["",None] and self.name == self.parent:
@@ -211,14 +216,14 @@ class System(item.Item):
self.server = server
return True
- def get_mac_address(self,interface="intf0"):
+ def get_mac_address(self,interface):
"""
Get the mac address, which may be implicit in the object name or explicit with
--mac-address.
Use the explicit location first.
"""
-
intf = self.__get_interface(interface)
+
if intf["mac_address"] != "":
return intf["mac_address"]
# obsolete, because we should have updated the mac field already with set_name
(?)
@@ -227,13 +232,14 @@ class System(item.Item):
else:
return None
- def get_ip_address(self,interface="intf0"):
+ def get_ip_address(self,interface):
"""
Get the IP address, which may be implicit in the object name or explict with
--ip-address.
Use the explicit location first.
"""
intf = self.__get_interface(interface)
+
if intf["ip_address"] != "":
return intf["ip_address"]
else:
@@ -258,22 +264,28 @@ class System(item.Item):
return True
return False
- def set_dhcp_tag(self,dhcp_tag,interface="intf0"):
+ def set_default_interface(self,interface):
+ if self.interfaces.has_key(interface):
+ self.default_interface = interface
+ else:
+ raise CX(_("invalid interface (%s)") % interface)
+
+ def set_dhcp_tag(self,dhcp_tag,interface):
intf = self.__get_interface(interface)
intf["dhcp_tag"] = dhcp_tag
return True
- def set_hostname(self,hostname,interface="intf0"):
+ def set_hostname(self,hostname,interface):
intf = self.__get_interface(interface)
intf["hostname"] = hostname
return True
- def set_static(self,truthiness,interface="intf0"):
+ def set_static(self,truthiness,interface):
intf = self.__get_interface(interface)
intf["static"] = utils.input_boolean(truthiness)
return True
- def set_ip_address(self,address,interface="intf0"):
+ def set_ip_address(self,address,interface):
"""
Assign a IP or hostname in DHCP when this MAC boots.
Only works if manage_dhcp is set in /etc/cobbler/settings
@@ -284,24 +296,24 @@ class System(item.Item):
return True
raise CX(_("invalid format for IP address (%s)") % address)
- def set_mac_address(self,address,interface="intf0"):
+ def set_mac_address(self,address,interface):
intf = self.__get_interface(interface)
if address == "" or utils.is_mac(address):
intf["mac_address"] = address
return True
raise CX(_("invalid format for MAC address (%s)" % address))
- def set_gateway(self,gateway,interface="intf0"):
+ def set_gateway(self,gateway,interface):
intf = self.__get_interface(interface)
intf["gateway"] = gateway
return True
- def set_subnet(self,subnet,interface="intf0"):
+ def set_subnet(self,subnet,interface):
intf = self.__get_interface(interface)
intf["subnet"] = subnet
return True
- def set_virt_bridge(self,bridge,interface="intf0"):
+ def set_virt_bridge(self,bridge,interface):
intf = self.__get_interface(interface)
intf["virt_bridge"] = bridge
return True
@@ -414,6 +426,7 @@ class System(item.Item):
'kernel_options_post' : self.kernel_options_post,
'depth' : self.depth,
'interfaces' : self.interfaces,
+ 'default_interface' : self.default_interface,
'ks_meta' : self.ks_meta,
'kickstart' : self.kickstart,
'netboot_enabled' : self.netboot_enabled,
@@ -451,9 +464,21 @@ class System(item.Item):
buf = buf + _("virt ram : %s\n") % self.virt_ram
buf = buf + _("virt type : %s\n") % self.virt_type
+ # list the default interface first
+ name = self.default_interface
+ x = self.interfaces[name]
+ buf = buf + _("interface : %s (default)\n") % (name)
+ buf = buf + _(" mac address : %s\n") %
x.get("mac_address","")
+ buf = buf + _(" ip address : %s\n") %
x.get("ip_address","")
+ buf = buf + _(" hostname : %s\n") %
x.get("hostname","")
+ buf = buf + _(" gateway : %s\n") %
x.get("gateway","")
+ buf = buf + _(" subnet : %s\n") %
x.get("subnet","")
+ buf = buf + _(" virt bridge : %s\n") %
x.get("virt_bridge","")
+ buf = buf + _(" dhcp tag : %s\n") %
x.get("dhcp_tag","")
+ buf = buf + _(" is static? : %s\n") %
x.get("static",False)
- counter = 0
for (name,x) in self.interfaces.iteritems():
+ if name == self.default_interface: continue
buf = buf + _("interface : %s\n") % (name)
buf = buf + _(" mac address : %s\n") %
x.get("mac_address","")
buf = buf + _(" ip address : %s\n") %
x.get("ip_address","")
@@ -463,8 +488,6 @@ class System(item.Item):
buf = buf + _(" virt bridge : %s\n") %
x.get("virt_bridge","")
buf = buf + _(" dhcp tag : %s\n") %
x.get("dhcp_tag","")
buf = buf + _(" is static? : %s\n") %
x.get("static",False)
- counter = counter + 1
-
return buf
diff --git a/cobbler/modules/cli_system.py b/cobbler/modules/cli_system.py
index 7d5a032..3ffd7cd 100644
--- a/cobbler/modules/cli_system.py
+++ b/cobbler/modules/cli_system.py
@@ -29,7 +29,7 @@ sys.path.insert(0, mod_path)
from utils import _, get_random_mac
import commands
-import cexceptions
+from cexceptions import *
class SystemFunction(commands.CobblerFunction):
@@ -54,9 +54,11 @@ class SystemFunction(commands.CobblerFunction):
p.add_option("--hostname", dest="hostname",
help="ex: server.example.org")
if not self.matches_args(args,["find"]):
- p.add_option("--interface", dest="interface",
help="edit this interface # (0-7, default 0)")
+ p.add_option("--interface", dest="interface",
help="edit this interface")
+ p.add_option("--delete-interface",
dest="delete_interface", metavar="INTERFACE", help="delete the
selected interface")
+ p.add_option("--default-interface",
dest="default_interface", metavar="INTERFACE", help="set
INTERFACE as the system default")
p.add_option("--image", dest="image",
help="inherit values from this image, not compatible with --profile")
- p.add_option("--ip", dest="ip",
help="ex: 192.168.1.55, for static IP or dynamic reservation, (RECOMMENDED)")
+ p.add_option("--ip", dest="ip",
help="ex: 192.168.1.55, (RECOMMENDED)")
p.add_option("--kickstart", dest="kickstart",
help="override profile kickstart template")
p.add_option("--kopts", dest="kopts",
help="ex: 'noipv6'")
p.add_option("--kopts-post", dest="kopts_post",
help="ex: 'clocksource=pit'")
@@ -130,9 +132,9 @@ class SystemFunction(commands.CobblerFunction):
if self.options.virt_path: obj.set_virt_path(self.options.virt_path)
if self.options.interface:
- my_interface = "intf%s" % self.options.interface
+ my_interface = self.options.interface
else:
- my_interface = "intf0"
+ my_interface = None
if self.options.hostname: obj.set_hostname(self.options.hostname,
my_interface)
if self.options.mac:
@@ -146,7 +148,12 @@ class SystemFunction(commands.CobblerFunction):
if self.options.dhcp_tag: obj.set_dhcp_tag(self.options.dhcp_tag,
my_interface)
if self.options.virt_bridge: obj.set_virt_bridge(self.options.virt_bridge,
my_interface)
if self.options.static: obj.set_static(self.options.static, my_interface)
-
+
+ if self.options.delete_interface:
+ success = obj.delete_interface(self.options.delete_interface)
+ if not success:
+ raise CX(_('interface does not exist or is the default interface
(%s)') % self.options.delete_interface)
+ if self.options.default_interface:
obj.set_default_interface(self.options.default_interface)
if self.options.owners: obj.set_owners(self.options.owners)
if self.options.mgmt_classes: obj.set_mgmt_classes(self.options.mgmt_classes)
diff --git a/cobbler/settings.py b/cobbler/settings.py
index fd2af0a..d652e4a 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -34,6 +34,7 @@ DEFAULTS = {
"allow_duplicate_ips" : 0,
"bind_bin" : "/usr/sbin/named",
"cobbler_master" : '',
+ "default_interface" : 'intf0',
"default_kickstart" : "/etc/cobbler/default.ks",
"default_virt_bridge" : "xenbr0",
"default_virt_type" : "auto",
diff --git a/config/settings b/config/settings
index 9ac6cec..67ea1a3 100644
--- a/config/settings
+++ b/config/settings
@@ -20,6 +20,11 @@ allow_duplicate_ips: 0
# the path to BIND's executable for this distribution.
bind_bin: /usr/sbin/named
+# name of the default interface when creating a new system.
+# this is intf0 for backwards-compatibility; you may want to
+# specify something else (e.g. eth0) to be more meaningful
+default_interface: intf0
+
# if no kickstart is specified, use this template (FIXME)
default_kickstart: /etc/cobbler/default.ks
--
1.5.5.1