summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@mdehaan.rdu.redhat.com>2007-04-20 17:57:02 -0400
committerMichael DeHaan <mdehaan@mdehaan.rdu.redhat.com>2007-04-20 17:57:02 -0400
commitbb1e5b50e930b7c9618387cc43634e6050eb3481 (patch)
treeac7feb459190458ed21a57ae1bf7d5dc5b664666
parent8205bf0691bb48080c3bc4d0fd7c444238187801 (diff)
downloadthird_party-cobbler-bb1e5b50e930b7c9618387cc43634e6050eb3481.tar.gz
third_party-cobbler-bb1e5b50e930b7c9618387cc43634e6050eb3481.tar.xz
third_party-cobbler-bb1e5b50e930b7c9618387cc43634e6050eb3481.zip
This commit overhauls the main cobbler CLI module and adds support for
object renaming, copying, and editing -- previously only addition and removal were supported. This frees uses (hopefully) from the need to hack YAML and risk damaging their configurations by rendering the config unparseable. It also makes "cobbler list" print out a simple tree representation that shows the association between objects. This also relaxes the requirements for what constitutes a kernel and initrd filename, just in case they are named something different. They still have to exist.
-rw-r--r--CHANGELOG4
-rwxr-xr-xcobbler/cobbler.py455
-rw-r--r--cobbler/cobbler_msg.py4
-rw-r--r--cobbler/collection.py1
-rw-r--r--cobbler/item.py11
-rw-r--r--cobbler/item_distro.py35
-rw-r--r--cobbler/item_profile.py19
-rw-r--r--cobbler/item_repo.py8
-rw-r--r--cobbler/item_system.py12
-rw-r--r--cobbler/utils.py22
-rw-r--r--docs/cobbler.pod32
11 files changed, 396 insertions, 207 deletions
diff --git a/CHANGELOG b/CHANGELOG
index a206959..768f241 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,7 @@
Cobbler CHANGELOG
(all entries mdehaan@redhat.com unless noted otherwise)
-* TBA - 0.4.7
+* Fri Apr 20 2007 - 0.4.7
- Disable mod_python tracker piece for RHEL5 (replacement eventual).
- Kickstart tracking now understands Apache logs
- Added support for --rpm-list parameter to "repo add" for download of partial content from repositories
@@ -13,6 +13,8 @@ Cobbler CHANGELOG
- BootAPI and Config object classes are now Borg patterned to prevent duplication of config info from the API.
- cobbler_syslogd -> cobblerd, now has XMLRPC component for koan >= 0.2.9 clients. Old clients still work.
- Make cobbler_import work for Centos 5
+- Removed requirements on what files that are parameters to --kernel and --initrd must be named.
+- Added support for "rename", "copy", and "edit" commands -- before there just was "add" and "remove"
* Thu Apr 05 2007 - 0.4.6
- Bind cobbler_syslogd to all addresses
diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py
index 36c457f..52f4ca5 100755
--- a/cobbler/cobbler.py
+++ b/cobbler/cobbler.py
@@ -37,32 +37,40 @@ class BootCLI:
self.api = api.BootAPI()
self.commands = {}
self.commands['distro'] = {
- 'add' : self.distro_edit,
+ 'add' : self.distro_add,
'edit' : self.distro_edit,
+ 'copy' : self.distro_copy,
+ 'rename' : self.distro_rename,
'delete' : self.distro_remove,
'remove' : self.distro_remove,
'list' : self.distro_list,
'report' : self.distro_report
}
self.commands['profile'] = {
- 'add' : self.profile_edit,
+ 'add' : self.profile_add,
'edit' : self.profile_edit,
+ 'copy' : self.profile_copy,
+ 'rename' : self.profile_rename,
'delete' : self.profile_remove,
'remove' : self.profile_remove,
'list' : self.profile_list,
'report' : self.profile_report
}
self.commands['system'] = {
- 'add' : self.system_edit,
+ 'add' : self.system_add,
'edit' : self.system_edit,
+ 'rename' : self.system_rename,
+ 'copy' : self.system_copy,
'delete' : self.system_remove,
'remove' : self.system_remove,
'list' : self.system_list,
'report' : self.system_report
}
self.commands['repo'] = {
- 'add' : self.repo_edit,
+ 'add' : self.repo_add,
'edit' : self.repo_edit,
+ 'rename' : self.repo_rename,
+ 'copy' : self.repo_copy,
'delete' : self.repo_remove,
'remove' : self.repo_remove,
'list' : self.repo_list,
@@ -107,30 +115,9 @@ class BootCLI:
"""
print cobbler_msg.USAGE
- def list(self,args):
- args.append("") # filler
- for a in args:
- if a == '--distros' or len(args) == 1:
- print "Distros:"
- self.distro_list([])
- if a == '--repos' or len(args) == 1:
- print "Repos:"
- self.repo_list([])
- if a == '--profiles' or len(args) == 1:
- print "Profiles:"
- self.profile_list([])
- if a == '--systems' or len(args) == 1:
- print "Systems:"
- self.system_list([])
- def __sorter(self, a, b):
- return cmp(a.name, b.name)
-
- def __print_sorted(self, collection):
- collection = [x for x in collection]
- collection.sort(self.__sorter)
- for x in collection:
- print x.printable()
+ ###########################################################
+ # REPORTING FUNCTIONS
def distro_report(self,args):
self.__print_sorted(self.api.distros())
@@ -169,16 +156,21 @@ class BootCLI:
raise cexceptions.CobblerException("unknown_cmd",a)
match = False
- def system_remove(self,args):
- """
- Delete a system: 'cobbler system remove --name=foo'
- """
- commands = {
- '--name' : lambda(a): self.api.systems().remove(a, with_delete=self.api.sync_flag),
- '--system' : lambda(a): self.api.systems().remove(a, with_delete=self.api.sync_flag),
- }
- on_ok = lambda: True
- return self.apply_args(args,commands,on_ok)
+ #############################################
+ # LISTING FUNCTIONS
+
+ def list(self,args):
+ # FIXME: inefficient
+ for d in self.api.distros():
+ print "distribution : %s" % d.name
+ for p in self.api.profiles():
+ if p.distro == d.name:
+ print " profile : %s" % p.name
+ for s in self.api.systems():
+ if s.profile == p.name:
+ print " system : %s" % s.name
+ for r in self.api.repos():
+ print "repo : %s" % r.name
def __list_names(self, collection):
names = [ x.name for x in collection]
@@ -198,143 +190,171 @@ class BootCLI:
def repo_list(self, args):
return self.__list_names(self.api.repos())
-
- def profile_remove(self,args):
- """
- Delete a profile: 'cobbler profile remove --name=foo'
- """
- commands = {
- '--name' : lambda(a): self.api.profiles().remove(a, with_delete=self.api.sync_flag),
- '--profile' : lambda(a): self.api.profiles().remove(a, with_delete=self.api.sync_flag)
- }
- on_ok = lambda: True
- return self.apply_args(args,commands,on_ok)
+
+ ###############################################################
+ # UTILITY FUNCTIONS
+
+ def find_arg(self,haystack,needle):
+ for arg in haystack:
+ arg2 = arg.replace('"','')
+ if arg2.startswith(needle):
+ tokens = arg2.split("=")
+ if len(tokens) >= 1:
+ return "".join(tokens[1:])
+ return None
+
+ def replace_names(self,haystack,newname):
+ args2 = []
+ for arg in haystack:
+ if arg.startswith("--name"):
+ args2.append("--name=%s" % newname)
+ else:
+ args2.append(arg)
+ return args2
- def distro_remove(self,args):
- """
- Delete a distro: 'cobbler distro remove --name='foo'
- """
+ def __sorter(self, a, b):
+ return cmp(a.name, b.name)
+
+ def __print_sorted(self, collection):
+ collection = [x for x in collection]
+ collection.sort(self.__sorter)
+ for x in collection:
+ print x.printable()
+
+
+ ######################################################################
+ # BASIC FRAMEWORK
+
+ def __generic_add(self,args,new_fn,control_fn):
+ obj = new_fn()
+ control_fn(args,obj)
+
+ def __generic_edit(self,args,collection_fn,control_fn,exc_msg):
+ obj = collection_fn().find(self.find_arg(args,"--name"))
+ name2 = self.find_arg(args,"--newname")
+ if name2 is not None:
+ raise cexceptions.CobblerException("no_rename")
+ if obj is None:
+ raise cexceptions.CobblerException(exc_msg)
+ control_fn(args,obj)
+
+ def __generic_copy(self,args,collection_fn,control_fn,exc_msg):
+ obj = collection_fn().find(self.find_arg(args,"--name"))
+ obj2 = self.find_arg(args,"--newname")
+ if obj is None:
+ raise cexceptions.CobblerException(exc_msg)
+ args = self.replace_names(args, obj2)
+ obj3 = obj.make_clone()
+ obj3.set_name(obj2)
+ control_fn(args,obj3)
+
+ def __generic_rename(self,args,collection_fn,control_fn,exc_msg):
+ objname = self.find_arg(args,"--name")
+ if objname is None:
+ raise cexceptions.CobblerException("bad_param")
+ objname2 = self.find_arg(args,"--newname")
+ if objname2 is None:
+ raise cexceptions.CobblerException("bad_param")
+ self.__generic_copy(args,collection_fn,control_fn,exc_msg)
+ if objname != objname2:
+ collection_fn().remove(objname, with_delete=self.api.sync_flag)
+ self.api.serialize()
+
+ def __generic_remove(self,args,alias1,alias2,collection_fn):
commands = {
- '--name' : lambda(a): self.api.distros().remove(a, with_delete=self.api.sync_flag),
- '--distro' : lambda(a): self.api.distros().remove(a, with_delete=self.api.sync_flag)
+ "--%s" % alias1 : lambda(a): collection_fn().remove(a, with_delete=self.api.sync_flag),
+ "--%s" % alias2 : lambda(a): collection_fn().remove(a, with_delete=self.api.sync_flag)
}
on_ok = lambda: True
return self.apply_args(args,commands,on_ok)
+ ####################################################################
+ # REMOVAL FUNCTIONS
+
+ def distro_remove(self,args):
+ return self.__generic_remove(self,args,"distro","name",self.api.distros)
+
+ def profile_remove(self,args):
+ return self.__generic_remove(self,args,"profile","name",self.api.profiles)
+
+ def system_remove(self,args):
+ return self.__generic_remove(self,args,"system","name",self.api.systems)
+
def repo_remove(self,args):
- """
- Delete a repo: 'cobbler repo remove --name='foo'
- """
- commands = {
- '--name' : lambda(a): self.api.repos().remove(a),
- '--repo' : lambda(a): self.api.repos().remove(a)
- }
- on_ok = lambda: True
- return self.apply_args(args,commands,on_ok)
+ return self.__generic_remove(self,args,"repo","name",self.api.repos)
+
+ ####################################################################
+ # COPY FUNCTIONS
+
+ def distro_copy(self,args):
+ self.__generic_copy(args,self.api.distros,self.__distro_control,"no_distro")
+
+ def profile_copy(self,args):
+ self.__generic_copy(args,self.api.profiles,self.__profile_control,"no_profile")
+
+ def system_copy(self,args):
+ self.__generic_copy(args,self.api.systems,self.__system_control,"no_system")
+
+ def repo_copy(self,args):
+ self.__generic_copy(args,self.api.repos,self.__repo_control,"no_repo")
- def status(self,args):
- """
- Show the kickstart status for logged kickstart activity.
- 'cobbler status [--mode=text|somethingelse]'
- """
- self.mode = "text"
- if args is None or len(args) == 0:
- return self.api.status(self.mode)
- def set_mode(a):
- if a.lower in [ "text" ]:
- self.mode = a
- return True
- else:
- return False
- commands = {
- '--mode' : set_mode
- }
- def go_status():
- return self.api.status(self.mode)
- return self.apply_args(args, commands, go_status)
+ #####################################################################
+ # RENAME FUNCTIONS
- def enchant(self,args):
- """
- Reinstall a system:
- 'cobbler system enchant --name='foo' [--password='foo']
- """
- self.temp_profile = None
- self.temp_system = None
- self.temp_address = None
- self.is_virt = False
- def set_is_virt(a):
- if a.lower() in [ "0", "false", "no", "n", "off" ]:
- self.is_virt = False
- elif a.lower() in [ "1", "true", "yes", "y", "on" ]:
- self.is_virt = True
- else:
- raise cexceptions.CobblerException("reject_arg","virt")
- def set_profile(a):
- self.temp_profile = a
- def set_system(a):
- self.temp_system = a
- def set_address(a):
- self.temp_address = a
- def go_enchant():
- return self.api.enchant(self.temp_address,self.temp_profile,self.temp_system,self.is_virt)
- commands = {
- '--address' : lambda(a): set_address(a),
- '--profile' : lambda(a): set_profile(a),
- '--system' : lambda(a): set_system(a),
- '--virt' : lambda(a): set_is_virt(a)
- }
- on_ok = lambda: go_enchant()
- return self.apply_args(args,commands,on_ok)
+ def distro_rename(self,args):
+ self.__generic_rename(args,self.api.distros,self.__distro_control,"no_distro")
- def import_tree(self,args):
- """
- Import a directory tree and auto-create distros & profiles.
- 'cobbler
- """
- self.temp_mirror = None
- self.temp_mirror_name = None
- def set_mirror_name(a):
- self.temp_mirror_name = a
- def set_mirror(a):
- self.temp_mirror = a
- def go_import():
- return self.api.import_tree(
- self.temp_mirror,
- self.temp_mirror_name)
- commands = {
- '--path' : lambda(a): set_mirror(a),
- '--mirror' : lambda(a): set_mirror(a),
- '--mirror-name' : lambda(a): set_mirror_name(a),
- '--name' : lambda(a): set_mirror_name(a)
- }
- on_ok = lambda: go_import()
- return self.apply_args(args,commands,on_ok)
+ def profile_rename(self,args):
+ self.__generic_rename(args,self.api.profiles,self.__profile_control,"no_profile")
- def system_edit(self,args):
- """
- Create/Edit a system: 'cobbler system edit --name='foo' ...
- """
- sys = self.api.new_system()
- commands = {
- '--name' : lambda(a) : sys.set_name(a),
- '--system' : lambda(a) : sys.set_name(a),
- '--profile' : lambda(a) : sys.set_profile(a),
- '--kopts' : lambda(a) : sys.set_kernel_options(a),
- '--ksmeta' : lambda(a) : sys.set_ksmeta(a),
- '--pxe-address' : lambda(a) : sys.set_pxe_address(a)
- }
- on_ok = lambda: self.api.systems().add(sys, with_copy=self.api.sync_flag)
- return self.apply_args(args,commands,on_ok)
+ def system_rename(self,args):
+ self.__generic_rename(args,self.api.systems,self.__system_control,"no_system")
+ def repo_rename(self,args):
+ self.__generic_rename(args,self.api.repos,self.__repo_control,"no_repo")
+ #####################################################################
+ # EDIT FUNCTIONS
+
+ def distro_edit(self,args):
+ self.__generic_edit(args,self.api.distros,self.__distro_control,"no_distro")
+
def profile_edit(self,args):
+ self.__generic_edit(args,self.api.profiles,self.__profile_control,"no_profile")
+
+ def system_edit(self,args):
+ self.__generic_edit(args,self.api.systems,self.__system_control,"no_system")
+
+ def repo_edit(self,args):
+ self.__generic_edit(args,self.api.repos,self.__repo_control,"no_repo")
+
+ #####################################################################
+ # ADD FUNCTIONS
+
+ def distro_add(self,args):
+ self.__generic_add(args,self.api.new_distro,self.__distro_control)
+
+ def profile_add(self,args):
+ self.__generic_add(args,self.api.new_profile,self.__profile_control)
+
+ def system_add(self,args):
+ self.__generic_add(args,self.api.new_system,self.__system_control)
+
+ def repo_add(self,args):
+ self.__generic_add(args,self.api.new_repo,self.__repo_control)
+
+
+ ###############################################################
+ # CONTROL IMPLEMENTATIONS
+
+ def __profile_control(self,args,profile,newname=None):
"""
Create/Edit a profile: 'cobbler profile edit --name='foo' ...
"""
- profile = self.api.new_profile()
commands = {
'--name' : lambda(a) : profile.set_name(a),
+ '--newname' : lambda(a) : True,
'--profile' : lambda(a) : profile.set_name(a),
'--distro' : lambda(a) : profile.set_distro(a),
'--kickstart' : lambda(a) : profile.set_kickstart(a),
@@ -346,32 +366,38 @@ class BootCLI:
'--ksmeta' : lambda(a) : profile.set_ksmeta(a),
'--repos' : lambda(a) : profile.set_repos(a)
}
- on_ok = lambda: self.api.profiles().add(profile, with_copy=self.api.sync_flag)
+ def on_ok():
+ if newname is not None:
+ profile.set_name(newname)
+ self.api.profiles().add(profile, with_copy=self.api.sync_flag)
return self.apply_args(args,commands,on_ok)
- def repo_edit(self,args):
+ def __repo_control(self,args,repo,newname=None):
"""
Create/edit a repo: 'cobbler repo add --name='foo' ...
"""
- repo = self.api.new_repo()
commands = {
'--name' : lambda(a): repo.set_name(a),
+ '--newname' : lambda(a): True,
'--mirror-name' : lambda(a): repo.set_name(a),
'--mirror' : lambda(a): repo.set_mirror(a),
'--keep-updated' : lambda(a): repo.set_keep_updated(a),
'--local-filename' : lambda(a): repo.set_local_filename(a),
'--rpm-list' : lambda(a): repo.set_rpm_list(a)
}
- on_ok = lambda: self.api.repos().add(repo)
+ def on_ok():
+ if newname is not None:
+ repo.set_name(newname)
+ self.api.repos().add(repo)
return self.apply_args(args,commands,on_ok)
- def distro_edit(self,args):
+ def __distro_control(self,args,distro):
"""
Create/Edit a distro: 'cobbler distro edit --name='foo' ...
"""
- distro = self.api.new_distro()
commands = {
'--name' : lambda(a) : distro.set_name(a),
+ '--newname' : lambda(a) : True,
'--distro' : lambda(a) : distro.set_name(a),
'--kernel' : lambda(a) : distro.set_kernel(a),
'--initrd' : lambda(a) : distro.set_initrd(a),
@@ -380,9 +406,29 @@ class BootCLI:
'--ksmeta' : lambda(a) : distro.set_ksmeta(a),
'--breed' : lambda(a) : distro.set_breed(a)
}
- on_ok = lambda: self.api.distros().add(distro, with_copy=self.api.sync_flag)
+ def on_ok():
+ self.api.distros().add(distro, with_copy=self.api.sync_flag)
return self.apply_args(args,commands,on_ok)
+ def __system_control(self,args,sys):
+ """
+ Create/Edit a system: 'cobbler system edit --name='foo' ...
+ """
+ commands = {
+ '--name' : lambda(a) : sys.set_name(a),
+ '--newname' : lambda(a) : True,
+ '--system' : lambda(a) : sys.set_name(a),
+ '--profile' : lambda(a) : sys.set_profile(a),
+ '--kopts' : lambda(a) : sys.set_kernel_options(a),
+ '--ksmeta' : lambda(a) : sys.set_ksmeta(a),
+ '--pxe-address' : lambda(a) : sys.set_pxe_address(a)
+ }
+ def on_ok():
+ self.api.systems().add(sys, with_copy=self.api.sync_flag)
+ return self.apply_args(args,commands,on_ok)
+
+ ###################################################################################
+ # PARSING FUNCTIONS
def apply_args(self,args,input_routines,on_ok):
"""
@@ -421,6 +467,9 @@ class BootCLI:
raise cexceptions.CobblerException("unknown_cmd", args[0])
return True
+ ################################################
+ # GENERAL FUNCTIONS
+
def reserialize(self, args):
"""
This command is intentionally not documented in the manpage.
@@ -460,6 +509,88 @@ class BootCLI:
print "#%d: %s" % (i,x)
return False
+ def status(self,args):
+ """
+ Show the kickstart status for logged kickstart activity.
+ 'cobbler status [--mode=text|somethingelse]'
+ """
+ self.mode = "text"
+ if args is None or len(args) == 0:
+ return self.api.status(self.mode)
+ def set_mode(a):
+ if a.lower in [ "text" ]:
+ self.mode = a
+ return True
+ else:
+ return False
+ commands = {
+ '--mode' : set_mode
+ }
+ def go_status():
+ return self.api.status(self.mode)
+ return self.apply_args(args, commands, go_status)
+
+ def enchant(self,args):
+ """
+ Reinstall a system:
+ 'cobbler system enchant --name='foo' [--password='foo']
+ """
+ self.temp_profile = None
+ self.temp_system = None
+ self.temp_address = None
+ self.is_virt = False
+ def set_is_virt(a):
+ if a.lower() in [ "0", "false", "no", "n", "off" ]:
+ self.is_virt = False
+ elif a.lower() in [ "1", "true", "yes", "y", "on" ]:
+ self.is_virt = True
+ else:
+ raise cexceptions.CobblerException("reject_arg","virt")
+ def set_profile(a):
+ self.temp_profile = a
+ def set_system(a):
+ self.temp_system = a
+ def set_address(a):
+ self.temp_address = a
+ def go_enchant():
+ return self.api.enchant(self.temp_address,self.temp_profile,self.temp_system,self.is_virt)
+ commands = {
+ '--address' : lambda(a): set_address(a),
+ '--profile' : lambda(a): set_profile(a),
+ '--system' : lambda(a): set_system(a),
+ '--virt' : lambda(a): set_is_virt(a)
+ }
+ on_ok = lambda: go_enchant()
+ return self.apply_args(args,commands,on_ok)
+
+ def import_tree(self,args):
+ """
+ Import a directory tree and auto-create distros & profiles.
+ 'cobbler
+ """
+ self.temp_mirror = None
+ self.temp_mirror_name = None
+ def set_mirror_name(a):
+ self.temp_mirror_name = a
+ def set_mirror(a):
+ self.temp_mirror = a
+ def go_import():
+ return self.api.import_tree(
+ self.temp_mirror,
+ self.temp_mirror_name)
+ commands = {
+ '--path' : lambda(a): set_mirror(a),
+ '--mirror' : lambda(a): set_mirror(a),
+ '--mirror-name' : lambda(a): set_mirror_name(a),
+ '--name' : lambda(a): set_mirror_name(a)
+ }
+ on_ok = lambda: go_import()
+ return self.apply_args(args,commands,on_ok)
+
+
+ #########################################################
+ # TOPLEVEL MAPPINGS
+
def distro(self,args):
"""
Handles any of the 'cobbler distro' subcommands
@@ -484,6 +615,8 @@ class BootCLI:
"""
return self.curry_args(args, self.commands['repo'])
+####################################################
+
def main():
"""
CLI entry point
diff --git a/cobbler/cobbler_msg.py b/cobbler/cobbler_msg.py
index ca8ab2d..ad3d601 100644
--- a/cobbler/cobbler_msg.py
+++ b/cobbler/cobbler_msg.py
@@ -61,6 +61,7 @@ _msg_table = {
"parse_error" : "cobbler could not read %s, replacing...",
"no_ssh" : "cobbler can't read ~/.ssh/id_dsa.pub",
"exc_koan_path" : "koan_path in /var/lib/cobbler/settings is invalid",
+ "no_rename" : "objects can not be renamed using the edit command",
"no_create" : "cobbler could not create: %s",
"no_delete" : "cobbler could not delete: %s",
"no_args" : "this command requires arguments.",
@@ -98,7 +99,8 @@ _msg_table = {
"orphan_system" : "Removing this profile would break system '%s'",
"delete_nothing" : "can't delete something that doesn't exist",
"no_distro" : "distro does not exist",
- "no_repo" : "repository %s referenced in profile cannot be found",
+ "no_system" : "system does not exist",
+ "no_repo" : "repository %s does not exist",
"no_repos" : "one of the listed repositories is not defined in cobbler",
"no_profile" : "profile does not exist",
"no_kickstart" : "kickstart must be an absolute path, or an http://, ftp:// or nfs:// URL",
diff --git a/cobbler/collection.py b/cobbler/collection.py
index 422ecc6..e740c19 100644
--- a/cobbler/collection.py
+++ b/cobbler/collection.py
@@ -89,7 +89,6 @@ class Collection(serializable.Serializable):
raise cexceptions.CobblerException("bad_param")
self.listing[ref.name] = ref
-
# perform filesystem operations
if with_copy:
lite_sync = action_litesync.BootLiteSync(self.config)
diff --git a/cobbler/item.py b/cobbler/item.py
index c974f64..1ccc84d 100644
--- a/cobbler/item.py
+++ b/cobbler/item.py
@@ -18,6 +18,17 @@ import utils
class Item(serializable.Serializable):
+ def __init__(self,config):
+ """
+ Constructor. Requires a back reference to the Config management object.
+ """
+ self.config = config
+ self.settings = self.config._settings
+ self.clear()
+
+ def clear(self):
+ raise exceptions.NotImplementedError
+
def set_name(self,name):
"""
All objects have names, and with the exception of System
diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py
index c4c115f..3f5dcce 100644
--- a/cobbler/item_distro.py
+++ b/cobbler/item_distro.py
@@ -22,12 +22,12 @@ import cexceptions
class Distro(item.Item):
- def __init__(self,config):
- """
- Constructor. Requires a back reference to the Config management object.
- """
- self.config = config
- self.clear()
+ #def __init__(self,config):
+ # """
+ # Constructor. Requires a back reference to the Config management object.
+ # """
+ # self.config = config
+ # self.clear()
def clear(self):
"""
@@ -42,6 +42,12 @@ class Distro(item.Item):
self.breed = "redhat"
self.source_repos = []
+ def make_clone(self):
+ ds = self.to_datastruct()
+ cloned = Distro(self.config)
+ cloned.from_datastruct(ds)
+ return cloned
+
def from_datastruct(self,seed_data):
"""
Modify this object to take on values in seed_data
@@ -151,14 +157,15 @@ class Distro(item.Item):
"""
kstr = utils.find_kernel(self.kernel)
istr = 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
+ # old code, as we've relaxed filename requirements:
+ #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 = "distro : %s\n" % self.name
buf = buf + "kernel : %s\n" % kstr
buf = buf + "initrd : %s\n" % istr
diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py
index 33e8594..0bd4b05 100644
--- a/cobbler/item_profile.py
+++ b/cobbler/item_profile.py
@@ -18,13 +18,18 @@ import cexceptions
class Profile(item.Item):
- def __init__(self,config):
- """
- Constructor. Requires a backreference to Config.
- """
- self.config = config
- self.settings = self.config.settings()
- self.clear()
+ #def __init__(self,config):
+ # """
+ # Constructor. Requires a backreference to Config.
+ # """
+ # self.config = config
+ # self.settings = self.config.settings()
+
+ def make_clone(self):
+ ds = self.to_datastruct()
+ cloned = Profile(self.config)
+ cloned.from_datastruct(ds)
+ return cloned
def clear(self):
"""
diff --git a/cobbler/item_repo.py b/cobbler/item_repo.py
index 79654cd..04327ec 100644
--- a/cobbler/item_repo.py
+++ b/cobbler/item_repo.py
@@ -21,9 +21,11 @@ import cexceptions
class Repo(item.Item):
- def __init__(self,config):
- self.config = config
- self.clear()
+ def make_clone(self):
+ ds = self.to_datastruct()
+ cloned = Repo(self.config)
+ cloned.from_datastruct(ds)
+ return cloned
def clear(self):
self.name = None # is required
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index 5f23be6..53cc979 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -18,9 +18,15 @@ import cexceptions
class System(item.Item):
- def __init__(self,config):
- self.config = config
- self.clear()
+ #def __init__(self,config):
+ # self.config = config
+ # self.clear()
+
+ def make_clone(self):
+ ds = self.to_datastruct()
+ cloned = System(self.config)
+ cloned.from_datastruct(ds)
+ return cloned
def clear(self):
self.name = None
diff --git a/cobbler/utils.py b/cobbler/utils.py
index e7bd3fa..e658583 100644
--- a/cobbler/utils.py
+++ b/cobbler/utils.py
@@ -136,11 +136,12 @@ def find_kernel(path):
if path is None:
return None
if os.path.isfile(path):
- filename = os.path.basename(path)
- if _re_kernel.match(filename):
- return path
- elif filename == "vmlinuz":
- return path
+ #filename = os.path.basename(path)
+ #if _re_kernel.match(filename):
+ # return path
+ #elif filename == "vmlinuz":
+ # return path
+ return path
elif os.path.isdir(path):
return find_highest_files(path,"vmlinuz",_re_kernel)
return None
@@ -171,11 +172,12 @@ def find_initrd(path):
if path is None:
return None
if os.path.isfile(path):
- filename = os.path.basename(path)
- if _re_initrd.match(filename):
- return path
- if filename == "initrd.img" or filename == "initrd":
- return path
+ #filename = os.path.basename(path)
+ #if _re_initrd.match(filename):
+ # return path
+ #if filename == "initrd.img" or filename == "initrd":
+ # return path
+ return path
elif os.path.isdir(path):
return find_highest_files(path,"initrd.img",_re_initrd)
return None
diff --git a/docs/cobbler.pod b/docs/cobbler.pod
index 3d7d4da..f586f5f 100644
--- a/docs/cobbler.pod
+++ b/docs/cobbler.pod
@@ -246,16 +246,17 @@ mirror types, such as local paths and rsync:// mirrors. This option requires yu
=head2 DISPLAYING CONFIGURATION ENTRIES
-This is a rather simple command, usable regardless of how you are using cobbler.
+The following commands are usable regardless of how you are using cobbler.
+"report" gives detailed configuration info. "list" just lists the names of items in the configuration.
+Run these commands to check how you have cobbler configured.
-B<cobbler report [--settings] [--profiles] [--distros] [--systems] [--repos]>
+B<cobbler report>
-Prints the current cobbler configuration for systems, profiles, and groups. If one of the switches is given, only information for those is printed.
+B<cobbler distro|profile|system|repo report>
-The list command gives an abbreviated version of what "report" gives.
-It only returns the names of each item.
+B<cobbler list>
-B<cobbler list [--settings] [--profiles] [--distros] [--systems] [--repos]>
+B<cobbler distro|profile|system|repo list>
Alternatively, you could look at the configuration files in /var/lib/cobbler to see the same information.
@@ -271,6 +272,25 @@ B<cobbler system remove --name=string>
B<cobbler remove repo --name=string>
+=head2 EDITING
+
+If you want to change a particular setting without doing an "add" again, use the "edit" command, using
+the same name you gave when you added the item.
+
+B<cobbler distro|profile|system|repo edit --name=string [parameterlist]>
+
+=head2 COPYING
+
+Objects can also be copied:
+
+B<cobbler distro|profile|system|repo copy --name=oldname --newname=newname>
+
+=head2 RENAMING
+
+Objects can also be renamed, as long as other objects don't reference them.
+
+B<cobbler distro|profile|system|repo rename --name=oldname --newname=newname>
+
=head2 REBUILDING CONFIGURATIONS
B<cobbler sync>