summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lutterkort <dlutter@redhat.com>2006-10-25 10:26:37 -0700
committerJim Meyering <jim@meyering.net>2006-10-25 10:26:37 -0700
commit1ba62867b46323e6b53b5233be300b4faae2458d (patch)
tree6f1b44557338082655e9e0ab3f85604797e65b4b
parent679d35e42dfc3ae181167522dc1f171dcf008a84 (diff)
downloadthird_party-cobbler-1ba62867b46323e6b53b5233be300b4faae2458d.tar.gz
third_party-cobbler-1ba62867b46323e6b53b5233be300b4faae2458d.tar.xz
third_party-cobbler-1ba62867b46323e6b53b5233be300b4faae2458d.zip
Merge 243:1f764e5dd1cc
-rw-r--r--CHANGELOG23
-rw-r--r--MANIFEST.in1
-rw-r--r--NEWS79
-rw-r--r--TODO2
-rw-r--r--cobbler.pod40
-rw-r--r--cobbler.spec24
-rw-r--r--cobbler/action_import.py15
-rw-r--r--cobbler/action_sync.py53
-rwxr-xr-xcobbler/cobbler.py11
-rw-r--r--cobbler/cobbler_msg.py14
-rw-r--r--cobbler/collection_profiles.py2
-rw-r--r--cobbler/item_profile.py118
-rw-r--r--cobbler/settings.py44
-rw-r--r--default.ks2
-rw-r--r--setup.py6
-rw-r--r--tests/tests.py32
16 files changed, 214 insertions, 252 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 655c5e4..fc225da 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,8 +1,27 @@
Cobbler CHANGELOG
(all entries mdehaan@redhat.com unless noted otherwise)
-* Mon Oct 23 2006 - 0.2.9-1
+* Wed Oct 25 2006 - 0.3.1-1
+- The app now refers to "virt" in many places instead of "xen".
+ It's been coded such that files will migrate forward without
+ any major issues, and the newer version of koan can still hit
+ older releases (for now). The CLI still takes the --xen options
+ as well as the new --virt options, as they are aliased. The API
+ now exclusively just uses methods with "virt" in them, however.
+
+* Tue Oct 24 2006 - 0.3.0-1
+- Reload httpd during sync
+- New profiles without set kickstarts default to /etc/cobbler/default.ks
+ though this can be changed in /var/lib/cobbler/settings
+- Better forward upgrades for /var/lib/cobbler/settings. New entries
+ get added when they are referenced.
+
+* Tue Oct 24 2006 - 0.2.9-1
- Bug fix, enchant now detects if koan_path is not set
+- import now can do ssh rsync as well as just rsyncd
+- Misc bug fixes related to not choking on bad info
+- Fixed bug where --pxe-address wasn't surfaced
+- Sync is a little less verbose
* Wed Oct 18 2006 - 0.2.8-1
- Performance speedups to "import" command
@@ -54,7 +73,7 @@ Cobbler CHANGELOG
* Wed Sep 20 2006 - 0.1.1-7
- Split HTTP and TFTP content to seperate directories
to enable running in SELinux targetted/enforcing mode.
-- Make the Xen MAC address a property of a system, not a profile
+- Make the Virt MAC address a property of a system, not a profile
- Misc. fixes, mainly along the error path
* Fri Sep 15 2006 - 0.1.1-6
diff --git a/MANIFEST.in b/MANIFEST.in
index 8302ab7..d18b423 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -2,5 +2,6 @@ include COPYING_ELILO
include elilo-3.6-ia64.efi
include dhcp.template
include kickstart_fc5.ks
+include default.ks
include cobbler.1.gz
include COPYING AUTHORS README CHANGELOG NEWS
diff --git a/NEWS b/NEWS
index d0359de..32f1001 100644
--- a/NEWS
+++ b/NEWS
@@ -1,81 +1,4 @@
Cobbler NEWS
(all entries mdehaan@redhat.com unless noted otherwise)
-======================================================
-0.2.7 -- RHEL4, pexpect not required, "enchant" changes
-======================================================
-
-Cobbler now builds on RHEL4 out of the box!
-
-In order to make Cobbler work on more platforms, the dependancy on
-pexpect (a python module) has been removed. SSH is now invoked directly.
-This means Cobbler now builds very easily on RHEL 4.
-
-As a result, this means that to run "enchant" a remote system, that
-system needs to have the cobbler server in the /root/.ssh/authorized_keys
-file or the password will be prompted for multiple times. Use ssh-agent
-if this is undesirable.
-
-In addition, the arguments to "enchant" have changed to make it more
-flexible. See the manpage for details.
-
-===================================
-0.2.6 -- Cheetah no longer required
-===================================
-
-Cobbler is losing it's dependency on Cheetah for kickstart templating.
-Most users won't be affected, templating still works as described in the
-manpage. A future release will remove the dependancy on pxssh, allowing
-for better installation on RHEL4.
-
-=============================
-0.2.5 -- New "import" feature
-=============================
-
-Cobbler now contains an import command. It currently can
-work in either of two modes (see manpage) -- filesystem directory
-trees and rsync:// mirrors.
-
-Rsync mirror support enables near instanteous setup of a new provisioning
-environment by auto-importing distribution and profile information for
-automatic installation.
-
-The "enchant" command has been slightly modified in terms of what
-arguments it requires. See the manpage if you have been using
-that command.
-
-===============================
-0.2.2 -- IA64 PXE Go For Launch
-===============================
-
-Having had the time to do proper IA64 testing with elilo, Itanium
-PXE support is now confirmed to work. --pxe-arch and --pxe-address
-must both be set on the IA64 system when it is created with cobbler.
-
-Additional bugfixes have improved stability of the dhcpd.conf generation.
-
-==============================
-0.2.1 -- New "enchant" feature
-==============================
-
-Usage of "enchant" can install a profile on a remote system, even
-if that system does not have the koan helper tool installed.
-You'll need an IP or system name, a profile name, and the password
-to the system. See the manpage.
-
-=======================================================
-0.2.0 -- New dhcp.conf templating and IA64 PXE features
-=======================================================
-
-Cobbler now contains an experimental dhcpd.conf templating feature.
-Read the manpage, and if you want to use it, back up your existing
-dhcpd.conf before enabling that feature. It is *OFF* by default.
-
-When using that feature, dhcpd.conf can associate MAC addresses
-with hostnames (as defined from cobbler), and cobbler can
-also differentiate between IA64 and x86/x86_64 network boots. Each
-time cobbler sync is run, it will build a new dhcpd.conf based on
-/etc/cobbler/dhcpd.template.
-
-Cobbler is now packaging ELILO to enable IA64 booting.
-
+No NEWS is good NEWS. See CHANGELOG.
diff --git a/TODO b/TODO
index d9dd433..9fab1ea 100644
--- a/TODO
+++ b/TODO
@@ -8,6 +8,8 @@ core:
- make the "scrub orphans" bit a seperate command, warn by default, with an
option for "--delete". Seperate from "import". This could probably
be a part of "check" to avoid making another command.
+ - "check" should check if services (esp httpd) are started
+ - import should be able to do rsync over ssh:// as well as rsync://
user interface:
- "cobbler add" should be distinguished from "edit" so as to not overwrite
diff --git a/cobbler.pod b/cobbler.pod
index 946b28d..3efbed4 100644
--- a/cobbler.pod
+++ b/cobbler.pod
@@ -1,6 +1,6 @@
=head1 NAME
-cobbler is a command line tool for configuring a provisioning server. It supports provisioning via PXE, Xen, and re-provisioning an existing Linux system ("auto-kickstarting"). The latter two features are enabled by usage of 'koan' (a client side provisioning application) on the remote system.
+cobbler is a command line tool for configuring a provisioning server. It supports provisioning via PXE, Virt, and re-provisioning an existing Linux system ("auto-kickstarting"). The latter two features are enabled by usage of 'koan' (a client side provisioning application) on the remote system.
=head1 SYNOPSIS
@@ -82,7 +82,7 @@ See the section below on templating.
A profile associates a distribution to additional specialized options, such as a kickstart automation file. Profiles are the core unit of provisioning and at least one profile must exist for every distribution to be provisioned.
-B<cobbler profile add --name=<string> --distro=<string> [--kickstart=<url>] [--kopts=<string>] [--ksmeta=<string>] [--xen-name=<string>] [--xen-file-size=<gigabytes>] [--xen-ram=<megabytes>]
+B<cobbler profile add --name=<string> --distro=<string> [--kickstart=<url>] [--kopts=<string>] [--ksmeta=<string>] [--virt-name=<string>] [--virt-file-size=<gigabytes>] [--virt-ram=<megabytes>]
=over
@@ -94,20 +94,22 @@ the name of a previously defined cobbler distribution
=item kickstart
-(optional) an HTTP URL, NFS URL, or local filesystem path to a kickstart file. Filesystem paths are needed to take advantage of cobbler's kickstart templating features. Kickstart templating is covered in a later section. If this parameter is not provided, no kickstart will be used, and the installs will not be automated.
+(optional) an HTTP URL, NFS URL, or local filesystem path to a kickstart file. Filesystem paths are needed to take advantage of cobbler's kickstart templating features and are therefore recommended. Kickstart templating is covered in a later section.
-=item xen-name
+If this parameter is not provided, the kickstart file will default to /etc/cobbler/default.ks (or whatever is set in /var/lib/cobbler/settings). This file is initially blank, meaning default kickstarts are not automated. Admins can change the default.ks or can leave it blank.
-(optional) (Xen-only) what the Xen domU name should start with. Creating
-multiple images on a machine will cause increasing numbers to be appended to this name. The default is "xenguest".
+=item virt-name
-=item xen-file-size
+(optional) (Virt-only) what the Virt guest name should start with. Creating
+multiple images on a machine will cause increasing numbers to be appended to this name. The default is "virtguest".
-(optional) (Xen-only) how large the disk image should be in gigabytes. The default is "5".
+=item virt-file-size
-=item xen-ram
+(optional) (Virt-only) how large the disk image should be in gigabytes. The default is "5".
-(optional) (Xen-only) how many megabytes of RAM to consume. The default is 512 MB.
+=item virt-ram
+
+(optional) (Virt-only) how many megabytes of RAM to consume. The default is 512 MB.
=back
@@ -126,7 +128,7 @@ the following changes:
The system name must be either a currently-resolvable hostname, an IP address, or a MAC address.
-When defining Xen systems, using a MAC address causes the Xen MAC address to be used for creation,
+When defining Virtualized systems, using a MAC address causes the Virt MAC address to be used for creation,
so that is the preferred usage.
=item pxe-address
@@ -212,19 +214,19 @@ B<cobbler sync>
=head2 XEN
-For Xen, be sure the distro uses a Xen kernel and initrd and follow similar steps as above, adding additional parameters as desired:
+For Virt, be sure the distro uses a Virt kernel and initrd and follow similar steps as above, adding additional parameters as desired:
=over
-B<cobbler distro add --name=fc5xen --kernel=/dir3/vmlinuz --initrd=/dir6/initrd.img>
+B<cobbler distro add --name=fc5virt --kernel=/dir3/vmlinuz --initrd=/dir6/initrd.img>
-Specify reasonable values for the Xen image size (in GB) and RAM requirements:
+Specify reasonable values for the Virt image size (in GB) and RAM requirements:
-B<cobbler profile add --name=xenwebservers --distro=fc5xen --kickstart=/dir7/kick.ks --xen-file-size=10 --xen-ram=512>
+B<cobbler profile add --name=virtwebservers --distro=fc5virt --kickstart=/dir7/kick.ks --virt-file-size=10 --virt-ram=512>
And define systems (if desired) using MAC addresses, not IP's or hostnames:
-B<cobbler system add --name=AA:BB:CC:DD:EE:FE --profile=xenwebservers>
+B<cobbler system add --name=AA:BB:CC:DD:EE:FE --profile=virtwebservers>
=back
@@ -264,7 +266,7 @@ The dhcpd.conf file will be updated each time "cobbler sync" is run.
=head2 ENCHANT
-While the normal provisioning procedure is either to PXE bare-metal, or use koan to do something else (kickstart an existing system or deploy Xen), cobbler contains yet another option, called "enchant".
+While the normal provisioning procedure is either to PXE bare-metal, or use koan to do something else (kickstart an existing system or deploy Virt), cobbler contains yet another option, called "enchant".
Enchant takes a configuration that has already been defined (be sure to run "cobbler sync" before using "cobbler enchant") and applies it to a remote system that may not have koan installed.
@@ -277,7 +279,7 @@ Usage: B<cobbler enchant --address=<ip|hostname> --system=<string>>
Cobbler can auto-add distributions and profiles from remote sources, whether this is an NFS path or an rsync mirror. This can save a lot of time when setting up a new provisioning environment.
-NOTE: The mirror or directory tree must have the basic directory tree layout as a Fedora or Centos mirror normally looks, including directories named things like "pxeboot" or "xen", "i386" or "x86_64", and so forth.
+NOTE: The mirror or directory tree must have the basic directory tree layout as a Fedora or Centos mirror normally looks, including directories named things like "pxeboot", "i386" or "x86_64", and so forth.
When importing a rsync mirror, cobbler can try to detect the distribution type and automatically assign kickstarts. This autodetection is rather primative but can improve as community users contribute kickstarts. If cobbler is able to guess the architecture, it will provision the system by erasing the hard drive, setting up eth0 for dhcp, and using a default password of "cobbler". If this is undesirable, edit the kickstart files in /etc/cobbler to do something else or change the kickstart setting after cobbler creates the profile.
@@ -289,6 +291,8 @@ Usage; B<cobbler import --mirror=<rsync_url> --mirror-name=<string>>
Example: B<cobbler import --mirror=rsync://mirror.linux.duke.edu/fedora-linux-core/ --mirror-name=fedora>
+Example2: B<cobbler import --mirror=root@192.168.1.10:/stuff --mirror-name=bar>
+
Once imported, run a "cobbler list" to see what you've added.
"Cobbler sync" must still be run after an import to get the system ready to provision what was just imported.
diff --git a/cobbler.spec b/cobbler.spec
index 4fe0a01..c3d3506 100644
--- a/cobbler.spec
+++ b/cobbler.spec
@@ -2,7 +2,7 @@
Summary: Boot server configurator
Name: cobbler
-Version: 0.2.8
+Version: 0.3.1
Release: 1%{?dist}
Source0: %{name}-%{version}.tar.gz
License: GPL
@@ -17,10 +17,7 @@ Url: http://cobbler.et.redhat.com
%description
-Cobbler is a command line tool for simplified configuration of provisioning
-servers. It is also accessible as a Python library. Cobbler supports PXE,
-Xen, and re-provisioning an existing Linux system via auto-kickstart. The
-last two modes require 'koan' to be run on the remote system.
+Cobbler is a command line tool for configuration of boot/provisioning servers. It is also accessible as a Python library. Cobbler supports PXE, provisioning virtualized ("virt") images, and reinstalling machines that are already up and running (over SSH). The last two modes require a helper tool called 'koan' that integrates with cobbler. Cobbler's advanced features include importing distributions from rsync mirrors, kickstart templating, and managing dhcpd.conf.
%prep
%setup -q
@@ -39,8 +36,9 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root)
%{_bindir}/cobbler
%dir /etc/cobbler
-/etc/cobbler/*.ks
-/etc/cobbler/dhcp.template
+%config(noreplace) /etc/cobbler/default.ks
+%config(noreplace) /etc/cobbler/kickstart_fc5.ks
+%config(noreplace) /etc/cobbler/dhcp.template
%dir %{python_sitelib}/cobbler
%dir %{python_sitelib}/cobbler/yaml
%{python_sitelib}/cobbler/*.py*
@@ -54,6 +52,18 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
%changelog
+* Wed Oct 25 2006 Michael DeHaan <mdehaan@redhat.com> - 0.3.1-1
+- Upstream changes (see CHANGELOG)
+- Updated description
+
+* Tue Oct 24 2006 Michael DeHaan <mdehaan@redhat.com> - 0.3.0-1
+- Upstream changes (see CHANGELOG)
+- Marked files in /etc/cobbler as config
+- Marked /etc/cobbler/dhcpd.template as noreplace
+
+* Tue Oct 24 2006 Michael DeHaan <mdehaan@redhat.com> - 0.2.9-1
+- Upstream changes (see CHANGELOG)
+
* Wed Oct 18 2006 Michael DeHaan <mdehaan@redhat.com> - 0.2.8-1
- Upstream changes (see CHANGELOG)
diff --git a/cobbler/action_import.py b/cobbler/action_import.py
index 69bfa97..486842e 100644
--- a/cobbler/action_import.py
+++ b/cobbler/action_import.py
@@ -85,18 +85,19 @@ class Importer:
if self.path and not os.path.isdir(self.path):
raise cexceptions.CobblerException("import_failed","bad path")
if self.mirror is not None:
- if not self.mirror.startswith("rsync://"):
- raise cexceptions.CobblerException("import_failed","expecting rsync:// url")
if self.mirror_name is None:
raise cexceptions.CobblerException("import_failed","must specify --mirror-name")
print "This will take a while..."
self.path = "/var/www/cobbler/localmirror/%s" % self.mirror_name
try:
- os.mkdir(self.path)
+ os.makedirs(self.path)
except:
if not os.path.exists(self.path):
raise cexceptions.CobblerException("couldn't create: %s" % (self.path))
- cmd = "rsync -az %s /var/www/cobbler/localmirror/%s --progress" % (self.mirror, self.mirror_name)
+ spacer = ""
+ if not self.mirror.startswith("rsync://"):
+ spacer = ' -e "ssh" '
+ cmd = "rsync -az %s %s /var/www/cobbler/localmirror/%s --progress" % (spacer, self.mirror, self.mirror_name)
sub_process.call(cmd,shell=True)
update_file = open(os.path.join(self.path,"update.sh"),"w+")
update_file.write("#!/bin/sh")
@@ -186,7 +187,7 @@ class Importer:
if tentative == filter_out:
fnames.remove(tentative)
print "%s" % dirname
- if not self.is_pxe_or_xen_dir(dirname):
+ if not self.is_pxe_or_virt_dir(dirname):
return
for x in fnames:
if x.startswith("initrd"):
@@ -235,8 +236,8 @@ class Importer:
return "x86"
return "x86"
- def is_pxe_or_xen_dir(self,dirname):
- if dirname.find("pxe") != -1 or dirname.find("xen") != -1:
+ def is_pxe_or_virt_dir(self,dirname):
+ if dirname.find("pxe") != -1 or dirname.find("xen") != -1 or dirname.find("virt") != -1:
return True
return False
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py
index 23e5660..725bf7d 100644
--- a/cobbler/action_sync.py
+++ b/cobbler/action_sync.py
@@ -153,7 +153,7 @@ class BootSync:
cobbler infrastructure available over TFTP over HTTP also.
"""
if not os.path.exists("/etc/httpd/conf.d"):
- self.sync_log(cobbler_msg.lookup("no_httpd"))
+ print cobbler_msg.lookup("no_httpd")
return
f = self.open_file("/etc/httpd/conf.d/cobbler.conf","w+")
config_data = """
@@ -172,14 +172,15 @@ class BootSync:
config_data = config_data.replace("/cobbler_webdir",self.settings.webdir)
self.tee(f, config_data)
self.close_file(f)
+ sub_process.call("/sbin/service httpd reload", shell=True)
def clean_trees(self):
"""
- Delete any previously built pxelinux.cfg tree and xen tree info.
+ Delete any previously built pxelinux.cfg tree and virt tree info.
Note: for SELinux reasons, some information goes in /tftpboot, some in /var/www/cobbler
and some must be duplicated in both. This is because PXE needs tftp, and auto-kickstart
- and Xen operations need http. Only the kernel and initrd images are duplicated, which is
+ and Virt operations need http. Only the kernel and initrd images are duplicated, which is
unfortunate, though SELinux won't let me give them two contexts, so symlinks are not
a solution. *Otherwise* duplication is minimal.
"""
@@ -245,7 +246,7 @@ class BootSync:
def validate_kickstarts_per_profile(self):
"""
- Koan provisioning (Xen + auto-ks) needs kickstarts
+ Koan provisioning (Virt + auto-ks) needs kickstarts
per profile. Validate them as needed. Local kickstarts
get template substitution. Since http:// kickstarts might
get generated via magic URLs, those are *not* substituted.
@@ -259,7 +260,6 @@ class BootSync:
for g in self.profiles:
distro = self.distros.find(g.distro)
- self.sync_log(cobbler_msg.lookup("sync_mirror_ks"))
kickstart_path = utils.find_kickstart(g.kickstart)
if kickstart_path and os.path.exists(kickstart_path):
# the input is an *actual* file, hence we have to copy it
@@ -323,7 +323,8 @@ class BootSync:
data = fd.read()
fd.close()
for x in metadata.keys():
- data = data.replace("TEMPLATE::%s" % x, metadata[x])
+ if x != "":
+ data = data.replace("TEMPLATE::%s" % x, metadata[x])
fd = open(out_path, "w+")
fd.write(data)
fd.close()
@@ -332,21 +333,19 @@ class BootSync:
"""
Now that kernels and initrds are copied and kickstarts are all valid,
build the pxelinux.cfg tree, which contains a directory for each
- configured IP or MAC address. Also build a tree for Xen info.
+ configured IP or MAC address. Also build a tree for Virt info.
NOTE: some info needs to go in TFTP and HTTP directories, but not all.
Usually it's just one or the other.
"""
- self.sync_log(cobbler_msg.lookup("sync_buildtree"))
self.write_listings()
# create pxelinux.cfg under tftpboot
# and file for each MAC or IP (hex encoded 01-XX-XX-XX-XX-XX-XX)
for d in self.distros:
- self.sync_log(cobbler_msg.lookup("sync_processing") % d.name)
# TODO: add check to ensure all distros have profiles (=warning)
filename = os.path.join(self.settings.webdir,"distros",d.name)
d.kernel_options = self.blend_options(True,(
@@ -357,7 +356,6 @@ class BootSync:
self.write_distro_file(filename,d)
for p in self.profiles:
- self.sync_log(cobbler_msg.lookup("sync_processing") % p.name)
# TODO: add check to ensure all profiles have distros (=error)
# TODO: add check to ensure all profiles have systems (=warning)
filename = os.path.join(self.settings.webdir,"profiles",p.name)
@@ -372,7 +370,6 @@ class BootSync:
self.write_profile_file(filename,p)
for system in self.systems:
- self.sync_log(cobbler_msg.lookup("sync_processing") % system.name)
profile = self.profiles.find(system.profile)
if profile is None:
raise cexceptions.CobblerException("orphan_profile2",system.name,system.profile)
@@ -436,8 +433,6 @@ class BootSync:
kernel_path = os.path.join("/images",distro.name,os.path.basename(distro.kernel))
initrd_path = os.path.join("/images",distro.name,os.path.basename(distro.initrd))
kickstart_path = profile.kickstart
- self.sync_log(cobbler_msg.lookup("writing") % filename)
- self.sync_log("---------------------------------")
fd = self.open_file(filename,"w+")
if not is_ia64:
# pxelinux tree
@@ -488,7 +483,6 @@ class BootSync:
self.tee(fd, "\tappend=\"%s\"" % append_line)
self.close_file(fd)
- self.sync_log("--------------------------------")
def write_listings(self):
"""
@@ -505,11 +499,10 @@ class BootSync:
self.tee(fd2, data2)
self.close_file(fd1)
self.close_file(fd2)
- self.sync_log("--------------------------------")
def write_distro_file(self,filename,distro):
"""
- Create distro information for xen-net-install
+ Create distro information for virt install
NOTE: relevant to http only
"""
@@ -522,7 +515,7 @@ class BootSync:
def write_profile_file(self,filename,profile):
"""
- Create profile information for xen-net-install
+ Create profile information for virt install
NOTE: relevant to http only
"""
@@ -537,7 +530,7 @@ class BootSync:
def write_system_file(self,filename,system):
"""
- Create system information for xen-net-install
+ Create system information for virt install
NOTE: relevant to http only
"""
@@ -549,7 +542,8 @@ class BootSync:
"""
For dryrun support: send data to screen and potentially to disk
"""
- self.sync_log(text)
+ if self.dryrun:
+ print text
if not self.dryrun:
fd.write(text)
@@ -572,7 +566,7 @@ class BootSync:
"""
For dryrun support: potentially copy a file.
"""
- self.sync_log(cobbler_msg.lookup("copying") % (src,dst))
+ print "%s -> %s" % (src,dst)
if self.dryrun:
return True
try:
@@ -585,7 +579,7 @@ class BootSync:
"""
For dryrun support: potentially copy a file.
"""
- self.sync_log(cobbler_msg.lookup("copying") % (src,dst))
+ print "%s -> %s" % (src,dst)
if self.dryrun:
return True
try:
@@ -611,7 +605,7 @@ class BootSync:
"""
For dryrun support: potentially delete a tree.
"""
- self.sync_log(cobbler_msg.lookup("removing") % (path))
+ print "del %s" % (path)
if self.dryrun:
return True
try:
@@ -624,8 +618,8 @@ class BootSync:
"""
For dryrun support: potentially make a directory.
"""
- self.sync_log(cobbler_msg.lookup("mkdir") % (path))
if self.dryrun:
+ print "mkdir %s" % (path)
return True
try:
return os.makedirs(path,mode)
@@ -633,19 +627,6 @@ class BootSync:
if not oe.errno == 17: # already exists (no constant for 17?)
raise cexceptions.CobblerException("no_create", path)
- def sync_log(self,message):
- """
- Used to differentiate dryrun output from the real thing
- automagically
- """
- if self.verbose:
- if self.dryrun:
- if not message:
- message = ""
- print cobbler_msg.lookup("dryrun") % str(message)
- else:
- print message
-
def blend_options(self, is_for_kernel, list_of_opts):
"""
Given a list of options, take the values used by the
diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py
index 7186b5c..aa64ff4 100755
--- a/cobbler/cobbler.py
+++ b/cobbler/cobbler.py
@@ -210,12 +210,13 @@ class BootCLI:
'--kickstart' : lambda(a) : profile.set_kickstart(a),
'--kick-start' : lambda(a) : profile.set_kickstart(a),
'--kopts' : lambda(a) : profile.set_kernel_options(a),
- '--xen-name' : lambda(a) : profile.set_xen_name(a),
- '--xen-file-size' : lambda(a) : profile.set_xen_file_size(a),
- '--xen-ram' : lambda(a) : profile.set_xen_ram(a),
+ '--xen-name' : lambda(a) : profile.set_virt_name(a),
+ '--virt-name' : lambda(a) : profile.set_virt_name(a),
+ '--xen-file-size' : lambda(a) : profile.set_virt_file_size(a),
+ '--virt-file-size' : lambda(a) : profile.set_virt_file_size(a),
+ '--xen-ram' : lambda(a) : profile.set_virt_ram(a),
+ '--virt-ram' : lambda(a) : profile.set_virt_ram(a),
'--ksmeta' : lambda(a) : profile.set_ksmeta(a)
- # the following options are most likely not useful for profiles (yet)
- # '--xen-paravirt' : lambda(a) : profile.set_xen_paravirt(a),
}
on_ok = lambda: self.api.profiles().add(profile)
return self.apply_args(args,commands,on_ok)
diff --git a/cobbler/cobbler_msg.py b/cobbler/cobbler_msg.py
index a77e537..0181439 100644
--- a/cobbler/cobbler_msg.py
+++ b/cobbler/cobbler_msg.py
@@ -26,8 +26,8 @@ cobbler distro add --name=<string> --kernel=<path> --initrd=<path>
cobbler profile add --name=<string --distro=<string>
[--kick-start=<url>] [--kopts=<string>] [--ksmeta=<string>]
- [--xen-name=<string>] [--xen-file-size=<gigabytes>]
- [--xen-ram=<megabytes>]
+ [--virt-name=<string>] [--virt-file-size=<gigabytes>]
+ [--virt-ram=<megabytes>]
cobbler system add --name=<ip│mac│hostname|default> --profile=<string>
[--pxe-address=<string>]
@@ -103,11 +103,11 @@ _msg_table = {
"copying" : "copying file: %s to %s",
"removing" : "removing: %s",
"no_initrd" : "cannot find initrd",
- "exc_xen_name" : "invalid Xen name",
- "exc_xen_file" : "invalid Xen file size",
- "exc_xen_ram" : "invalid Xen RAM size",
- "exc_xen_mac" : "invalid Xen mac address",
- "exc_xen_para" : "invalid Xen paravirtualization setting",
+ "exc_virt_name" : "invalid name for virtual image",
+ "exc_virt_file" : "invalid file size for virtual image",
+ "exc_virt_ram" : "invalid RAM size for virtual image",
+ "exc_virt_mac" : "invalid MAC address for virtual image",
+ "exc_virt_para" : "invalid paravirtualization setting",
"exc_profile" : "invalid profile name",
"exc_profile2" : "profile name not set",
"exc_pxe_arch" : "valid PXE architectures: standard or ia64",
diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py
index 71cbd9f..717d19c 100644
--- a/cobbler/collection_profiles.py
+++ b/cobbler/collection_profiles.py
@@ -1,7 +1,7 @@
"""
A profile represents a distro paired with a kickstart file.
For instance, FC5 with a kickstart file specifying OpenOffice
-might represent a 'desktop' profile. For Xen, there are many
+might represent a 'desktop' profile. For Virt, there are many
additional options, with client-side defaults (not kept here).
Copyright 2006, Red Hat, Inc
diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py
index 9b9edc5..311b54f 100644
--- a/cobbler/item_profile.py
+++ b/cobbler/item_profile.py
@@ -1,5 +1,5 @@
"""
-A Cobbler Profile. A profile is a reference to a distribution, possibly some kernel options, possibly some Xen options, and some kickstart data.
+A Cobbler Profile. A profile is a reference to a distribution, possibly some kernel options, possibly some Virt options, and some kickstart data.
Copyright 2006, Red Hat, Inc
Michael DeHaan <mdehaan@redhat.com>
@@ -23,6 +23,7 @@ class Profile(item.Item):
Constructor. Requires a backreference to Config.
"""
self.config = config
+ self.settings = self.config.settings()
self.clear()
def clear(self):
@@ -31,13 +32,13 @@ class Profile(item.Item):
"""
self.name = None
self.distro = None # a name, not a reference
- self.kickstart = None
+ self.kickstart = self.settings.default_kickstart
self.kernel_options = ''
self.ks_meta = ''
- self.xen_name = 'xenguest'
- self.xen_file_size = 5 # GB. 5 = Decent _minimum_ default for FC5.
- self.xen_ram = 512 # MB. Install with 256 not likely to pass
- self.xen_paravirt = True # hvm support is *NOT* in Koan (now)
+ self.virt_name = 'virtguest'
+ self.virt_file_size = 5 # GB. 5 = Decent _minimum_ default for FC5.
+ self.virt_ram = 512 # MB. Install with 256 not likely to pass
+ self.virt_paravirt = True # hvm support is *NOT* in Koan (now)
def from_datastruct(self,seed_data):
"""
@@ -48,12 +49,22 @@ class Profile(item.Item):
self.kickstart = self.load_item(seed_data,'kickstart')
self.kernel_options = self.load_item(seed_data,'kernel_options')
self.ks_meta = self.load_item(seed_data,'ks_meta')
- self.xen_name = self.load_item(seed_data,'xen_name')
- if not self.xen_name or self.xen_name == '':
- self.xen_name = self.name
- self.xen_ram = self.load_item(seed_data,'xen_ram')
- self.xen_file_size = self.load_item(seed_data,'xen_file_size')
- self.xen_paravirt = self.load_item(seed_data,'xen_paravirt')
+
+ # virt specific
+ self.virt_name = self.load_item(seed_data,'virt_name')
+ self.virt_ram = self.load_item(seed_data,'virt_ram')
+ self.virt_file_size = self.load_item(seed_data,'virt_file_size')
+ self.virt_paravirt = self.load_item(seed_data,'virt_paravirt')
+
+ # support for older versions of the cobbler files (backwards compat)...
+ self.virt_name = self.load_item(seed_data,'xen_name')
+ if not self.virt_name or self.virt_name == '':
+ self.virt_name = self.name
+ self.virt_ram = self.load_item(seed_data,'xen_ram')
+ self.virt_file_size = self.load_item(seed_data,'xen_file_size')
+ self.virt_paravirt = self.load_item(seed_data,'xen_paravirt')
+
+
return self
def set_distro(self,distro_name):
@@ -76,11 +87,11 @@ class Profile(item.Item):
return True
raise cexceptions.CobblerException("no_kickstart")
- def set_xen_name(self,str):
+ def set_virt_name(self,str):
"""
- For Xen only.
- Specifies what xenguest install should use for --name.
- xen-net-install may do conflict resolution, so this is mostly
+ For Virt only.
+ Specifies what virt install should use for --name.
+ virt install may do conflict resolution, so this is mostly
a hint... To keep the shell happy, the 'str' cannot
contain wildcards or slashes and may be subject to some other
untainting later.
@@ -88,14 +99,14 @@ class Profile(item.Item):
# no slashes or wildcards
for bad in [ '/', '*', '?' ]:
if str.find(bad) != -1:
- raise cexceptions.CobblerException("exc_xen_name")
- self.xen_name = str
+ raise cexceptions.CobblerException("exc_virt_name")
+ self.virt_name = str
return True
-
- def set_xen_file_size(self,num):
+
+ def set_virt_file_size(self,num):
"""
- For Xen only.
- Specifies the size of the Xen image in gigabytes. xen-net-install
+ For Virt only.
+ Specifies the size of the virt image in gigabytes. koan
may contain some logic to ignore 'illogical' values of this size,
though there are no guarantees. 0 tells koan to just
let it pick a semi-reasonable size. When in doubt, specify the
@@ -105,36 +116,35 @@ class Profile(item.Item):
try:
inum = int(num)
if inum != float(num):
- return cexceptions.CobblerException("exc_xen_file")
+ return cexceptions.CobblerException("exc_virt_file")
if inum >= 0:
- self.xen_file_size = inum
+ self.virt_file_size = inum
return True
- return cexceptions.CobblerException("exc_xen_file")
+ return cexceptions.CobblerException("exc_virt_file")
except:
- return cexceptions.CobblerException("exc_xen_file")
+ return cexceptions.CobblerException("exc_virt_file")
- def set_xen_ram(self,num):
+ def set_virt_ram(self,num):
"""
- For Xen only.
- Specifies the size of the Xen RAM in MB.
+ For Virt only.
+ Specifies the size of the Virt RAM in MB.
0 tells Koan to just choose a reasonable default.
"""
# num is a non-negative integer (0 means default)
try:
inum = int(num)
if inum != float(num):
- return cexceptions.CobblerException("exc_xen_ram")
+ return cexceptions.CobblerException("exc_virt_ram")
if inum >= 0:
- self.xen_ram = inum
+ self.virt_ram = inum
return True
- return cexceptions.CobblerException("exc_xen_ram")
+ return cexceptions.CobblerException("exc_virt_ram")
except:
- return cexceptions.CobblerException("exc_xen_ram")
-
+ return cexceptions.CobblerException("exc_virt_ram")
- def set_xen_paravirt(self,truthiness):
+ def set_virt_paravirt(self,truthiness):
"""
- For Xen only.
+ For Virt only.
Specifies whether the system is a paravirtualized system or not.
For ordinary computers, you want to pick 'true'. Method accepts string
'true'/'false' in all cases, or Python True/False.
@@ -144,19 +154,19 @@ class Profile(item.Item):
# the string "foosball" is True, and that is not a valid argument for this function
try:
if (not truthiness or truthiness.lower() == 'false'):
- self.xen_paravirt = False
+ self.virt_paravirt = False
elif (truthiness or truthiness.lower() == 'true'):
- self.xen_paravirt = True
+ self.virt_paravirt = True
else:
- return cexceptions.CobblerException("exc_xen_para")
+ return cexceptions.CobblerException("exc_virt_para")
except:
- return cexceptions.CobblerException("exc_xen_para")
+ return cexceptions.CobblerException("exc_virt_para")
return True
def is_valid(self):
"""
A profile only needs a name and a distro. Kickstart info,
- as well as Xen info, are optional. (Though I would say provisioning
+ as well as Virt info, are optional. (Though I would say provisioning
without a kickstart is *usually* not a good idea).
"""
for x in (self.name, self.distro):
@@ -169,15 +179,15 @@ class Profile(item.Item):
Return hash representation for the serializer
"""
return {
- 'name' : self.name,
- 'distro' : self.distro,
- 'kickstart' : self.kickstart,
- 'kernel_options' : self.kernel_options,
- 'xen_name' : self.xen_name,
- 'xen_file_size' : self.xen_file_size,
- 'xen_ram' : self.xen_ram,
- 'xen_paravirt' : self.xen_paravirt,
- 'ks_meta' : self.ks_meta
+ 'name' : self.name,
+ 'distro' : self.distro,
+ 'kickstart' : self.kickstart,
+ 'kernel_options' : self.kernel_options,
+ 'virt_name' : self.virt_name,
+ 'virt_file_size' : self.virt_file_size,
+ 'virt_ram' : self.virt_ram,
+ 'virt_paravirt' : self.virt_paravirt,
+ 'ks_meta' : self.ks_meta
}
def printable(self,id):
@@ -189,9 +199,9 @@ class Profile(item.Item):
buf = buf + "kickstart : %s\n" % self.kickstart
buf = buf + "kernel options : %s\n" % self.kernel_options
buf = buf + "ks metadata : %s\n" % self.ks_meta
- buf = buf + "xen name : %s\n" % self.xen_name
- buf = buf + "xen file size : %s\n" % self.xen_file_size
- buf = buf + "xen ram : %s\n" % self.xen_ram
- buf = buf + "xen paravirt : %s\n" % self.xen_paravirt
+ buf = buf + "virt name : %s\n" % self.virt_name
+ buf = buf + "virt file size : %s\n" % self.virt_file_size
+ buf = buf + "virt ram : %s\n" % self.virt_ram
+ buf = buf + "virt paravirt : %s\n" % self.virt_paravirt
return buf
diff --git a/cobbler/settings.py b/cobbler/settings.py
index 9e03666..276e1ed 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -17,6 +17,27 @@ import utils
TESTMODE = False
+DEFAULTS = {
+ "httpd_bin" : "/usr/sbin/httpd",
+ "dhcpd_conf" : "/etc/dhcpd.conf",
+ "tftpd_bin" : "/usr/sbin/in.tftpd",
+ "server" : "127.0.0.1",
+ "next_server" : "127.0.0.1",
+ "dhcpd_bin" : "/usr/sbin/dhcpd",
+ "kernel_options" : "append devfs=nomount ramdisk_size=16438 lang= vga=788 ksdevice=eth0",
+ "tftpd_conf" : "/etc/xinetd.d/tftp",
+ "tftpboot" : "/tftpboot",
+ "webdir" : "/var/www/cobbler",
+ "default_kickstart" : "/etc/cobbler/default.ks",
+ "manage_dhcp" : 0,
+ "koan_path" : "",
+ "bootloaders" : {
+ "standard" : "/usr/lib/syslinux/pxelinux.0",
+ "ia64" : "/var/lib/cobbler/elilo-3.6-ia64.efi"
+ }
+}
+
+
class Settings(serializable.Serializable):
def filename(self):
@@ -38,24 +59,7 @@ class Settings(serializable.Serializable):
"""
Reset this object to reasonable default values.
"""
- self._attributes = {
- "httpd_bin" : "/usr/sbin/httpd",
- "dhcpd_conf" : "/etc/dhcpd.conf",
- "tftpd_bin" : "/usr/sbin/in.tftpd",
- "server" : "127.0.0.1",
- "next_server" : "127.0.0.1",
- "dhcpd_bin" : "/usr/sbin/dhcpd",
- "kernel_options" : "append devfs=nomount ramdisk_size=16438 lang= vga=788 ksdevice=eth0",
- "tftpd_conf" : "/etc/xinetd.d/tftp",
- "tftpboot" : "/tftpboot",
- "webdir" : "/var/www/cobbler",
- "manage_dhcp" : 0,
- "koan_path" : "",
- "bootloaders" : {
- "standard" : "/usr/lib/syslinux/pxelinux.0",
- "ia64" : "/var/lib/cobbler/elilo-3.6-ia64.efi"
- }
- }
+ self._attributes = DEFAULTS
def printable(self):
buf = ""
@@ -82,6 +86,10 @@ class Settings(serializable.Serializable):
def __getattr__(self,name):
if self._attributes.has_key(name):
return self._attributes[name]
+ elif DEFAULTS.has_key(name):
+ lookup = DEFAULTS[name]
+ self._attributes[name] = lookup
+ return lookup
else:
raise AttributeError, name
diff --git a/default.ks b/default.ks
new file mode 100644
index 0000000..42c3cf8
--- /dev/null
+++ b/default.ks
@@ -0,0 +1,2 @@
+# this file intentionally left blank
+# admins: edit it as you like, or leave it blank for non-interactive install
diff --git a/setup.py b/setup.py
index 2b060f9..803adeb 100644
--- a/setup.py
+++ b/setup.py
@@ -4,11 +4,10 @@ import sys
from distutils.core import setup, Extension
import string
-VERSION = "0.2.8"
+VERSION = "0.3.1"
SHORT_DESC = "Boot server configurator"
LONG_DESC = """
-Cobbler is a command line tool for simplified configuration of boot/provisioning servers. It is also accessible as a Python library. Cobbler supports PXE, Xen, and re-provisioning an existing Linux system via auto-kickstart. The last two modes require 'koan' to be run on the remote system.
-
+Cobbler is a command line tool for configuration of boot/provisioning servers. It is also accessible as a Python library. Cobbler supports PXE, provisioning virtualized ("virt") images, and reinstalling machines that are already up and running (over SSH). The last two modes require a helper tool called 'koan' that integrates with cobbler. Cobbler's advanced features include importing distributions from rsync mirrors, kickstart templating, and managing dhcpd.conf.
"""
if __name__ == "__main__":
@@ -31,6 +30,7 @@ if __name__ == "__main__":
(wwwpath, []),
(cobpath, ['elilo-3.6-ia64.efi']),
(etcpath, ['kickstart_fc5.ks']),
+ (etcpath, ['default.ks']),
(etcpath, ['dhcp.template']),
(manpath, ['cobbler.1.gz'])
],
diff --git a/tests/tests.py b/tests/tests.py
index 243934b..e4dc8a3 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -170,25 +170,25 @@ class Additions(BootTest):
self.assertTrue(profile.set_kickstart("ftp://bar"))
self.assertTrue(profile.set_kickstart("nfs://bar"))
- def test_profile_xen_parameter_checking(self):
+ def test_profile_virt_parameter_checking(self):
profile = self.api.new_profile()
self.assertTrue(profile.set_name("testprofile12b"))
self.assertTrue(profile.set_distro("testdistro0"))
self.assertTrue(profile.set_kickstart("http://127.0.0.1/foo"))
# no slashes or wildcards in name
- self.assertTrue(profile.set_xen_name("xen"))
- self.assertTrue(profile.set_xen_name("xen"))
- self.failUnlessRaises(CobblerException, profile.set_xen_name, "xen/foo")
- self.failUnlessRaises(CobblerException, profile.set_xen_name, "xen*foo")
- self.failUnlessRaises(CobblerException, profile.set_xen_name, "xen?foo")
+ self.assertTrue(profile.set_virt_name("virt"))
+ self.assertTrue(profile.set_virt_name("virt"))
+ self.failUnlessRaises(CobblerException, profile.set_virt_name, "virt/foo")
+ self.failUnlessRaises(CobblerException, profile.set_virt_name, "virt*foo")
+ self.failUnlessRaises(CobblerException, profile.set_virt_name, "virt?foo")
# sizes must be integers
- self.assertTrue(profile.set_xen_file_size("54321"))
+ self.assertTrue(profile.set_virt_file_size("54321"))
# temporarily commenting out failing test
- # self.failUnlessRaises(CobblerException, profile.set_xen_file_size, "huge")
- # self.failUnlessRaises(CobblerException, profile.set_xen_file_size, "54321.23")
+ # self.failUnlessRaises(CobblerException, profile.set_virt_file_size, "huge")
+ # self.failUnlessRaises(CobblerException, profile.set_virt_file_size, "54321.23")
# paravirt must be 'true' or 'false'
- self.assertTrue(profile.set_xen_paravirt(False))
- self.assertTrue(profile.set_xen_paravirt(True))
+ self.assertTrue(profile.set_virt_paravirt(False))
+ self.assertTrue(profile.set_virt_paravirt(True))
self.assertTrue(self.api.profiles().add(profile))
def test_invalid_system_bad_name_host(self):
@@ -307,11 +307,11 @@ class TestImport(BootTest):
# below:
# partial name of distro: current count, passing count, required arch
haystacks = {
- "import_testdata/RHEL-4/U4/AS/ia64/tree/images/pxeboot" : [0, 1, "ia64" ],
- "import_testdata/RHEL-4/U4/AS/i386/tree/images/pxeboot" : [0, 1, "x86" ],
- "import_testdata/RHEL-4/U4/AS/x86_64/tree/images/pxeboot" : [0, 1, "x86_64" ],
- "import_testdata/core/5/i386/os/images/pxeboot" : [ 0, 1, "x86" ],
- "import_testdata/core/5/i386/os/images/xen" : [0, 1, "x86" ],
+ "import_testdata_RHEL-4_U4_AS_ia64_tree_images_pxeboot" : [0, 1, "ia64" ],
+ "import_testdata_RHEL-4_U4_AS_i386_tree_images_pxeboot" : [0, 1, "x86" ],
+ "import_testdata_RHEL-4_U4_AS_x86_64_tree_images_pxeboot" : [0, 1, "x86_64" ],
+ "import_testdata_core_5_i386_os_images_pxeboot" : [ 0, 1, "x86" ],
+ "import_testdata_core_5_i386_os_images_xen" : [0, 1, "x86" ],
}
# first go through all found distros and count the matches