Merge lp:~andreserl/ubuntu/natty/cobbler/lp731620 into lp:ubuntu/natty/cobbler

Proposed by Andres Rodriguez
Status: Superseded
Proposed branch: lp:~andreserl/ubuntu/natty/cobbler/lp731620
Merge into: lp:ubuntu/natty/cobbler
Diff against target: 55544 lines (+53908/-0) (has conflicts)
301 files modified
.bzrignore (+1/-0)
AUTHORS (+95/-0)
CHANGELOG (+912/-0)
COPYING (+340/-0)
MANIFEST.in (+13/-0)
README (+9/-0)
aux/anamon (+280/-0)
aux/anamon.init (+101/-0)
cobbler.spec (+266/-0)
cobbler/action_acl.py (+120/-0)
cobbler/action_buildiso.py (+447/-0)
cobbler/action_check.py (+482/-0)
cobbler/action_dlcontent.py (+96/-0)
cobbler/action_hardlink.py (+60/-0)
cobbler/action_import.py (+1332/-0)
cobbler/action_litesync.py (+167/-0)
cobbler/action_log.py (+71/-0)
cobbler/action_power.py (+150/-0)
cobbler/action_replicate.py (+357/-0)
cobbler/action_report.py (+365/-0)
cobbler/action_reposync.py (+568/-0)
cobbler/action_status.py (+172/-0)
cobbler/action_sync.py (+259/-0)
cobbler/action_validate.py (+119/-0)
cobbler/api.py (+947/-0)
cobbler/cexceptions.py (+44/-0)
cobbler/cli.py (+553/-0)
cobbler/clogger.py (+89/-0)
cobbler/cobblerd.py (+145/-0)
cobbler/codes.py (+98/-0)
cobbler/collection.py (+444/-0)
cobbler/collection_distros.py (+103/-0)
cobbler/collection_files.py (+63/-0)
cobbler/collection_images.py (+78/-0)
cobbler/collection_mgmtclasses.py (+64/-0)
cobbler/collection_packages.py (+63/-0)
cobbler/collection_profiles.py (+82/-0)
cobbler/collection_repos.py (+77/-0)
cobbler/collection_systems.py (+69/-0)
cobbler/config.py (+298/-0)
cobbler/configgen.py (+156/-0)
cobbler/couch.py (+101/-0)
cobbler/field_info.py (+170/-0)
cobbler/func_utils.py (+34/-0)
cobbler/item.py (+407/-0)
cobbler/item_distro.py (+246/-0)
cobbler/item_file.py (+82/-0)
cobbler/item_image.py (+197/-0)
cobbler/item_mgmtclass.py (+64/-0)
cobbler/item_package.py (+64/-0)
cobbler/item_profile.py (+240/-0)
cobbler/item_repo.py (+198/-0)
cobbler/item_system.py (+676/-0)
cobbler/kickgen.py (+200/-0)
cobbler/module_loader.py (+106/-0)
cobbler/modules/add_post_distro_tftp_copy_fetchable_files.py (+53/-0)
cobbler/modules/authn_configfile.py (+84/-0)
cobbler/modules/authn_denyall.py (+51/-0)
cobbler/modules/authn_ldap.py (+136/-0)
cobbler/modules/authn_passthru.py (+47/-0)
cobbler/modules/authn_spacewalk.py (+154/-0)
cobbler/modules/authn_testing.py (+50/-0)
cobbler/modules/authz_allowall.py (+50/-0)
cobbler/modules/authz_configfile.py (+65/-0)
cobbler/modules/authz_ownership.py (+205/-0)
cobbler/modules/install_post_log.py (+51/-0)
cobbler/modules/install_post_power.py (+53/-0)
cobbler/modules/install_post_report.py (+101/-0)
cobbler/modules/install_pre_clear_anamon_logs.py (+74/-0)
cobbler/modules/install_pre_log.py (+31/-0)
cobbler/modules/manage_bind.py (+332/-0)
cobbler/modules/manage_dnsmasq.py (+205/-0)
cobbler/modules/manage_import_debian.old (+727/-0)
cobbler/modules/manage_import_debian_ubuntu.py (+777/-0)
cobbler/modules/manage_import_redhat.py (+972/-0)
cobbler/modules/manage_import_ubuntu.old (+727/-0)
cobbler/modules/manage_import_vmware.py (+862/-0)
cobbler/modules/manage_in_tftpd.py (+144/-0)
cobbler/modules/manage_isc.py (+201/-0)
cobbler/modules/manage_tftpd_py.py (+109/-0)
cobbler/modules/scm_track.py (+109/-0)
cobbler/modules/serializer_catalog.py (+241/-0)
cobbler/modules/serializer_couch.py (+136/-0)
cobbler/modules/sync_post_restart_services.py (+66/-0)
cobbler/modules/sync_post_tftp_copy_fetchable_files.py (+48/-0)
cobbler/pxegen.py (+836/-0)
cobbler/remote.py (+2547/-0)
cobbler/resource.py (+75/-0)
cobbler/serializer.py (+168/-0)
cobbler/services.py (+462/-0)
cobbler/settings.py (+170/-0)
cobbler/sub_process.py (+1149/-0)
cobbler/templar.py (+171/-0)
cobbler/template_api.py (+212/-0)
cobbler/test_basic.py (+894/-0)
cobbler/utils.py (+2071/-0)
cobbler/yumgen.py (+120/-0)
cobbler4j/.classpath (+9/-0)
cobbler4j/.externalToolBuilders/Ant Builder.launch (+18/-0)
cobbler4j/.project (+23/-0)
cobbler4j/README (+24/-0)
cobbler4j/build.py (+143/-0)
cobbler4j/build.xml (+61/-0)
cobbler4j/notes.txt (+458/-0)
cobbler4j/object_base.tmpl (+145/-0)
cobbler4j/pom.xml (+130/-0)
cobbler4j/src/main/java/org/fedorahosted/cobbler/CobblerConnection.java (+106/-0)
cobbler4j/src/main/java/org/fedorahosted/cobbler/CobblerObject.java (+238/-0)
cobbler4j/src/main/java/org/fedorahosted/cobbler/Finder.java (+118/-0)
cobbler4j/src/main/java/org/fedorahosted/cobbler/ObjectType.java (+46/-0)
cobbler4j/src/main/java/org/fedorahosted/cobbler/PropertyLoader.java (+56/-0)
cobbler4j/src/main/java/org/fedorahosted/cobbler/XmlRpcException.java (+51/-0)
cobbler4j/src/test/java/org/fedorahosted/cobbler/test/Config.java (+44/-0)
cobbler4j/src/test/java/org/fedorahosted/cobbler/test/DistroTests.java (+107/-0)
cobbler4j/src/test/java/org/fedorahosted/cobbler/test/FinderTests.java (+25/-0)
cobbler4j/src/test/java/org/fedorahosted/cobbler/test/Fixture.java (+34/-0)
cobbler4j/src/test/java/org/fedorahosted/cobbler/test/ProfileTests.java (+119/-0)
cobbler4j/src/test/java/org/fedorahosted/cobbler/test/RepoTests.java (+106/-0)
cobbler4j/user.properties.sample (+6/-0)
config/auth.conf (+2/-0)
config/cheetah_macros (+2/-0)
config/cobbler.conf (+32/-0)
config/cobbler_bash (+87/-0)
config/cobbler_web.conf (+27/-0)
config/cobblerd (+141/-0)
config/cobblerd_rotate (+28/-0)
config/completions (+508/-0)
config/modules.conf (+86/-0)
config/rsync.exclude (+12/-0)
config/settings (+342/-0)
config/users.conf (+28/-0)
config/users.digest (+1/-0)
contrib/cobbler_sync_master (+193/-0)
debian/README.source (+8/-0)
debian/changelog (+92/-0)
debian/cobbler-common.dirs (+12/-0)
debian/cobbler-common.install (+50/-0)
debian/cobbler-web.install (+2/-0)
debian/cobbler-web.postinst (+22/-0)
debian/cobbler-web.postrm (+20/-0)
debian/cobbler.dirs (+2/-0)
debian/cobbler.docs (+1/-0)
debian/cobbler.install (+4/-0)
debian/cobbler.postinst (+8/-0)
debian/cobbler.postrm (+8/-0)
debian/cobbler.upstart (+14/-0)
debian/compat (+1/-0)
debian/control (+132/-0)
debian/copyright (+452/-0)
debian/koan.dirs (+3/-0)
debian/koan.install (+4/-0)
debian/libcobbler4j-java.jlibs (+1/-0)
debian/patches/05_cobbler_fix_reposync_permissions.patch (+12/-0)
debian/patches/12_fix_dhcp_restart.patch (+12/-0)
debian/patches/21_cobbler_use_netboot.patch (+17/-0)
debian/patches/30_cobbler4j_redstone.patch (+21/-0)
debian/patches/31_add_ubuntu_koan_utils_support.patch (+35/-0)
debian/patches/32_fix_koan_import_yum.patch (+60/-0)
debian/patches/series (+6/-0)
debian/pycompat (+1/-0)
debian/python-cobbler.install (+1/-0)
debian/python-cobbler.postinst (+12/-0)
debian/rules (+47/-0)
debian/source/format (+1/-0)
docs/cobbler-register.pod (+39/-0)
docs/cobbler.pod (+993/-0)
docs/koan.pod (+112/-0)
kickstarts/default.ks (+2/-0)
kickstarts/legacy.ks (+62/-0)
kickstarts/pxerescue.ks (+15/-0)
kickstarts/sample.ks (+69/-0)
kickstarts/sample.seed (+96/-0)
kickstarts/sample_end.ks (+75/-0)
koan/app.py (+1656/-0)
koan/configurator.py (+307/-0)
koan/imagecreate.py (+192/-0)
koan/opt_parse.py (+1682/-0)
koan/qcreate.py (+212/-0)
koan/register.py (+196/-0)
koan/sub_process.py (+1149/-0)
koan/text_wrap.py (+354/-0)
koan/utils.py (+548/-0)
koan/vmwcreate.py (+175/-0)
koan/xencreate.py (+193/-0)
scripts/cobbler (+36/-0)
scripts/cobbler-ext-nodes (+21/-0)
scripts/cobbler-register (+19/-0)
scripts/cobblerd (+97/-0)
scripts/debuginator.py (+50/-0)
scripts/demo_connect.py (+44/-0)
scripts/index.py (+199/-0)
scripts/koan (+19/-0)
scripts/services.py (+99/-0)
scripts/tftpd.py (+1064/-0)
scripts/zpxe.rexx (+298/-0)
setup.cfg (+19/-0)
setup.py (+276/-0)
snippets/cobbler_register (+13/-0)
snippets/download_config_files (+18/-0)
snippets/func_install_if_enabled (+4/-0)
snippets/func_register_if_enabled (+26/-0)
snippets/keep_cfengine_keys (+97/-0)
snippets/keep_files (+156/-0)
snippets/keep_rhn_keys (+88/-0)
snippets/keep_ssh_host_keys (+107/-0)
snippets/kickstart_done (+76/-0)
snippets/kickstart_start (+32/-0)
snippets/koan_environment (+4/-0)
snippets/log_ks_post (+2/-0)
snippets/log_ks_pre (+12/-0)
snippets/main_partition_select (+3/-0)
snippets/network_config (+85/-0)
snippets/partition_select (+34/-0)
snippets/post_anamon (+23/-0)
snippets/post_install_kernel_options (+7/-0)
snippets/post_install_network_config (+372/-0)
snippets/post_koan_add_reinstall_entry (+6/-0)
snippets/post_s390_reboot (+67/-0)
snippets/pre_anamon (+4/-0)
snippets/pre_install_network_config (+92/-0)
snippets/pre_partition_select (+33/-0)
snippets/redhat_register (+18/-0)
templates/etc/dhcp.template (+62/-0)
templates/etc/dnsmasq.template (+20/-0)
templates/etc/named.template (+31/-0)
templates/etc/rsync.template (+43/-0)
templates/etc/tftpd.template (+19/-0)
templates/etc/zone.template (+13/-0)
templates/ldap/ldap_authconfig.template (+1/-0)
templates/power/power_apc_snmp.template (+1/-0)
templates/power/power_bladecenter.template (+1/-0)
templates/power/power_bullpap.template (+1/-0)
templates/power/power_drac.template (+4/-0)
templates/power/power_ether_wake.template (+9/-0)
templates/power/power_ilo.template (+2/-0)
templates/power/power_integrity.template (+1/-0)
templates/power/power_ipmilan.template (+2/-0)
templates/power/power_ipmitool.template (+1/-0)
templates/power/power_lpar.template (+3/-0)
templates/power/power_rsa.template (+1/-0)
templates/power/power_virsh.template (+32/-0)
templates/power/power_wti.template (+1/-0)
templates/pxe/efidefault.template (+4/-0)
templates/pxe/grubprofile.template (+4/-0)
templates/pxe/grubsystem.template (+4/-0)
templates/pxe/pxedefault.template (+15/-0)
templates/pxe/pxelocal.template (+9/-0)
templates/pxe/pxelocal_ia64.template (+4/-0)
templates/pxe/pxelocal_s390x.template (+1/-0)
templates/pxe/pxeprofile.template (+5/-0)
templates/pxe/pxeprofile_esxi.template (+6/-0)
templates/pxe/pxeprofile_s390x.template (+11/-0)
templates/pxe/pxesystem.template (+8/-0)
templates/pxe/pxesystem_esxi.template (+8/-0)
templates/pxe/pxesystem_ia64.template (+6/-0)
templates/pxe/pxesystem_ppc.template (+11/-0)
templates/pxe/pxesystem_s390x.template (+11/-0)
templates/pxe/s390x_conf.template (+77/-0)
templates/pxe/s390x_parm.template (+21/-0)
templates/reporting/build_report_email.template (+46/-0)
tests/multi.py (+29/-0)
tests/performance.py (+70/-0)
tests/pycallgraph_mod.py (+228/-0)
web/cobbler_web/templates/blank.tmpl (+12/-0)
web/cobbler_web/templates/check.tmpl (+14/-0)
web/cobbler_web/templates/empty.tmpl (+9/-0)
web/cobbler_web/templates/enoaccess.tmpl (+12/-0)
web/cobbler_web/templates/error_page.tmpl (+14/-0)
web/cobbler_web/templates/eventlog.tmpl (+14/-0)
web/cobbler_web/templates/events.tmpl (+33/-0)
web/cobbler_web/templates/generic_delete.tmpl (+27/-0)
web/cobbler_web/templates/generic_edit.tmpl (+536/-0)
web/cobbler_web/templates/generic_list.tmpl (+188/-0)
web/cobbler_web/templates/generic_rename.tmpl (+35/-0)
web/cobbler_web/templates/header.tmpl (+3/-0)
web/cobbler_web/templates/import.tmpl (+50/-0)
web/cobbler_web/templates/index.tmpl (+11/-0)
web/cobbler_web/templates/item.tmpl (+38/-0)
web/cobbler_web/templates/ksfile_edit.tmpl (+62/-0)
web/cobbler_web/templates/ksfile_list.tmpl (+32/-0)
web/cobbler_web/templates/master.tmpl (+84/-0)
web/cobbler_web/templates/message.tmpl (+13/-0)
web/cobbler_web/templates/paginate.tmpl (+186/-0)
web/cobbler_web/templates/settings.tmpl (+30/-0)
web/cobbler_web/templates/snippet_edit.tmpl (+72/-0)
web/cobbler_web/templates/snippet_list.tmpl (+31/-0)
web/cobbler_web/templates/task_created.tmpl (+10/-0)
web/cobbler_web/templatetags/site.py (+361/-0)
web/cobbler_web/urls.py (+47/-0)
web/cobbler_web/views.py (+1120/-0)
web/content/cobbler.js (+49/-0)
web/content/index.html (+10/-0)
web/content/jquery-1.3.2.js (+4376/-0)
web/content/jquery-1.3.2.min.js (+19/-0)
web/content/jsGrowl.css (+101/-0)
web/content/jsGrowl.js (+269/-0)
web/content/jsGrowl_jquery.js (+29/-0)
web/content/style.css (+47/-0)
web/manage.py (+11/-0)
web/settings.py (+69/-0)
web/urls.py (+18/-0)
Conflict adding file .bzrignore.  Moved existing file to .bzrignore.moved.
Conflict adding file AUTHORS.  Moved existing file to AUTHORS.moved.
Conflict adding file CHANGELOG.  Moved existing file to CHANGELOG.moved.
Conflict adding file COPYING.  Moved existing file to COPYING.moved.
Conflict adding file MANIFEST.in.  Moved existing file to MANIFEST.in.moved.
Conflict adding file README.  Moved existing file to README.moved.
Conflict adding file aux.  Moved existing file to aux.moved.
Conflict adding file cobbler.  Moved existing file to cobbler.moved.
Conflict adding file cobbler.spec.  Moved existing file to cobbler.spec.moved.
Conflict adding file cobbler4j.  Moved existing file to cobbler4j.moved.
Conflict adding file config.  Moved existing file to config.moved.
Conflict adding file contrib.  Moved existing file to contrib.moved.
Conflict adding file debian.  Moved existing file to debian.moved.
Conflict adding file diagrams.  Moved existing file to diagrams.moved.
Conflict adding file docs.  Moved existing file to docs.moved.
Conflict adding file kickstarts.  Moved existing file to kickstarts.moved.
Conflict adding file koan.  Moved existing file to koan.moved.
Conflict adding file scripts.  Moved existing file to scripts.moved.
Conflict adding file setup.cfg.  Moved existing file to setup.cfg.moved.
Conflict adding file setup.py.  Moved existing file to setup.py.moved.
Conflict adding file snippets.  Moved existing file to snippets.moved.
Conflict adding file templates.  Moved existing file to templates.moved.
Conflict adding file tests.  Moved existing file to tests.moved.
Conflict adding file web.  Moved existing file to web.moved.
To merge this branch: bzr merge lp:~andreserl/ubuntu/natty/cobbler/lp731620
Reviewer Review Type Date Requested Status
Chuck Short Pending
Review via email: mp+53091@code.launchpad.net

This proposal has been superseded by a proposal from 2011-03-11.

To post a comment you must log in.

Unmerged revisions

2009. By Andres Rodriguez

Update patch Descriptions

2008. By Andres Rodriguez

* debian/patches/32_fix_koan_import_yum.patch: Fix import error of yum
  python module; adds flexibility for other package managers. (LP: #731620)

2007. By Andres Rodriguez

debian/patches/31_add_ubuntu_koan_utils_support.patch: Add support for ubuntu
distro in koan utils.py.

2006. By Chuck Short

New release

2005. By Chuck Short

New upstream version

2004. By Chuck Short

* New upstream release
* Add python-koan package (LP: #731616):
  - debian/control: Add python-koan binary package; fix typo
  - debian/python-cobbler.install: Do not install koan python modules.
  - debian/python-koan.install: Add. Install koan python modules.

2003. By Chuck Short

Fake changelog

2002. By Chuck Short

Update changelog

2001. By Chuck Short

New upstream release

2000. By Chuck Short

Fix up get-orig-source a bit better

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2011-03-11 21:10:49 +0000
@@ -0,0 +1,1 @@
1.pc
02
=== renamed file '.bzrignore' => '.bzrignore.moved'
=== added file 'AUTHORS'
--- AUTHORS 1970-01-01 00:00:00 +0000
+++ AUTHORS 2011-03-11 21:10:49 +0000
@@ -0,0 +1,95 @@
1Cobbler, Koan, and Cobbler-Web are written & maintained by:
2
3 Michael DeHaan <mdehaan@redhat.com>
4
5Patches and other contributions from:
6
7 Partha Aji <paji@redhat.com>
8 Anton Arapov <aarapov@redhat.com>
9 Niels Basjes <cobbler@basjes.nl>
10 Tim Bielawa <timbielawa@gmail.com>
11 Joseph Boyer Jr. <jboyer@liquidnet.com>
12 Andrew Brown <ambrown@ncsu.edu>
13 David Brown <dmlb2000@gmail.com>
14 James Bowes <jbowes@redhat.com>
15 James Cammarata <jimi@sgnx.net>
16 Jasper Capel <jcapel@redhat.com>
17 C. Daniel Chase <dan@cdchase.com>
18 Gordon Child <gordon@cpanel.net>
19 Cristian Ciupitu <cristian.ciupitu@yahoo.com>
20 Carsten Clasohm <cclasohm@redhat.com>
21 Ian Ward Comfort <icomfort@rescomp.stanford.edu>
22 Rob Crittenden <rcritten@redhat.com>
23 Scott Dodson <sdodson@redhat.com>
24 Charles Duffy <Charles_Duffy@messageone.com>
25 Máirín Duffy <duffy@redhat.com>
26 John Eckersberg <jeckersb@redhat.com>
27 Lee Faus <lfaus@redhat.com>
28 Leonid Flaks <flaks@bnl.gov>
29 Eoghan Gaffney <eoghan@noroutetohost.org>
30 Dan Guernsey <danpg102@gmail.com>
31 Marcel Haerry <haerry+et@puzzle.ch>
32 Peter Halliday <phalliday@excelsiorsystems.net>
33 Niels Hasse <haase.niels@googlemail.com>
34 Dave Hatton <dave@davehatton.it>
35 Scott Henson <shenson@redhat.com>
36 Garrett Holmstrom <garett.holmstrom@gmail.com>
37 Stephan Hauiser <stephan@huiser.nl>
38 Tru Huynh <tru@pasteur.fr>
39 Matt Hyclak <hyclak@math.ohiou.edu>
40 Mihai Ibanescu <mihai.ibanescu@gmail.com>
41 Shuichi Ihara <ihara@sun.com>
42 Pablo Iranzo Gómez <pablo.iranzo@redhat.com>
43 Brian Kearney <bkearney@redhat.com>
44 Henry Kemp <henrykemp@gmail.com>
45 Ruben Kerkhof <ruben@rubenkerkhof.com>
46 Don Khan <khan_don@emc.com>
47 Dominic LoBue <git.20.dlobue@neverbox.com>
48 Gavin Romig-Koch <gavin@redhat.com>
49 James Laska <jlaska@redhat.com>
50 Vito Laurenza <vitolaurenza@gmail.com>
51 Adrian Likins <alikins@redhat.com>
52 David Lutterkort <dlutter@redhat.com>
53 Lester M. <needwork@gmail.com>
54 Bryan Mason <bjmason@redhat.com>
55 Mike McCune <mmccune@redhat.com>
56 Mark McLoughlin <markmc@redhat.com>
57 Jim Meyering <jim@meyering.net>
58 Jeroen van Meeuwen <kanarip@kanarip.com>
59 Sean Millichamp <sean@bruenor.org>
60 Perry Myers <pmyers@redhat.com>
61 Jack Neely <jjneely@ncsu.edu>
62 Javier Palacious <javiplx@gmail.com>
63 Bill Peck <bpeck@redhat.com>
64 Lassi Pölönen <lassi.polonen@helsinki.fi>
65 Jasper Poppe <jpoppe@ebay.com>
66 Dan Radez <dradez@redhat.com>
67 Ben Riggs <rigg0022@umn.edu>
68 Jeremy Rosengren <jeremy@rosengren.org>
69 Adam Rosenwald <thestrider@gmail.com>
70 Christophe Sahut <csahut@nogoa.org>
71 Satoru Satoh <ssato@redhat.com>
72 Jeff Schroeder <jeffschroeder@computer.org>
73 Scott Seago <sseago@redhat.com>
74 Justin Sherill <jsherril@redhat.com>
75 Anderson Silva <ansilva@redhat.com>
76 Joe Smith <yasumoto7@gmail.com>
77 Michael Stahnke <mastahnke@gmail.com>
78 Dylan Swift <dylan.swift@gmail.com>
79 Al Tobey <tobert@gmail.com>
80 Thomas Uhde <thomas.uhde@KabelDeutschland.de>
81 Ronald van den Blink <ronald@a61.nl>
82 Tim Verhoeven <tim.verhoeven.be@gmail.com>
83 John L. Villalovos <john@sodarock.com>
84 Peter Vreman <peter.vreman@acision.com>
85 Adam Wolf <adamwolf@feelslikeburning.com>
86 Simon Woolsgrove <simon@woolsgrove.com>
87 Todd Zullinger <tmz@pobox.com>
88 Kelsey Hightower <kelsey.hightower@gmail.com>
89 Chuck Short <chuck.short@canonical.com>
90 Jonathan Sabo <jonathan.sabo@gmail.com>
91 Douglas Kilpatrick <dkilpatrick@verisign.com>
92
93 [...send patches to get your name here...]
94
95
096
=== renamed file 'AUTHORS' => 'AUTHORS.moved'
=== added file 'CHANGELOG'
--- CHANGELOG 1970-01-01 00:00:00 +0000
+++ CHANGELOG 2011-03-11 21:10:49 +0000
@@ -0,0 +1,912 @@
1Cobbler CHANGELOG
2- Nov 29 2010
3- (FEAT) --force-path to overwrite virt-path file location
4
5- Apr 27 2010 - 2.0.4
6- (BUGF) fetch extra metadata from upstream repositories more safely
7- (BUGF) allow the creation of subprofiles again
8- (BUGF) don't warn needlessly when repo rpm_list is empty
9- (BUGF) run createrepo on partial yum mirrors
10- (BUGF) change default mode for new directories from 0777 to 0755
11- (BUGF) fix replication pruning to not prune systems when inappropriate
12- (BUGF) always authorize the CLI
13- (BUGF) fix passthru auth Trac#549
14- (BUGF) fix for spacewalk bug 529277
15- (BUGF) fix umask so files are not world writable
16- (BUGF) fix default pxe template to support default system record
17- (BUGF) redo the PXE menuif a profile is removed
18- (BUGF) properly escape snippets
19- (FEAT) Support Mercurial (hg) for scm tracking
20
21- Feb 15 2010 - 2.0.3.1
22- (BUGF) Fix kernel command line parsing
23
24- Feb 12 2010 - 2.0.3
25- (FEAT) API Test Framework
26- (FEAT) Cobbler4j Eclipse bindings
27- (BUGF) Trac544 Create noarch and src repos
28- (BUGF) Snippet Cleanups
29- (FEAT) Cleanup Kickstart Generation
30- (FEAT) Ability to include remote kickstart content
31- (FEAT) Koan ability for remote kickstart content
32- (BUGF) Trac547 Profile Creation in WebUI
33- (BUGF) Trac520 Sort HTML Dropdown Lists
34- (BUGF) Allow koan to use http urls for kernel/initrd
35- (FEAT) Cobbler4j now uses maven to build
36- (FEAT) Allow multiple kernel options with the same name
37- (BUGF) Various logging cleanups
38- (BUGF) Exit with proper error codes
39- (BUGF) Fix multiselect fields in the WUI
40- (BUGF) Trac550 stop leaking FDs in subprocess_call
41- (BUGF) Trac566 link distros on replicate
42- (BUGF) Trac563 Replace dos line endings with unix line endings when saving ksdata
43- (FEAT) Support RHEL6 kernel sizes
44- (BUGF) Preserve hardlinks on replicate
45- Full List 2b3a4f960b564691ca9a0470f677bd902f60b021..b99401d4dc6cf7f6c010eecf6c5d235316b59f73
46
47- Nov 23 2009 - 2.0.2
48- (FEAT) Added support for Cobbler4j
49- (FEAT) Added method for enabling autostart on qemu domains
50- (BUGF) web ui: move sessions directory to /var
51- (BUGF) Update the vlanpattern regex to cover more common virtual interface formats
52- (BUGF) cobbler check: fix BIND detection
53- (BUGF) Fix error message creating profile without a distro
54- (BUGF) use proper HTTP error codes
55- (BUGF) Create more intuitive system for displaying actions under configuration items.
56- (BUGF) Fixed hardlinking
57- (BUGF) Creating subprofile in WebUI no longer fails on default_ownership
58- (BUGF) No longer delete excluded files in reposync rsync
59- (BUGF) Add fedora12 and fedora13 as valid 'redhat' versions
60- (BUGF) Correct improper distro creation while importing i386 Fedora/RHEL.
61- (BUGF) Better messaging for invalid object errors
62- (BUGF) Added a legacy sync mechanism
63- (BUGF) No longer bundle libraries on distros where they are already available
64
65- Sep 18 2009 - 2.0.1
66- (BUGF) Fixes for image based CLI usage and object validation
67- (BUGF) Fix koan check for images ... they don't need a kickstart
68- (BUGF) Get NFS image mounting working again
69- (BUGF) Show object name on cobbler-web edit pages
70- (BUGF) Make memtest integration look in the right file locations
71- (BUGF) Fix check for dhcpd installation
72- (BUGF) Fix code to detect dhcpd config file installation
73- (BUGF) Cleaned up generated comments in settings files
74- (BUGF) Unhide per-system post-install kernel options
75- (BUGF) Unhide owners fields
76- (BUGF) Fix "cobbler profile/system dumpvars" command
77- (BUGF) Remove acl_engine reference from authz_configfile
78- (BUGF) Add "View Kickstart" link back on profile list page
79- (FEAT) Very Experimental CouchDB serializer, off by default. Touch /etc/cobbler/use.couch
80- (BUGF) Fix pagination for webapp
81- (BUGF) Widen left column for webapp to better show controls
82- (BUGF) Workaround older mod_python scoping bug with utils.uniquify
83- (BUGF) Fix interface additions from web system edit page for new systems
84- (BUGF) Make cobbler reposync --only=N sync only that repo
85- (BUGF) Mark cobbler_web.conf config(noreplace) in the RPM specfile
86- (BUGF) Have cobbler check look for more SELinux things to do
87- (BUGF) Fix saving of "static" network field in webapp
88- (BUGF) Deepcopy interfaces to prevent copying of interface data
89
90- Sep 17 2009 - for 2.0 release
91- Development release start
92- (FEAT) add two new default flags to yum reposync (-m and -d) for grabbing comps automatically and also deleting duplicate RPMs
93- (BUGF) validate gateway input against python-netaddr
94- (FEAT) --kopts="~foo" --in-place can be used to delete a hash entry without affecting the others, not to be confused with "!foo" to supress it.
95- (FEAT) web app moves to Django
96- (FEAT) koan: Support for virt-autoboot feature (Xen only at this point, needs fixing)
97- (FEAT) koan: use private address range for random MACs
98- (FEAT) yum createrepo flags are now tweakable in settings
99- (FEAT) new snippet for RHN Hosted: keep RHN keys between reinstalls
100- (FEAT) allow per_distro snippets in addition to per_profile/per_system
101- (BUGF) don't add port number to http_server if it's 80.
102- (FEAT) support F11 fence-agent paths
103- (BUGF) koan autodetection now can gather MACs/IPs for bridged interfaces better
104- (FEAT) F11 and RAID support for keep_ssh_host_keys
105- (FEAT) keep_ssh_host_keys gets F11+RAID support
106- (FEAT) per-task logging
107- (BUGF) validateks checkes /every/ kickstart, as different variables may be present
108- (FEAT) CLI now speaks XMLRPC (faster)
109- (FEAT) task engine for webapp
110- (FEAT) background APIs for all actions
111- (FEAT) look at ksdevice when building buildiso CDs to add the proper network lines
112- (BUGF) don't use RPM to check os_version, so RPM won't be called in rpm %post
113- (BUGF) deprecated omapi/omshell features for manage_isc now removed
114- (FEAT) removed configuration files for binary paths, will look for in PATH
115- (FEAT) removed configuration settings indicating where some config files are
116- (FEAT) yum priorities plugin setting for distro repos now tweakable in settings
117- (BUGF) unfinished contrib. debian import/repo support disabled until it can be finished
118- (FEAT) replicate is now greatly improved and smarter
119- (BUGF) aclengine (unfinished feature) removed, (not the same as aclsetup)
120
121- - 1.6.9
122- (FEAT/cobbler) cobbler can now pass the virtio26 os version to virtinst, so virtio drivers can be used for RHEL5
123.3 for instance
124- (BUGF/cobbler) The URL to the WebUI documentation in the manpage was corrected
125- (BUGF/cobbler) add the --nameserver option for static interfaces when defined (snippet fix)
126
127- 1.6.7
128- (BUGF/koan) Workaround for a bug in ybin, use --verbose for happy return codes
129- (BUGF/cobbler) patch to redhat_register for Satellite
130
1311.6.6 (for more accurate listing, see release16 branch)
132- (BUGF) don't use -m option for drac unless power_id is set
133- (BUGF) don't run createrepo on reposync'd repos, it is redundant
134- (BUGF) fix error message when wrong virt ram value is applied
135- (FEAT) koan now partially works in source code form on EL 2
136- (FEAT) discover repomd filenames (for F11 and later)
137- (BUGF) Satellite also has a python module named "server" so we have to remove ours for Python imports. This code was not used anyway.
138- (BUGF) fix typo in network config snippet
139
140- ... - 1.6.5
141- (BUGF) don't use json on python x<=2.3 since we know it's simplejson x<2.0, which has unicode issues
142- (FEAT) support F-11 imports
143- (BUGF) don't add koan virtual interfaces for vlan tagged interfaces
144- (BUGF) pair PAE and non-PAE content in imports better
145- (BUGF) don't try to scp /etc/cobbler/*.ks on replicate, this is an old path
146- (BUGF) set proper umask on .mtime files
147- (BUGF) fix koan error with unspecified arch using --kexec
148- (BUGF) don't use --onboot=on in network config for kickstart for RHEL 3.
149- (FEAT) koan can be built on EL-2
150
151- Fri May 8 2009 - 1.6.4
152- (BUGF) empty nameserver search paths now don't screw up resolv.conf
153- (BUGF) unicode fix for --template-files feature
154- (BUGF) mod python input fix for repo/profile associations in webapp
155- (BUGF) change "hostname" to "option hostname" in dhcp.template
156- (BUGF) fixes for unicode problem with Cheetah, repos, and json
157- (BUGF) unicode fix for --template-files feature
158- (BUGF) another unicode fix
159- (BUGF) bonding interface setup for RHEL4 now works
160- (BUGF) generate DHCP info even if netboot is disabled
161- (BUGF) Change to network_config snippet to ignore bond masters to prevent anaconda failures when MAC addresses are not specified
162- (BUGF) fix to CLI rename deleting subobjects via cobblerd (important!)
163- (BUGF) fix blender cache problem with using dnsnames instead of record names (ISC DHCP management)
164- (BUGF) quote host name in stock ISC template
165
166- XXX - 1.6.3
167- (BUGF) import with datestamp 0 when .discinfo is not found, do not crash
168- (BUGF) various fixes to "cobbler report" when using non-standard formats
169- (BUGF) rename with same name does not delete
170- (BUGF) Fix for traceback when generating DHCP config and the bonding_master interface does not exist.
171- (BUGF) remove trailing newline from tokens
172- (BUGF) fix unicode handling of some fields under EL4
173- (BUGF) fix webui search error (fixed better on devel)
174- (BUGF) fix duplicate power reference
175- (BUGF) fix error message that makes it appear dnsmasq had a problem restarting, when it did not
176- (BUGF) spec requires python-urlgrabber
177- (BUGF) change settings default from 'ksdevice=eth0' to 'bootif'
178- (BUGF) keep DHCP restart quiet
179- (BUGF) better hostname setting with DHCP management on
180- (BUGF) fix bug in repo breed auto-detection code
181- (BUGF) close file descriptors by using subprocess, not os.system
182- (BUGF) make cobbler package Arch for now, require syslinux where it makes sense only. To be changed in later release to download it from intertubes.
183
184- Mon Mar 30 2009 - 1.6.2
185- (BUGF) Fix for cache cleanup problem in cobblerd
186
187- Fri Mar 27 2009 - 1.6.1
188- (FEAT) Improved anaconda monitoring code
189- (FEAT) download comps.xml always (even if yum does not have the option)
190- (FEAT) performance upgrades for cobblerd service to avoid reloads
191- (FEAT) more code for s390 imports (WIP)
192- (BUGF) import works better with rawhide
193- (FEAT) snippet to preserve SSH host keys across reinstalls
194- (FEAT) email trigger to notify when builds finish
195- (FEAT) triggers now are written in Python, old system still exists.
196- (FEAT) s390x zpxe support
197- (BUGF) retry power 5 times before giving up
198- (BUGF) fix for RHEL3 ppc imports
199- (FEAT) use nameserver variable in network config in Anaconda when set
200- (BUGF) sleep 5 seconds between power cycling systems
201- (FEAT) support for /usr/bin/cobbler-register
202- (FEAT) web UI search feature
203- (FEAT) very simple "cobbler hardlink" command to optimize space in /var/www/cobbler
204- (FEAT) new "change" trigger that runs on all adds/edits/removes/syncs
205- (FEAT) an SCM trigger that knows about /var/lib/cobbler kickstarts, snippets, and config directories, and audits them for changes
206- (BUGF) update ctime on object copies
207- (BUGF) fix cobbler check code that makes sure default password is not in use
208- (BUGF) remove duplicate text box for management classes from server edit page
209- (BUGF) fix stderr output on Ctrl+C
210- (BUGF) potential performance savings WRT duplicate python objects
211- (BUGF) don't deserialize during sync, it makes it take twice as long
212- (FEAT) Ubuntu support for import (added/improved)
213- (BUGF) make DHCP managemnet work with bonding
214- (BUGF) teach serializer_catalog to fly with JSON
215- (BUGF) don't use yumdownloader when rpm_list is []
216- (BUGF) fix default kickstart location
217- (BUGF) properly "flatten" environment values for webapp
218- (BUGF) fix for MSIE rendering in web app
219- (BUGF) stop yumdownloader including system yum repos
220- (DOCS) update webui project page link
221- (BUGF) remove caching logic from remote.py
222- (FEAT) added --exclude-dns option to buildiso
223- (BUGF) fix string comparisons to tolerate unicode
224- (BUGF) fix dealing with name servers and name servers search, esp in web app
225
226- Tue Mar 3 2009 - 1.4.3
227- (BUGF) fix OMAPI support's (note: deprecated) usage of subprocess
228- (BUGF) don't traceback on invalid cmd ("cobbler distro list --name=foo")
229- (BUGF) fix import usage with --kickstart option (no more traceback)
230- (BUGF) fix removal of images with child system objects
231- (BUGF) make --rpmlist on repo use same parsing routes as the rest of cobbler
232- (BUGF) default value for server override should be <<inherit>> not <inherit>
233- (BUGF) ensure if virt bridge is set to "" it will apply the value from settings
234- (BUGF) cobbler check should say path to config file is /etc/cobbler, not /var/lib
235- (FEAT) enable cobblerweb username/pass logins when authing with spacewalk
236- (BUGF) allow --kopts to take parameters that are shell quoted.
237- (BUGF) allow kernel options to start with '-'
238- (BUGF) Use shlex for parsing --kopts to allow a wider variety of kernel options
239- (BUGF) prevent potential traceback when --template-file data isn't a hash
240- (BUGF) anaconda doesn't honor nameserver always, set manually
241- (BUGF) various post install network snippet fixes
242- (BUGF) fix OMAPI support's (note: deprecated) usage of subprocess
243- (SPEC) fix build for rawhide now that yaboot is included
244- (BUGF) allow src and noarch arches for repo objects
245- (BUGF) move to PyYAML for YAML implementation since it is better maintained
246- (BUGF) fixed web-interface editing of ownership
247- (BUGF) fixed web-interface editing of management classes
248- (BUGF) don't run full sync in import, sync makes the install system unavailable for very short periods of time
249- (FEAT) XMLRPC functions for searching objects, just like the Python API has
250- (BUGF) make "find repo" CLI command search repos, not systems
251
252- XXX - 1.4.2
253- (BUGF) fix WTI power templates
254- (FEAT) add WTI power type
255- (BUGF) remove Python 2.6/3000 warnings
256- (BUGF) fix typo in network template (DNS enumeration)
257- (BUGF) make buildiso work for systems that are using bonding
258- (BUGF) blending fix for --template-files
259- (BUGF) cobbler check ignores comments in TFTP config
260- (BUGF) fix image type field editing in the webapp
261- (BUGF) allow deletion of eth0 if other interfaces are present
262- (BUGF) fix server-override setting in CLI for profile objects
263- (BUGF) systems and profiles are now sorted for "cobbler buildiso"
264- (BUGF) ensure that directories exist when installing a template file
265- (BUGF) fix for typo in network config snippet
266- (BUGF) fix for func integration script (should overwrite config, not append)
267- (BUGF) append nameservers and gateway, if set, for buildiso
268
269- Fri Jan 09 2009 - 1.4.1
270- (BUGF) Cobbler check looks for right httpd on SUSE
271- (BUGF) post_install_network_config snippet had bash errors
272- (BUGF) don't run restorecon programatically
273- (FEAT) have cobbler check mention when semanage rules should be applied
274- (BUGF) fix an obscure xmlrpclib corner case where a string that looks like an int can't be served because xmlrpclib thinks it's an int. Applies to XMLRPC consumers only, not CobblerWeb or the cobbler CLI.
275- (BUGF) fix external kickstart URLs (not templated) and per-system overrides.
276- (BUGF) fix 'cobbler check' code for SuSE services
277- (FEAT) batch editing on the system page.
278
279- Fri Dec 19 2008 - 1.4
280- (----) Stable release of 1.3 development branch
281
282- Fri Dec 19 2008 - 1.3
283- (FEAT) ACLs to extend authz (see Wiki)
284- (FEAT) puppet integration with --mgmt-classes and external nodes URL
285- (FEAT) added puppet external nodes script, cobbler-ext-nodes
286 see https://fedorahosted.org/cobbler/wiki/UsingCobblerWithConfigManagementSystem
287- (FEAT) ability to use --enable-menu=0/1 to hide profiles from the PXE menu, and config setting to change default value for --enable-menu
288- (FEAT) added livecd based physical machine cloner script to "contrib"
289- (FEAT) enable import for debian ISOs and mirrors (1 distro at a time for now)
290- (FEAT) auto-create rescue profile objects
291- (FEAT) included network_config snippet and added --static=0/1 to system objects
292- (FEAT) cobbler report gains additional options for Wiki formatting, csv, and showing only certain fields
293- (FEAT) changed default kernel options to include ksdevice=bootif (not ksdevice=eth0) and added ipappend 2 to PXE
294- (FEAT) distro edits now no longer require a sync to rebuild the PXE menu
295- (BUGF) minor tweak to the blender function to remove a certain class of typing errors where a string is being blended with a list, should not have any noticable effect on existing installs
296- (BUGF) add missing import of "_" in remote.py
297- (FEAT) upgraded webui editing for multiple NICs
298- (FEAT) "template_universe" variable created for snake's usage, variable contains all template variables and is also passed to the template.
299- (FEAT) refactored import with better Debian/Ubuntu support
300- (FEAT) Func integration snippets and new settings
301- (FEAT) settings file and modules.conf now generated by setup.py using templates
302- (FEAT) --template-files makes cobbler more of a full config management system!
303- (FEAT) cobbler reposync now supports --tries=N and --no-fail
304- (FEAT) duplicate hostname prevention, on by default
305- (FEAT) make import work for Scientific Linux
306- (FEAT) distro remove will remove mirrored content when it's safe to do so
307- (FEAT) repo remove will remove mirrored repo content
308- (FEAT) added snippet for better post-install network configuration
309- (BUGF) duplicate repo supression to prevent errors in certain Andaconda's
310- (FEAT) post_network_snippet/interfaces can set up VLANs
311- (FEAT) call unittests with nose, which offers cleaner output, see tests/README
312- (FEAT) update included elilo to 3.8
313- (BUGF) quote append line for elilo
314- (BUGF) added ExcludeArch: ppc64
315- (FEAT) --environment parameter added to reposync
316- (BUGF) have triggers ignore dotfiles so directories can be version controlled (and so on)
317- (FEAT) init scripts and specfiles now install on SuSE
318- (TEST) added remote tests, moved existing unit tests to api.py methods
319- (FEAT) import can auto assign kickstarts based on distro (feature for beaker)
320- (FEAT) import now saves the dot version of the OS in the comment field
321- (FEAT) import now adds tree build time
322- (FEAT) --comment field added to all objects
323- (FEAT) keep creation and modification times with each object
324- (FEAT) added ppc imports and arches to supplement s390x (and assoc koan chage)
325- (FEAT) added number of interfaces required to each image
326- ~~~ 1.3.2
327- (BUGF) fix for possible import of insecure modules by Cheetah in Cobbler web.
328- (FEAT) new version function
329- (FEAT) misc WUI organization
330- (FEAT) allow auth against multiple LDAP servers
331- (FEAT) replicate now copies image objects
332- (BUGF) replicate now uses higher level API methods to avoid some profile sync errors when distros fail
333- (FEAT) /etc/cobbler/pxe and /etc/cobbler/power are new config file paths
334- (FEAT) /var/lib/cobbler/kickstarts is the new home for kicktart files
335- (FEAT) webui sidebar reorg
336- (FEAT) manage_dhcpd feature (ISC) now checks service status before restarting
337- (BUGF) omapi for manage_dhcp feature (ISC) now defaults to off
338- (FEAT) added module whitelist to settings file
339- (BUGF) don't let the service handler connect to itself over mod_python/proxy, RH 5.3 does not like
340- (FEAT) mtimes and ctimes and uids in the API
341- (FEAT) new functions to get objects based on last modified time, for sync with other apps
342- ~~~ 1.3.3 Test release
343- (FEAT) Python 2.6 specfile changes
344- ~~~ 1.3.X
345- (FEAT) cobbler check output is always logged to /var/log/cobbler/check.log
346- (FEAT) new redhat_register snippet and --redhat-management-key options!
347- (BUGF) SELinux optimizations to symlink/hardlink/chcon/restorecon behavior
348- (----) no SELinux support on EL 4
349- (FEAT) yum_post_install_mirror now on by default
350
351- ??? - 1.2.9
352- (BUGF) do not allow unsafe Cheetah imports
353
354- Wed Oct 15 2008 - 1.2.8
355- (BUGF) make cobbler read /etc/cobbler/settings.py (introduced in 1.2.6)
356
357- Tue Oct 14 2008 - 1.2.7
358- (BUGF) go easier on restrictings when importing subprofiles to prevent load errors
359- (FEAT) added debuginator script to scripts/ (not shipped with RPM)
360
361- Fri Oct 10 2008 - 1.2.6
362- (BUGF) fix image vs system parentage problem affecting cobbler replicate
363- (BUGF) fix restart-services trigger to not restart dns unneccessarily
364- (BUGF) add missing variable newname to signature for remote copy_ functions
365- (BUGF) fix for ownership ownership module when editing kickstarts
366
367- Fri Sep 26 2008 - 1.2.5
368- (BUGF) expose --arch for "cobbler image add"
369- (BUGF) unbreak dnsmasq DHCP management, similar to ISC bug
370- (BUGF) fix --arch for cobbler distro add/edit
371- (BUGF) fix merge error with remote.py's remove_profile function (fix webapp)
372- (BUGF) make keep_updated and mirror_locally checkboxes in WebUI display correctly
373
374- Mon Sep 08 2008 - 1.2.4
375- (BUGF) simple rebuild to remove cli_report.py, which is not in git
376
377- Sun Sep 07 2008 - 1.2.3
378- (BUGF) fix to manage_isc.py code
379
380- Fri Sep 05 2008 - 1.2.2
381- (BUGF) fix to where elilo location is loaded in manage_isc.py
382- (BUGF) populate netboot_enabled in WebUI correctly
383- (BUGF) make RPM own some unowned directories in "triggers"
384- (BUGF) add named_conf setting to settings
385
386- Tue Sep 02 2008 - 1.2.1
387- (BUGF) fix merge problem with 1.2
388
389- Fri Aug 29 2008 - 1.2.0
390- (FEAT) All development work from 1.X merged in
391- (FEAT) when --netboot-enabled is toggled, rather than deleting the PXE config, create a local boot PXE config
392- (BUGF) disable some s390 aspects of cobbler check until it is supported
393- (FEAT) new --os-version, better validation for --breed, --breed/--os-version also for images
394
395- ??? - 1.1.1
396- (FEAT) make template replacement use regex module
397- (BUGF) remove bootloader check in settings as that code doesn't need it
398- (BUGF) refinements to image handling
399- (FEAT) getks command added to command line
400- (BUGF) don't print traceback during certain SystemExits
401- (BUGF) --help now works more intuitively on odd command line usage
402- (BUGF) use pxesystem for systems, not pxeprofile
403- (FEAT) make Cheetah formatting errors contain help text for users
404- (FEAT) --kopts-post can configure post-install kernel options
405- (BUGF) subtemplates are now errorCatcher Echo compatible
406
407- ??? - 1.1.0
408- devel branch
409- added cobbler aclsetup command for running cobbler as non-root
410- added cobbler find command to do searches from the command line
411- fix mkdir invocation
412- improved cobbler replicate, it now can rsync needed files
413- further templatize ISC dhcp config file (pay attention to /etc/cobbler/dhcp.template.rpmnew !)
414- fix for NFS imported URLs during kickstart generation
415- added yumreposync_flags to settings, default "-l" for use plugins
416- added an extra mkdir for rhn's reposync, though I believe the -l cures it already
417- allow mod python bits to work via non-80 http ports
418- when mirroring repos, act as 686 not 386 to get all the kernel updates
419- upgrades to cobbler buildiso
420- added patch to allow --in-place editing of ksmeta/kopts
421- added patch to allow multiple duplicate kernel options
422- fix kickstart serving when the tree is on NFS
423- s390x import, added support for s390x "pseudo-PXE" trees
424- added support for tracking image objects and virtual ISO images
425- support for multiple copies of the same kernel option in kopts
426- add cobbler bash completion script
427- fix bug with 255 kernel options line warning not firing soon enough
428- add findks.cgi support back as http://server/cblr/svc/op/findks
429- merge patch to surface status over API
430- make yum repos served up for /etc/yum.repos.d fully dynamic (mod_python)
431- cobbler find API calls and command line usage can now use fnmatch (wildcards)
432- return code cleanup (0/1 now more predictable)
433- added comments to /etc/cobbler/modules.conf
434- during import non-xen kernels will default --virt-type to qemu
435- when editing/adding profiles, auto-rebuild the PXE menu
436- added http://cobbler.example.org/cblr/svc/op/list/what/systems (or profiles, etc)
437- in the webui, only show compatible repos when editing a profile
438- refresh cobblerd cache before adding objects
439- system object IP's ok in CIDR notation (AAA.BBB.CCC.DDD/EE) for defining PXE behavior.
440- split partition select template into two parts (old one still ships)
441- cleanup some stock kickstarts so we always use $kickstart_start
442- hook ctrl+c during serializer writes to prevent possible corruption of data in /var/lib/cobbler
443- added 'serializer_catalog' as the new default serializer. It is backward compatible and much faster.
444- removed serializer_shelve
445- webui page lookups don't load the full object collection
446- systems can also inherit from images
447- changes to PXE images directly
448- bootloaders is no longer a config file setting
449- we can now look for syslinux in one of two places (/usr/lib, /usr/share)
450- cobbler hardlinks a bit more when it can for /var/www image copies
451- add Xen FV and VMware virt types to WebUI
452
453- Thu Jul 17 2008 - 1.0.4 (tentative)
454- Backported findks.cgi to mod_python, minor mod_python svc handler changes
455
456- Wed Jun 03 2008 - 1.0.3
457- Fix typo in replicate code
458- remove rhpl reference
459- scrub references to manage_*_mode and rewrite the restart-services trigger
460- add new settings to control whether the restart-trigger restarts things
461- yum reposync should also pull i686 kernels, not just i386
462- make cobblerd close file handles
463- fix kickstart serving when the tree is on NFS
464- fix missing reposync createdir (also now in stable branch)
465- add back missing remove_profile/remove_repo
466- remove profile_change support
467
468- Mon Jun 09 2008 - 1.0.2
469- Fix mkdir invocation
470- Fix error message output from failed kickstart rendering
471- manpage edits
472- make buildiso work for SuSE
473
474- Tue Jun 03 2008 - 1.0.1
475- Fix misformatted warning in "check"
476- Do not have RPM own tftpboot, just generate files in TFTP dir as detected
477- Default arches to 'i386' not 'x86' for consistency, esp. in import
478- When querying kickstart templates, do not return directories
479- Make triggers for add/delete work for renames and copies (same triggers)
480- Do not cache snippets so they can be tweaked w/o starting the service
481- Make manpage reference /etc/cobbler/settings, not /var/lib
482- Added manage_forward_zones/manage_reverse_zones to included config file
483- Fix python double-use-of-parameter error
484
485- Mon May 12 2008 - 0.9.2
486- run createrepo with less preconditions during cobbler reposync
487- doc upgrades and error handling for "cobbler replicate"
488- improved error message that occurs when copying from nfs w/ rootsquash
489- mac duplication checking improvements for CLI
490- add warning to cobbler check if selinux is on and Apache boolean not set
491- added warning to cobbler check if templates use the default password
492- setting per-system kickstart template to "" or "delete" restores inheritance
493- if repos in profiles no longer exist, remove noisy warning, move to "check"
494- move warning about reposync to check also (check is more useful at runtime now)
495- build pxe trees for systems even if interface0 is undefined
496- add sync() back into XMLRPC API, missing in 0.9.1
497- added 'distro_name', 'profile_name', and 'system_name' to generated template vars
498- it's now possible to undefine a --ksmeta or kopts symbol defined in a parent with "!foo"
499- log errors while rendering kickstarts
500- comments added to the config file, neat!
501- settings file is now /etc/cobbler/settings
502
503- Fri May 09 2008 - 0.9.1
504- patch to allow yumopts to override gpgcheck
505- applied patch to send hostname from ISC
506- added patch to allow --kopts/--ksmeta items to be cleared with --kopts=delete
507- tftpboot location is now inferred from xinetd config (added for F9 compat)
508- added authn_ldap and stub for authz_configfile
509- authz_configfile allows filtering ldap/other users by config file
510- WebUI now has checkbox on distro/profile for deleting child objects
511- cli has different semantics between "add" and "edit" now for safety reasons
512- cobbler wants to keep IPs/MACs unique now in configuration (can be disabled)
513- added --clobber option to allow add to overwrite existing objects (for scripts)
514- updated/tested kerberos support for those needing to auth against it
515- update menu.c32 to 3.62 to allow for timeouts during menu (and future submenu)
516- update PXE defaults to invoke menu.c32 automatically w/ timeout
517- removed dependency on rhpl
518- import can now take an --arch (and is recommended usage)
519- now possible to override snippets on a profile/system specific basis
520- provide a different default sample kickstart for imports of F8 and later
521- support for kerberos authentication
522- revamped pre/post install triggers system (triggered via cgi from kickstart wget)
523- logrotate should not send emails to root when restarting services
524- default core (but not repo add) repos to priority 1 (lowest) if using priorities plugin
525- change default authentication to deny_all, xmlrpc_rw_enabled now on by default
526- additional fix for mod_python select box submissions
527- set repo arch if found in the URL and no --arch is specified
528- CGI scripts have been moved under mod_python for speed/consolidation
529- kickstart templates are now evaluated dynamically
530- optional MAC registration is now built-in to requesting kickstarts
531- legacy static file generation from /var/www/cobbler removed
532- implement "cobbler ___ dumpvars --name=X" feature to show template vars
533- validateks now works against all URLs as opposed to rendered local files
534- now possible to create new kickstarts in webui, and delete unused ones
535- support for OMAPI for avoid dhcp restarts
536- support for managing BIND
537- xen kernel (PV) distros do not get added to PXE menus as they won't boot there
538- cobbler buildiso command to build non live ISOs
539- cobbler replicate command
540- added cobbler repo option --mirror-locally to reference external repos without mirroring
541- all virt parameters on profiles can now be overriden on cobbler profile objects
542- added some additional links for kickstart viewing/editing to the web page
543
544- ??? - 0.8.3
545- Make createrepo get run for local cobbler reposync invocations as needed
546- fix WebUI documentation URL
547- fix bug in /etc/cobbler/modules.conf regarding pluggable authn/z
548- fix default flags for yumdownloader
549- fix for RHEL 4u6 DVD/tree import x86_64 arch detection
550- fix for dnsmasq template file host config path
551- fix dnsmasq template to point at the correct hosts file
552- force all names to be alphanumeric
553- all mod python pieces now happy with Unicode output
554
555* Fri Feb 22 2008 - 0.8.2
556- fix to webui to allow repos to be edited there on profile page
557- disable local socket XMLRPC as nothing is using it.
558- fixed findks.cgi so it supports multiple NICs
559- import now supports both --path and --mirror as aliases, as before
560- added change_profile.cgi for changing profiles from CGI
561- added register_mac.cgi
562
563* Wed Feb 20 2008 - 0.8.1
564- bugfix in reposync code
565- don't print tracebacks on SystemExit from optparse
566- manpage tweaks
567
568* Fri Feb 15 2008 - 0.8.0 (TBD)
569- stable release of 0.7.* branch plus ...
570- fixed potential user problem with source_repos in upgrade scenario
571- additional higher level API functions for find, fixes for other higher level API functions
572- better messaging when insufficient permissions on needed files
573- update permissions on reposync fixes
574
575* Thu Jan 31 2008 - 0.7.2 (0.8 rc)
576- default_virt_file_size and default_virt_ram added to settings
577- enforce permissions/selinux context after reposync
578- better API for copying/renames, API consistancy cleanup
579- support for renames that resolve dependencies, inclusion in CLI+webapp
580- remove leading newline in rendered template files, which apparently breaks AutoYAST?
581- recursive syncs automatically sync all subobjects when editing parent objects (default behavior)
582- deletes can now be done recursively (optional --recursive on distro/profile remove)
583- 'cobbler list' is now (re)sorted
584
585* Wed Jan 09 2008 - 0.7.1
586- allow imports to force usage of a specific kickstart template with --kickstart
587- added --yumopts parameter to repos (works just like --kopts/--ksmeta)
588- minor doc fixes
589- fix for name of F8 comps.xml file
590- added option --rsync-flags to import command
591- added http_port to settings to run Apache on non-80
592- rsync during createrepo now keeps filesystem permissions/groups
593- ...
594
595* Mon Dec 10 2007 - 0.7.0
596- Testing branch
597- Fix bug related to <<inherit>> and kickstart args
598- Make CLI functions modular and use optparse
599- Quote wget args to avoid creating stray files on target system
600- Support Xen FV as virt type (requires F8+)
601- Implemented fully pluggable authn/authz system
602- WebUI is now mod_python based
603- Greatly enhanced logging (goes to /var/log/cobbler/cobbler.log)
604- ...
605
606* Wed Nov 14 2007 - 0.6.4
607- Changed permissions of auth.conf
608- Fixes for working with rhn_yum_plugin
609- still allow repo configuration for distro repos that have just 1 repo (like C5.1)
610- disable CGI weblogging by default (backend logging TBA)
611- fix WebUI handling of keep_updated (repo field) and netboot_enabled (system field)
612- disable the blender_cache as it's running afoul of the sync code
613- update htaccess file to only authenticate the webui, not nopxe.cgi and findks.cgi
614
615* Wed Nov 07 2007 - 0.6.3
616- Be able to define and use Multiple NICs per system
617- Add --virt-cpus to profile editing
618- Fix bug where WUI (XMLRPC) auth wasn't supported on EL4
619- Add --virt-bridge to profile editing and NICs
620- Added serializer_shelve (as option) for added performance/persistance over YAML, experimental in /etc/cobbler/modules.conf, see Wiki
621- Backup state files and migrate state structures upon RPM upgrade
622- Added some more redundant files (for unsupported distros) to the rsync.exclude file
623- added pre-sync and post-sync triggers, service restarts are now handled by /var/lib/cobbler/triggers
624- webui now uses htaccess (see manpage and Wiki for setup instructions)
625- added pagination to the WUI to keep pages from growing overly long
626- added --server-override parameter for help with multi-subnet configurations (also see Wiki)
627- removed yum-utils as a hard requirement, cobbler check now looks for yum-utils
628- fixed bug where cobbler would try to copy hardlinks to themselves during sync
629- misc random bugfixing
630
631* Fri Sep 28 2007 - 0.6.2
632- cobbler repo auto-add to discover yum repos automatically
633- fix bug that allows empty mac addresses (None) in dhcpd.conf
634- kickstarts automatically save kickstart file used to /root/cobbler.ks
635- allow multiple (comma-seperated) values for --virt-size
636- removed deprecated 'enchant' function (use SSH and koan instead)
637- cleanup of a few unused settings
638- allow for serialization modules to be selected in /etc/cobbler/modules.conf
639- patch to allow for reposync of specific repos, even if not set to update
640- added --dhcp-tag section for better DHCP customization (esp with multiple subnets)
641- added Apache proxying around XMLRPC port for wider network access
642- refactor XMLRPC API and establish a read-write API
643- allow for configuring of read-write XMLRPC users in /etc/cobbler/auth.conf
644- WebUI
645- packaged /var/lib/cobbler/settings as a config file
646- added BuildRequires to help build on other platforms
647- relocate cgi-bin files to cgi-bin/cobbler for namespacing
648- fix syslog logging for systems not in the cobbler DB.
649- fix bug in which non-lowercase intermediate objects could be deleted
650
651* Thu Aug 30 2007 - 0.6.1
652- re enable --resolve in yumdownloader (cobbler repo mgmt feature)
653- fix get_distros_for_koan API function in cobblerd (not used by koan)
654- allow find API to search by arbitrary fields
655- status and logging now shows system names
656- upgraded init scripts
657- zeroconf/avahi publishing for cobblerd service
658- logRequests = 0 for XMLRPC. Make it be quiet.
659- ignore subdirectories of /var/lib/cobbler/snippets
660- fixed bug in graph rendering that allowed for upward property propogation in some cases
661- fixed bug that did not correctly evaluate repository settings of inherited sub-profiles/objects
662- tweaked domU sample kickstart to include wget
663- added some more unit tests
664- fix typo down one error path in cobbler sync.
665- fix reposync handling when using rsync protocol and directory paths do not contain arch
666- allow basic usage of Cheetah variables in config files @@server@@, etc.
667- fix auto-repo attachment for distros with split trees (i.e. RHEL5)
668
669* Thu Aug 09 2007 - 0.6.0
670- bugfix in error path in "cobbler check"
671- stable release for 0.5.x
672
673* Thu Jul 26 2007 - 0.5.2 (RC)
674- Have cobbler check ensure services are started
675- Add cobbler validateks command to look for broken rendered kickstarts
676- Added -v/--version
677- Added SNIPPET::foo capability to pull /var/lib/cobbler/snippets/foo into templates (anywhere)
678- Import can now take an --available-as=nfs://server:/mount/point to do cobbler import without mirroring
679- Feature to enable "pxe_just_once" for boot loop prevention
680
681* Fri Jul 20 2007 - 0.5.1
682- Added logging for cobblerd -- /var/log/cobbler/cobblerd.log
683- Cobblerd now ignores XMLRPC IOError
684- Added findks.cgi
685- Misc bugfixing
686- Added --virt-path, --virt-type
687
688* Wed Jun 24 2007 - 0.5.0
689- Remove hardcode of /var/www/cobbler in cobblerd
690- Improve various warning warning messages
691- cobbler (objecttype) (objectname) now gives info about the object instead of just all objects
692- Added --hostname to "cobbler system add", --ip-address (or --ip) is also a better alias for the misnamed --pxe-address
693- Optionally use dnsmasq for DHCP (and DNS!) instead of ISC dhcpd.
694- Add --mac and remove requirement for --name to be an ip, mac, or hostname.
695- Manpage cleanup
696- Patch to allow pre and post triggers
697- Patch to allow --createrepo-flags and to cache on import, fix multiple calls to createrepo
698- Various modifications to allow for profile inheritance
699- All variables in object tree now available for use in templating, nicer blending algorithms
700- Optional override of --kickstart in system object
701
702* Thu Apr 26 2007 - 0.4.8
703- Make import friendlier for older distros
704- Make import friendlier for newer createrepos that don't have --basedir
705
706* Fri Apr 20 2007 - 0.4.7
707- Disable mod_python tracker piece for RHEL5 (replacement eventual).
708- Kickstart tracking now understands Apache logs
709- Added support for --rpm-list parameter to "repo add" for download of partial content from repositories
710 (ex: cobbler and koan from FC6extras, w/o games).
711- More consistant naming on imports, regardless of data source.
712- Teach cobbler to remove .olddata dirs, which can happen if createrepo crashes or is killed mid-process
713- Default yum_core_repos_from_server to 0
714- Implemented triggers for add/delete commands
715- BootAPI and Config object classes are now Borg patterned to prevent duplication of config info from the API.
716- cobbler_syslogd -> cobblerd, now has XMLRPC component for koan >= 0.2.9 clients. Old clients still work.
717- Make cobbler_import work for Centos 5
718- Removed requirements on what files that are parameters to --kernel and --initrd must be named.
719- Added support for "rename", "copy", and "edit" commands -- before there just was "add" and "remove"
720
721* Thu Apr 05 2007 - 0.4.6
722- Bind cobbler_syslogd to all addresses
723- Store repos as list, not string
724- Fix traceback in cobbler_sync with older configurations (pre-kickstart tracking)
725- Make cobbler import feature better understand older RHEL and in-between builds of Fedora.
726- Make cobbler repo add/reposync understand http://, ftp://, and some limited support for RHN.
727- Add settings parameter to toggle core repo mirror behavior on/off.
728- Manpage cleanup.
729
730* Fri Mar 23 2007 - 0.4.5
731- Removed legacy --virt-name parameter, requires koan upgrade to 0.2.8
732
733* Fri Mar 23 2007 - 0.4.4
734- Generate PXE configuration files from templates in /etc/cobbler to be more customizable
735- Fix bug with wrong kickstart metadata being used for import
736- Fix bug with argument parsing for --repos
737- Much cleaner distro/profile names with --import
738- For import, the "tree" parameter is now attached to the distro, not the profile
739- Add "links" directory in webdir for symlinking to full kickstart tree paths.
740- Misc tweaks to shorten kernel parameter length
741- Giving invalid arguments to "report" will show an error message
742- Distros, Profiles, and System names are now case insensitive.
743
744* Wed Feb 28 2007 - 0.4.3
745- Added netboot_enabled option for systems to control install loops in programmatic context.
746- Disabling anchors in YAML serialization (which make files harder to edit)
747- Fix bug in ksmeta argument processing, takes whitespace again, not commas
748- Fix bug in old-style deserialization with str and int concatenation
749
750* Mon Feb 19 2007 - 0.4.2
751- Fix bug in "cobbler system remove"
752
753* Mon Feb 19 2007 - 0.4.1
754- Bundle menu.c32 for older distros
755- Unbundle Cheetah as it's available at http://www.python.org/pyvault/centos-4-i386/
756
757* Mon Feb 19 2007 - 0.4.0
758- Added feature to minimize the need to run "cobbler sync" for add commands
759 Now only need to run sync when files change behind the scenes or when
760 manually editing YAML
761- Moving back to Cheetah for templating (old kickstarts should escape $ with \$)
762- PXE menus for the default profile. Type "menu" at the prompt to get a menu, or wait for local boot.
763- Manpage cleanup and clarification
764- Bugfix: cobbler will no longer create repo files on remotes when --local-filename is not used for "repo add"
765
766* Mon Jan 28 2007 - 0.3.9
767- Make init scripts correspond with FC-E guidelines
768
769* Thu Jan 24 2007 - 0.3.8
770- Fixed minor bug in logfile processing related to 0.3.7
771
772* Thu Jan 24 2007 - 0.3.7
773- Default/examples kickstarts are now fully automatic (added hd type/size detection).
774- Kickstart tracking now includes remote syslog support, just run "cobbler sync" to enable.
775- "cobbler status" command improved to include syslog info/times.
776- Added fc6 kickstart file that was left out of the RPM earlier
777- Added mini domU kickstart
778- bugfix: don't install mod_python watcher on older Apache installs (like RHEL4) as it
779 somehow corrupts downloads on older copies. kickstart tracking by syslog still works
780 on those platforms. (This only applies to the cobbler server, not clients).
781
782* Thu Dec 21 2006 - 0.3.6
783- locking feature now enabled
784- "enchant" now supports provisioning virtual images remotely when using --is-virt=yes
785- cobbler no longer restarts httpd if the config file already exists.
786- "cobbler repo sync" is now an alias for "cobbler reposync"
787- "cobbler list --something" can now be invoked as "cobbler something list"
788- "cobbler list" just shows names of items now
789- "cobbler report" is now used for showing full information output
790- "list" (as well as report) are now sorted alphabetically
791- basic kickstart tracking feature. requests on /var/www/cobbler get logged to /var/log/cobbler.
792
793* Wed Dec 20 2006 - 0.3.5
794- Fixed bug in cobbler import related to orphan detection
795- Made default rsync.exclude more strict (OO langpacks and KDE translation)
796- Now runs createrepo during "cobbler import" to build more correct repodata
797- Added additional repo mirroring commands: "cobbler repo add", etc
798- Documentation on repo mirroring features.
799- fix bug in rsync:// import code that saved distributions in the wrong path
800- The --dryrun option on "cobbler sync" is now unsupported.
801- Fixed bug in virt specific profile information not being used with koan
802- import now takes --name in addition to --mirror-name to be more consistant
803- rsync repo import shouldn't assume SSH unless no rsync:// in mirror URL
804- strict host key checking disabled for "cobbler enchant" feature
805
806* Mon Dec 05 2006 - 0.3.4
807- Don't rsync PPC content or ISO's on cobbler import
808- Manpage cleanup
809
810* Tue Nov 14 2006 - 0.3.3
811- During "cobbler sync" only PXE-related directories in /tftpboot
812 are deleted. This allows /tftpboot to be used for other
813 purposes.
814
815* Thr Oct 25 2006 - 0.3.2
816- By default, boot and install in text mode
817
818* Wed Oct 25 2006 - 0.3.1
819- The app now refers to "virt" in many places instead of "xen".
820 It's been coded such that files will migrate forward without
821 any major issues, and the newer version of koan can still hit
822 older releases (for now). The CLI still takes the --xen options
823 as well as the new --virt options, as they are aliased. The API
824 now exclusively just uses methods with "virt" in them, however.
825- ...
826
827* Tue Oct 24 2006 - 0.3.0
828- Reload httpd during sync
829- New profiles without set kickstarts default to /etc/cobbler/default.ks
830 though this can be changed in /var/lib/cobbler/settings
831- Better forward upgrades for /var/lib/cobbler/settings. New entries
832 get added when they are referenced.
833
834* Tue Oct 24 2006 - 0.2.9
835- Bug fix, enchant now detects if koan_path is not set
836- import now can do ssh rsync as well as just rsyncd
837- Misc bug fixes related to not choking on bad info
838- Fixed bug where --pxe-address wasn't surfaced
839- Sync is a little less verbose
840
841* Wed Oct 18 2006 - 0.2.8
842- Performance speedups to "import" command
843- Bug fix, imported paths (again) convert slashes to underscores
844
845* Tue Oct 17 2006 - 0.2.7
846- Removed pexpect to enhance support for other distros
847- enchant syntax changed (see NEWS)
848- now builds on RHEL4
849
850* Tue Oct 17 2006 - 0.2.6
851- Removing Cheetah and replacing w/ simpler templating system
852- Don't delete localmirror on sync
853
854* Mon Oct 16 2006 - 0.2.5
855- New "import" feature for rsync:// mirrors and filesystem directories
856- Manpage clarification
857- "enchant" is now a subcommand of "cobbler system" and takes less arguments.
858- Several random bugfixes (mainly along error paths)
859
860* Wed Oct 11 2006 - 0.2.4
861- Changes to make things work with python 2.3 (RHEL4, etc)
862- Updated YAML code to ensure better backward compatibility
863
864* Mon Oct 9 2006 - 0.2.3
865- Cobbler now creates a profile and system listing (YAML) in /var needed
866 by the next version of koan (which will be 0.2.1)
867- bugfix: enchant should reboot the target box
868- bugfix: enchant should fail if path to koan isn't configured
869
870* Fri Oct 6 2006 - 0.2.2
871- bugfix: "--pxe-hostname" made available in CLI and renamed as "--pxe-address"
872- workaround: elilo doesn't do MAC address pxe config files, use IP for ia64
873- bugfix: added next-server line for per-MAC dhcp configs
874- bugfix: fixed manpage errors
875
876* Thu Sep 28 2006 - 0.2.1
877- New ability to "enchant" remote systems (see NEWS)
878- Misc. bugfixes
879
880* Fri Sep 22 2006 - 0.2.0
881- New dhcp.d conf management features (see NEWS)
882- IA64 support (see NEWS)
883- dhcpd.conf MAC & hostname association features
884
885* Thu Sep 21 2006 - 0.1.1-8
886- (RPM) Added doc files to doc section, removed INSTALLED_FILES
887
888* Wed Sep 20 2006 - 0.1.1-7
889- Split HTTP and TFTP content to seperate directories
890 to enable running in SELinux targetted/enforcing mode.
891- Make the Virt MAC address a property of a system, not a profile
892- Misc. fixes, mainly along the error path
893
894* Fri Sep 15 2006 - 0.1.1-6
895- Make koan own it's directory, add GPL "COPYING" file.
896
897* Wed Aug 16 2006 - 0.1.1-5
898- Spec file tweaks only for FC-Extras
899
900* Thu Jul 20 2006 - 0.1.1-4
901- Fixed python import paths in yaml code, which errantly assumed yaml was installed as a module.
902
903* Wed Jul 12 2006 - 0.1.1-3
904- Added templating support using Cheetah
905
906* Thu Jul 9 2006 - 0.1.0-2
907- Fedora-Extras rpm spec tweaks
908
909* Tue Jun 28 2006 - 0.1.0-1
910- rpm genesis
911
912
0913
=== renamed file 'CHANGELOG' => 'CHANGELOG.moved'
=== added file 'COPYING'
--- COPYING 1970-01-01 00:00:00 +0000
+++ COPYING 2011-03-11 21:10:49 +0000
@@ -0,0 +1,340 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Lesser General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you".
71
72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License
85along with the Program.
86
87You may charge a fee for the physical act of transferring a copy, and
88you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1
93above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it.
123
124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or
127collective works based on the Program.
128
129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under
132the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of
136Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component
164itself accompanies the executable.
165
166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such
178parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to
195this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program.
209
210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other
213circumstances.
214
215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot
224impose that choice.
225
226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns.
241
242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software
248Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and
256of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285possible use to the public, the best way to achieve this is to make it
286free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least
291the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) <year> <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License along
307 with this program; if not, write to the Free Software Foundation, Inc.,
308 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
310Also add information on how to contact you by electronic and paper mail.
311
312If the program is interactive, make it output a short notice like this
313when it starts in an interactive mode:
314
315 Gnomovision version 69, Copyright (C) year name of author
316 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 This is free software, and you are welcome to redistribute it
318 under certain conditions; type `show c' for details.
319
320The hypothetical commands `show w' and `show c' should show the appropriate
321parts of the General Public License. Of course, the commands you use may
322be called something other than `show w' and `show c'; they could even be
323mouse-clicks or menu items--whatever suits your program.
324
325You should also get your employer (if you work as a programmer) or your
326school, if any, to sign a "copyright disclaimer" for the program, if
327necessary. Here is a sample; alter the names:
328
329 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
332 <signature of Ty Coon>, 1 April 1989
333 Ty Coon, President of Vice
334
335This General Public License does not permit incorporating your program into
336proprietary programs. If your program is a subroutine library, you may
337consider it more useful to permit linking proprietary applications with the
338library. If this is what you want to do, use the GNU Lesser General
339Public License instead of this License.
340
0341
=== renamed file 'COPYING' => 'COPYING.moved'
=== added file 'MANIFEST.in'
--- MANIFEST.in 1970-01-01 00:00:00 +0000
+++ MANIFEST.in 2011-03-11 21:10:49 +0000
@@ -0,0 +1,13 @@
1include COPYING AUTHORS README CHANGELOG
2include cobbler.spec
3
4recursive-include aux *
5recursive-include config *
6recursive-include docs *
7recursive-include installer_templates *
8recursive-include kickstarts *
9recursive-include snippets *
10recursive-include scripts *
11recursive-include templates *
12recursive-include web *
13
014
=== renamed file 'MANIFEST.in' => 'MANIFEST.in.moved'
=== added file 'README'
--- README 1970-01-01 00:00:00 +0000
+++ README 2011-03-11 21:10:49 +0000
@@ -0,0 +1,9 @@
1Cobbler README
2
3Docs are currently available two ways:
4- Install the RPM and run "man cobbler"
5- Run "perldoc cobbler.pod" from a source checkout
6
7To build the RPM:
8- Run "make"
9
010
=== renamed file 'README' => 'README.moved'
=== added directory 'aux'
=== renamed directory 'aux' => 'aux.moved'
=== added file 'aux/anamon'
--- aux/anamon 1970-01-01 00:00:00 +0000
+++ aux/anamon 2011-03-11 21:10:49 +0000
@@ -0,0 +1,280 @@
1#!/usr/bin/python
2
3"""
4This is a script used to automatically log details from an Anaconda
5install back to a cobbler server.
6
7Copyright 2008, Red Hat, Inc
8various@redhat.com
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2302110-1301 USA
24"""
25
26import os
27import sys
28import string
29import time
30import re
31import base64
32import shlex
33
34# on older installers (EL 2) we might not have xmlrpclib
35# and can't do logging, however this is more widely
36# supported than remote syslog and also provides more
37# detail.
38try:
39 import xmlrpclib
40except ImportError, e:
41 print "xmlrpclib not available, exiting"
42 sys.exit(0)
43
44# shlex.split support arrived in python-2.3, the following will provide some
45# accomodation for older distros (e.g. RHEL3)
46if not hasattr(shlex, "split"):
47 shlex.split = lambda s: s.split(" ")
48
49class WatchedFile:
50 def __init__(self, fn, alias):
51 self.fn = fn
52 self.alias = alias
53 self.reset()
54
55 def reset(self):
56 self.where = 0
57 self.last_size = 0
58 self.lfrag=''
59 self.re_list={}
60 self.seen_line={}
61
62 def exists(self):
63 return os.access(self.fn, os.F_OK)
64
65 def lookfor(self,pattern):
66 self.re_list[pattern] = re.compile(pattern,re.MULTILINE)
67 self.seen_line[pattern] = 0
68
69 def seen(self,pattern):
70 if self.seen_line.has_key(pattern):
71 return self.seen_line[pattern]
72 else:
73 return 0
74
75 def changed(self):
76 if not self.exists():
77 return 0
78 size = os.stat(self.fn)[6]
79 if size > self.last_size:
80 self.last_size = size
81 return 1
82 else:
83 return 0
84
85 def uploadWrapper(self, blocksize = 262144):
86 """upload a file in chunks using the uploadFile call"""
87 retries = 3
88 fo = file(self.fn, "r")
89 totalsize = os.path.getsize(self.fn)
90 ofs = 0
91 while True:
92 lap = time.time()
93 contents = fo.read(blocksize)
94 size = len(contents)
95 data = base64.encodestring(contents)
96 if size == 0:
97 offset = -1
98 sz = ofs
99 else:
100 offset = ofs
101 sz = size
102 del contents
103 tries = 0
104 while tries <= retries:
105 debug("upload_log_data('%s', '%s', %s, %s, ...)\n" % (name, self.alias, sz, offset))
106 if session.upload_log_data(name, self.alias, sz, offset, data):
107 break
108 else:
109 tries = tries + 1
110 if size == 0:
111 break
112 ofs += size
113 fo.close()
114
115 def update(self):
116 if not self.exists():
117 return
118 if not self.changed():
119 return
120 try:
121 self.uploadWrapper()
122 except:
123 raise
124
125class MountWatcher:
126
127 def __init__(self,mp):
128 self.mountpoint = mp
129 self.zero()
130
131 def zero(self):
132 self.line=''
133 self.time = time.time()
134
135 def update(self):
136 found = 0
137 if os.path.exists('/proc/mounts'):
138 fd = open('/proc/mounts')
139 while 1:
140 line = fd.readline()
141 if not line:
142 break
143 parts = string.split(line)
144 mp = parts[1]
145 if mp == self.mountpoint:
146 found = 1
147 if line != self.line:
148 self.line = line
149 self.time = time.time()
150 fd.close()
151 if not found:
152 self.zero()
153
154 def stable(self):
155 self.update()
156 if self.line and (time.time() - self.time > 60):
157 return 1
158 else:
159 return 0
160
161def anamon_loop():
162 alog = WatchedFile("/tmp/anaconda.log", "anaconda.log")
163 alog.lookfor("step installpackages$")
164
165 slog = WatchedFile("/tmp/syslog", "sys.log")
166 xlog = WatchedFile("/tmp/X.log", "X.log")
167 llog = WatchedFile("/tmp/lvmout", "lvmout.log")
168 storage_log = WatchedFile("/tmp/storage.log", "storage.log")
169 prgm_log = WatchedFile("/tmp/program.log", "program.log")
170 vnc_log = WatchedFile("/tmp/vncserver.log", "vncserver.log")
171 kcfg = WatchedFile("/tmp/ks.cfg", "ks.cfg")
172 scrlog = WatchedFile("/tmp/ks-script.log", "ks-script.log")
173 dump = WatchedFile("/tmp/anacdump.txt", "anacdump.txt")
174 mod = WatchedFile("/tmp/modprobe.conf", "modprobe.conf")
175
176 # Setup '/mnt/sysimage' watcher
177 sysimage = MountWatcher("/mnt/sysimage")
178
179 # Monitor for {install,upgrade}.log changes
180 package_logs = list()
181 package_logs.append(WatchedFile("/mnt/sysimage/root/install.log", "install.log"))
182 package_logs.append(WatchedFile("/mnt/sysimage/tmp/install.log", "tmp+install.log"))
183 package_logs.append(WatchedFile("/mnt/sysimage/root/upgrade.log", "upgrade.log"))
184 package_logs.append(WatchedFile("/mnt/sysimage/tmp/upgrade.log", "tmp+upgrade.log"))
185
186 # Monitor for bootloader configuration changes
187 bootloader_cfgs = list()
188 bootloader_cfgs.append(WatchedFile("/mnt/sysimage/boot/grub/grub.conf", "grub.conf"))
189 bootloader_cfgs.append(WatchedFile("/mnt/sysimage/boot/etc/yaboot.conf", "yaboot.conf"))
190 bootloader_cfgs.append(WatchedFile("/mnt/sysimage/boot/efi/efi/redhat/elilo.conf", "elilo.conf"))
191 bootloader_cfgs.append(WatchedFile("/mnt/sysimage/etc/zipl.conf", "zipl.conf"))
192
193 # Were we asked to watch specific files?
194 watchlist = list()
195 waitlist = list()
196 if watchfiles:
197 # Create WatchedFile objects for each requested file
198 for watchfile in watchfiles:
199 if os.path.exists(watchfile):
200 watchfilebase = os.path.basename(watchfile)
201 watchlog = WatchedFile(watchfile, watchfilebase)
202 watchlist.append(watchlog)
203
204 # Use the default watchlist and waitlist
205 else:
206 watchlist = [alog, slog, dump, scrlog, mod, llog, kcfg, storage_log, prgm_log, vnc_log, xlog]
207 waitlist.extend(package_logs)
208 waitlist.extend(bootloader_cfgs)
209
210 # Monitor loop
211 while 1:
212 time.sleep(5)
213
214 # Not all log files are available at the start, we'll loop through the
215 # waitlist to determine when each file can be added to the watchlist
216 for watch in waitlist:
217 if alog.seen("step installpackages$") or (sysimage.stable() and watch.exists()):
218 debug("Adding %s to watch list\n" % watch.alias)
219 watchlist.append(watch)
220 waitlist.remove(watch)
221
222 # Send any updates
223 for wf in watchlist:
224 wf.update()
225
226 # If asked to run_once, exit now
227 if exit:
228 break
229
230# Establish some defaults
231name = ""
232server = ""
233port = "80"
234daemon = 1
235debug = lambda x,**y: None
236watchfiles = []
237exit = False
238
239# Process command-line args
240n = 0
241while n < len(sys.argv):
242 arg = sys.argv[n]
243 if arg == '--name':
244 n = n+1
245 name = sys.argv[n]
246 elif arg == '--watchfile':
247 n = n+1
248 watchfiles.extend(shlex.split(sys.argv[n]))
249 elif arg == '--exit':
250 exit = True
251 elif arg == '--server':
252 n = n+1
253 server = sys.argv[n]
254 elif arg == '--port':
255 n = n+1
256 port = sys.argv[n]
257 elif arg == '--debug':
258 debug = lambda x,**y: sys.stderr.write(x % y)
259 elif arg == '--fg':
260 daemon = 0
261 n = n+1
262
263# Create an xmlrpc session handle
264session = xmlrpclib.Server("http://%s:%s/cobbler_api" % (server, port))
265
266# Fork and loop
267if daemon:
268 if not os.fork():
269 # Redirect the standard I/O file descriptors to the specified file.
270 DEVNULL = getattr(os, "devnull", "/dev/null")
271 os.open(DEVNULL, os.O_RDWR) # standard input (0)
272 os.dup2(0, 1) # Duplicate standard input to standard output (1)
273 os.dup2(0, 2) # Duplicate standard input to standard error (2)
274
275 anamon_loop()
276 sys.exit(1)
277 sys.exit(0)
278else:
279 anamon_loop()
280
0281
=== added file 'aux/anamon.init'
--- aux/anamon.init 1970-01-01 00:00:00 +0000
+++ aux/anamon.init 2011-03-11 21:10:49 +0000
@@ -0,0 +1,101 @@
1#!/bin/bash
2## BEGIN INIT INFO
3# Provides: anamon
4# Default-Start: 3 5
5# Default-Stop: 0 1 2 4 6
6# Required-Start:
7# Should-Start: $network
8# Short-Description: Starts the cobbler anamon boot notification program
9# Description: anamon runs the first time a machine is booted after
10# installation.
11## END INIT INFO
12
13#
14# anamon: Starts the cobbler post-install boot notification program
15#
16# chkconfig: 35 99 95
17#
18# description: anamon runs the first time a machine is booted after
19# installation.
20#
21
22LOCKFILE="/var/lock/subsys/anamon"
23CFGFILE="/etc/sysconfig/anamon"
24
25# Source function library.
26. /etc/init.d/functions
27
28# Source anamon config
29. $CFGFILE
30
31LOGFILES=${LOGFILES:-/var/log/boot.log}
32
33# FIXME - can we rely on the koan snippet to update /etc/profile.d/cobbler.sh?
34if [ -z "$COBBLER_SERVER" ]; then
35 echo "No COBBLER_SERVER defined in $CFGFILE"
36 exit 1
37fi
38
39if [ -z "$COBBLER_NAME" ]; then
40 echo "No COBBLER_NAME defined in $CFGFILE"
41 exit 1
42fi
43
44if [ -z "$LOGFILES" ]; then
45 echo "No LOGFILES defined in $CFGFILE"
46 exit 1
47fi
48
49start() {
50 echo -n $"Starting anamon: "
51 daemon /usr/local/sbin/anamon --watchfile \"$LOGFILES\" --name $COBBLER_NAME --server $COBBLER_SERVER --port ${COBBLER_PORT:-80} --exit
52 RETVAL=$?
53 [ $RETVAL -eq 0 ] && touch $LOCKFILE
54 echo
55
56 # Disable service start
57 chkconfig anamon off
58
59 return $RETVAL
60}
61
62stop () {
63 echo -n $"Shutting down anamon: "
64 killproc /usr/local/sbin/anamon
65 RETVAL=$?
66 [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
67 echo
68 return $RETVAL
69}
70
71restart() {
72 stop
73 start
74}
75
76case "$1" in
77 start)
78 start
79 ;;
80 stop)
81 stop
82 ;;
83 restart)
84 restart
85 ;;
86 condrestart)
87 if [ -f $LOCKFILE ]; then
88 restart
89 fi
90 ;;
91 status)
92 status anamon
93 RETVAL=$?
94 ;;
95 *)
96 echo $"Usage: $0 {start|stop|status|restart|condrestart}"
97 RETVAL=2
98 ;;
99esac
100
101exit $RETVAL
0102
=== added directory 'cobbler'
=== renamed directory 'cobbler' => 'cobbler.moved'
=== added file 'cobbler.spec'
--- cobbler.spec 1970-01-01 00:00:00 +0000
+++ cobbler.spec 2011-03-11 21:10:49 +0000
@@ -0,0 +1,266 @@
1%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
2%{!?pyver: %define pyver %(%{__python} -c "import sys ; print sys.version[:3]" || echo 0)}
3
4%define _binaries_in_noarch_packages_terminate_build 0
5%global debug_package %{nil}
6Summary: Boot server configurator
7Name: cobbler
8License: GPLv2+
9AutoReq: no
10Version: 2.1.0
11Release: 2%{?dist}
12Source0: http://shenson.fedorapeople.org/cobbler/cobbler-%{version}.tar.gz
13Group: Applications/System
14BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
15BuildArch: noarch
16Url: http://fedorahosted.org/cobbler
17
18BuildRequires: redhat-rpm-config
19BuildRequires: PyYAML
20BuildRequires: python-cheetah
21
22Requires: python >= 2.3
23Requires: httpd
24Requires: tftp-server
25Requires: mod_wsgi
26Requires: createrepo
27Requires: python-cheetah
28Requires: python-netaddr
29Requires: python-simplejson
30Requires: python-urlgrabber
31Requires: PyYAML
32Requires: rsync
33
34%if 0%{?fedora} >= 11 || 0%{?rhel} >= 6
35Requires: python(abi) >= %{pyver}
36Requires: genisoimage
37%else
38Requires: mkisofs
39%endif
40%if 0%{?fedora} >= 8
41BuildRequires: python-setuptools-devel
42%else
43BuildRequires: python-setuptools
44%endif
45%if 0%{?fedora} >= 6 || 0%{?rhel} >= 5
46Requires: yum-utils
47%endif
48
49Requires(post): /sbin/chkconfig
50Requires(preun): /sbin/chkconfig
51Requires(preun): /sbin/service
52
53%description
54
55Cobbler is a network install server. Cobbler supports PXE,
56virtualized installs, and re-installing existing Linux machines. The
57last two modes use a helper tool, 'koan', that integrates with
58cobbler. There is also a web interface 'cobbler-web'. Cobbler's
59advanced features include importing distributions from DVDs and rsync
60mirrors, kickstart templating, integrated yum mirroring, and built-in
61DHCP/DNS Management. Cobbler has a XMLRPC API for integration with
62other applications.
63
64%prep
65%setup -q
66
67%build
68%{__python} setup.py build
69
70%install
71test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
72%{__python} setup.py install --optimize=1 --root=$RPM_BUILD_ROOT $PREFIX
73mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d
74install -p -m 644 config/cobbler.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/
75install -p -m 644 config/cobbler_web.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/
76
77mkdir -p $RPM_BUILD_ROOT/var/spool/koan
78
79%if 0%{?fedora} >= 9 || 0%{?rhel} > 5
80mkdir -p $RPM_BUILD_ROOT/var/lib/tftpboot/images
81%else
82mkdir -p $RPM_BUILD_ROOT/tftpboot/images
83%endif
84
85rm -f $RPM_BUILD_ROOT/etc/cobbler/cobblerd
86
87%clean
88test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
89
90%post
91if [ "$1" = "1" ];
92then
93 # This happens upon initial install. Upgrades will follow the next else
94 /sbin/chkconfig --add cobblerd
95elif [ "$1" -ge "2" ];
96then
97 # backup config
98 if [ -e /var/lib/cobbler/distros ]; then
99 cp /var/lib/cobbler/distros* /var/lib/cobbler/backup 2>/dev/null
100 cp /var/lib/cobbler/profiles* /var/lib/cobbler/backup 2>/dev/null
101 cp /var/lib/cobbler/systems* /var/lib/cobbler/backup 2>/dev/null
102 cp /var/lib/cobbler/repos* /var/lib/cobbler/backup 2>/dev/null
103 cp /var/lib/cobbler/networks* /var/lib/cobbler/backup 2>/dev/null
104 cp /var/lib/cobbler/mgmtclasses* /var/lib/cobbler/backup 2>/dev/null
105 cp /var/lib/cobbler/packages* /var/lib/cobbler/backup 2>/dev/null
106 cp /var/lib/cobbler/files* /var/lib/cobbler/backup 2>/dev/null
107 fi
108 if [ -e /var/lib/cobbler/config ]; then
109 cp -a /var/lib/cobbler/config /var/lib/cobbler/backup 2>/dev/null
110 fi
111 # upgrade older installs
112 # move power and pxe-templates from /etc/cobbler, backup new templates to *.rpmnew
113 for n in power pxe; do
114 rm -f /etc/cobbler/$n*.rpmnew
115 find /etc/cobbler -maxdepth 1 -name "$n*" -type f | while read f; do
116 newf=/etc/cobbler/$n/`basename $f`
117 [ -e $newf ] && mv $newf $newf.rpmnew
118 mv $f $newf
119 done
120 done
121 # upgrade older installs
122 # copy kickstarts from /etc/cobbler to /var/lib/cobbler/kickstarts
123 rm -f /etc/cobbler/*.ks.rpmnew
124 find /etc/cobbler -maxdepth 1 -name "*.ks" -type f | while read f; do
125 newf=/var/lib/cobbler/kickstarts/`basename $f`
126 [ -e $newf ] && mv $newf $newf.rpmnew
127 cp $f $newf
128 done
129 /sbin/service cobblerd condrestart
130fi
131
132%preun
133if [ $1 = 0 ]; then
134 /sbin/service cobblerd stop >/dev/null 2>&1 || :
135 chkconfig --del cobblerd || :
136fi
137
138%postun
139if [ "$1" -ge "1" ]; then
140 /sbin/service cobblerd condrestart >/dev/null 2>&1 || :
141 /sbin/service httpd condrestart >/dev/null 2>&1 || :
142fi
143
144
145%files
146
147%defattr(-,root,root,-)
148
149%{_bindir}/cobbler
150%{_bindir}/cobbler-ext-nodes
151%{_bindir}/cobblerd
152%{_sbindir}/tftpd.py*
153
154%config(noreplace) %{_sysconfdir}/cobbler
155/etc/init.d/cobblerd
156
157%{python_sitelib}/cobbler
158
159%config(noreplace) /var/lib/cobbler
160
161/var/log/cobbler
162/var/www/cobbler
163
164%{_mandir}/man1/cobbler.1.gz
165
166%config(noreplace) /etc/httpd/conf.d/cobbler.conf
167
168%if 0%{?fedora} >= 9 || 0%{?rhel} >= 5
169%exclude %{python_sitelib}/cobbler/sub_process.py*
170%endif
171%if 0%{?fedora} >= 9 || 0%{?rhel} > 5
172%{python_sitelib}/cobbler*.egg-info
173/var/lib/tftpboot/images
174%else
175/tftpboot/images
176%endif
177
178%doc AUTHORS CHANGELOG README COPYING
179
180%package -n koan
181
182Summary: Helper tool that performs cobbler orders on remote machines
183Group: Applications/System
184Requires: python >= 2.0
185%if 0%{?fedora} >= 11 || 0%{?rhel} >= 6
186Requires: python(abi) >= %{pyver}
187%endif
188
189
190%description -n koan
191
192Koan stands for kickstart-over-a-network and allows for both
193network installation of new virtualized guests and reinstallation
194of an existing system. For use with a boot-server configured with Cobbler
195
196%files -n koan
197%defattr(-,root,root,-)
198%dir /var/spool/koan
199%dir /var/lib/koan/config
200%{_bindir}/koan
201%{_bindir}/cobbler-register
202%{python_sitelib}/koan
203
204%if 0%{?fedora} >= 9 || 0%{?rhel} >= 5
205%exclude %{python_sitelib}/koan/sub_process.py*
206%exclude %{python_sitelib}/koan/opt_parse.py*
207%exclude %{python_sitelib}/koan/text_wrap.py*
208%endif
209
210%{_mandir}/man1/koan.1.gz
211%{_mandir}/man1/cobbler-register.1.gz
212%dir /var/log/koan
213%doc AUTHORS COPYING CHANGELOG README
214
215
216%package -n cobbler-web
217
218Summary: Web interface for Cobbler
219Group: Applications/System
220Requires: cobbler
221Requires: Django
222%if 0%{?fedora} >= 11 || 0%{?rhel} >= 6
223Requires: python(abi) >= %{pyver}
224%endif
225
226%description -n cobbler-web
227
228Web interface for Cobbler that allows visiting
229http://server/cobbler_web to configure the install server.
230
231%files -n cobbler-web
232%defattr(-,root,root,-)
233%doc AUTHORS COPYING CHANGELOG README
234%config(noreplace) /etc/httpd/conf.d/cobbler_web.conf
235%defattr(-,apache,apache,-)
236/usr/share/cobbler/web
237%dir /var/lib/cobbler/webui_sessions
238/var/www/cobbler_webui_content/
239
240%changelog
241* Thu Jun 17 2010 Scott Henson <shenson@redhat.com> - 2.1.0-1
242- Bump upstream release
243
244* Tue Apr 27 2010 Scott Henson <shenson@redhat.com> - 2.0.4-1
245- Bug fix release, see Changelog for details
246
247* Thu Apr 15 2010 Devan Goodwin <dgoodwin@rm-rf.ca> 2.0.3.2-1
248- Tagging for new build tools.
249
250* Mon Mar 1 2010 Scott Henson <shenson@redhat.com> - 2.0.3.1-3
251- Bump release because I forgot cobbler-web
252
253* Mon Mar 1 2010 Scott Henson <shenson@redhat.com> - 2.0.3.1-2
254- Remove requires on mkinitrd as it is not used
255
256* Mon Feb 15 2010 Scott Henson <shenson@redhat.com> - 2.0.3.1-1
257- Upstream Brown Paper Bag Release (see CHANGELOG)
258
259* Thu Feb 11 2010 Scott Henson <shenson@redhat.com> - 2.0.3-1
260- Upstream changes (see CHANGELOG)
261
262* Mon Nov 23 2009 John Eckersberg <jeckersb@redhat.com> - 2.0.2-1
263- Upstream changes (see CHANGELOG)
264
265* Tue Sep 15 2009 Michael DeHaan <mdehaan@redhat.com> - 2.0.0-1
266- First release with unified spec files
0267
=== renamed file 'cobbler.spec' => 'cobbler.spec.moved'
=== added file 'cobbler/__init__.py'
=== added file 'cobbler/action_acl.py'
--- cobbler/action_acl.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_acl.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,120 @@
1"""
2Configures acls for various users/groups so they can access the cobbler command
3line as non-root. Now that CLI is largely remoted (XMLRPC) this is largely just
4useful for not having to log in (access to shared-secret) file but also grants
5access to hand-edit various config files and other useful things.
6
7Copyright 2006-2009, Red Hat, Inc
8Michael DeHaan <mdehaan@redhat.com>
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2302110-1301 USA
24"""
25
26import os
27import os.path
28import shutil
29import sys
30import glob
31import traceback
32import errno
33import utils
34from cexceptions import *
35from utils import _
36import clogger
37
38class AclConfig:
39
40 def __init__(self,config,logger=None):
41 """
42 Constructor
43 """
44 self.config = config
45 self.api = config.api
46 self.settings = config.settings()
47 if logger is None:
48 logger = clogger.Logger()
49 self.logger = logger
50
51 def run(self,adduser=None,addgroup=None,removeuser=None,removegroup=None):
52 """
53 Automate setfacl commands
54 """
55
56 ok = False
57 if adduser:
58 ok = True
59 self.modacl(True,True,adduser)
60 if addgroup:
61 ok = True
62 self.modacl(True,False,addgroup)
63 if removeuser:
64 ok = True
65 self.modacl(False,True,removeuser)
66 if removegroup:
67 ok = True
68 self.modacl(False,False,removegroup)
69 if not ok:
70 raise CX("no arguments specified, nothing to do")
71
72 def modacl(self,isadd,isuser,who):
73
74 webdir = self.settings.webdir
75 snipdir = self.settings.snippetsdir
76 tftpboot = utils.tftpboot_location()
77
78 PROCESS_DIRS = {
79 "/var/log/cobbler" : "rwx",
80 "/var/log/cobbler/tasks" : "rwx",
81 "/var/lib/cobbler" : "rwx",
82 "/etc/cobbler" : "rwx",
83 tftpboot : "rwx",
84 "/var/lib/cobbler/triggers" : "rwx"
85 }
86 if not snipdir.startswith("/var/lib/cobbler/"):
87 PROCESS_DIRS[snipdir] = "r"
88
89 cmd = "-R"
90
91 if isadd:
92 cmd = "%s -m" % cmd
93 else:
94 cmd = "%s -x" % cmd
95
96 if isuser:
97 cmd = "%s u:%s" % (cmd,who)
98 else:
99 cmd = "%s g:%s" % (cmd,who)
100
101 for d in PROCESS_DIRS:
102 how = PROCESS_DIRS[d]
103 if isadd:
104 cmd2 = "%s:%s" % (cmd,how)
105 else:
106 cmd2 = cmd
107
108 cmd2 = "%s %s" % (cmd2,d)
109 rc = utils.subprocess_call(self.logger,"setfacl -d %s" % cmd2,shell=True)
110 if not rc == 0:
111 utils.die(self.logger,"command failed")
112 rc = utils.subprocess_call(self.logger,"setfacl %s" % cmd2,shell=True)
113 if not rc == 0:
114 utils.die(self.logger,"command failed")
115
116
117
118
119
120
0121
=== added file 'cobbler/action_buildiso.py'
--- cobbler/action_buildiso.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_buildiso.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,447 @@
1"""
2Builds non-live bootable CD's that have PXE-equivalent behavior
3for all cobbler profiles currently in memory.
4
5Copyright 2006-2009, Red Hat, Inc
6Michael DeHaan <mdehaan@redhat.com>
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301 USA
22"""
23
24import os
25import os.path
26import shutil
27import sys
28import traceback
29import shutil
30import re
31
32import utils
33from cexceptions import *
34from utils import _
35import clogger
36
37# FIXME: lots of overlap with pxegen.py, should consolidate
38# FIXME: disable timeouts and remove local boot for this?
39HEADER = """
40
41DEFAULT menu
42PROMPT 0
43MENU TITLE Cobbler | http://cobbler.et.redhat.com
44TIMEOUT 200
45TOTALTIMEOUT 6000
46ONTIMEOUT local
47
48LABEL local
49 MENU LABEL (local)
50 MENU DEFAULT
51 KERNEL chain.c32
52 APPEND hd0 0
53
54"""
55
56class BuildIso:
57 """
58 Handles conversion of internal state to the tftpboot tree layout
59 """
60
61 def __init__(self,config,verbose=False,logger=None):
62 """
63 Constructor
64 """
65 self.verbose = verbose
66 self.config = config
67 self.api = config.api
68 self.distros = config.distros()
69 self.profiles = config.profiles()
70 self.systems = config.systems()
71 self.distros = config.distros()
72 self.distmap = {}
73 self.distctr = 0
74 self.source = ""
75 if logger is None:
76 logger = clogger.Logger()
77 self.logger = logger
78
79
80 def make_shorter(self,distname):
81 if self.distmap.has_key(distname):
82 return self.distmap[distname]
83 else:
84 self.distctr = self.distctr + 1
85 self.distmap[distname] = str(self.distctr)
86 return str(self.distctr)
87
88
89 def generate_netboot_iso(self,imagesdir,isolinuxdir,profiles=None,systems=None,exclude_dns=None):
90 self.logger.info("copying kernels and initrds for profiles")
91 # copy all images in included profiles to images dir
92 for profile in self.api.profiles():
93 use_this = True
94 if profiles is not None:
95 which_profiles = profiles.split(",")
96 if not profile.name in which_profiles:
97 use_this = False
98
99 if use_this:
100 dist = profile.get_conceptual_parent()
101 if dist.name.lower().find("-xen") != -1:
102 self.logger.info("skipping Xen distro: %s" % dist.name)
103 continue
104 distname = self.make_shorter(dist.name)
105 # buildisodir/isolinux/$distro/vmlinuz, initrd.img
106 # FIXME: this will likely crash on non-Linux breeds
107 f1 = os.path.join(isolinuxdir, "%s.krn" % distname)
108 f2 = os.path.join(isolinuxdir, "%s.img" % distname)
109 if not os.path.exists(dist.kernel):
110 utils.die(self.logger,"path does not exist: %s" % dist.kernel)
111 if not os.path.exists(dist.initrd):
112 utils.die(self.logger,"path does not exist: %s" % dist.initrd)
113 shutil.copyfile(dist.kernel, f1)
114 shutil.copyfile(dist.initrd, f2)
115
116 if systems is not None:
117 self.logger.info("copying kernels and initrds for systems")
118 # copy all images in included profiles to images dir
119 for system in self.api.systems():
120 if system.name in systems:
121 profile = system.get_conceptual_parent()
122 dist = profile.get_conceptual_parent()
123 if dist.name.find("-xen") != -1:
124 continue
125 distname = self.make_shorter(dist.name)
126 # buildisodir/isolinux/$distro/vmlinuz, initrd.img
127 # FIXME: this will likely crash on non-Linux breeds
128 shutil.copyfile(dist.kernel, os.path.join(isolinuxdir, "%s.krn" % distname))
129 shutil.copyfile(dist.initrd, os.path.join(isolinuxdir, "%s.img" % distname))
130
131 self.logger.info("generating a isolinux.cfg")
132 isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg")
133 cfg = open(isolinuxcfg, "w+")
134 cfg.write(HEADER) # fixme, use template
135
136 self.logger.info("generating profile list")
137 #sort the profiles
138 profile_list = [profile for profile in self.profiles]
139 def sort_name(a,b):
140 return cmp(a.name,b.name)
141 profile_list.sort(sort_name)
142
143 for profile in profile_list:
144 use_this = True
145 if profiles is not None:
146 which_profiles = profiles.split(",")
147 if not profile.name in which_profiles:
148 use_this = False
149
150 if use_this:
151 dist = profile.get_conceptual_parent()
152 if dist.name.find("-xen") != -1:
153 continue
154 data = utils.blender(self.api, True, profile)
155 distname = self.make_shorter(dist.name)
156
157 cfg.write("\n")
158 cfg.write("LABEL %s\n" % profile.name)
159 cfg.write(" MENU LABEL %s\n" % profile.name)
160 cfg.write(" kernel %s.krn\n" % distname)
161
162 if data["kickstart"].startswith("/"):
163 data["kickstart"] = "http://%s:%s/cblr/svc/op/ks/profile/%s" % (
164 data["server"],
165 self.api.settings().http_port,
166 profile.name
167 )
168
169 append_line = " append initrd=%s.img" % distname
170 append_line = append_line + " ks=%s " % data["kickstart"]
171 append_line = append_line + " %s\n" % data["kernel_options"]
172
173 length=len(append_line)
174 if length>254:
175 self.logger.warning("append line length is greater than 254 chars: (%s chars)" % length)
176
177 cfg.write(append_line)
178
179 if systems is not None:
180 self.logger.info("generating system list")
181
182 cfg.write("\nMENU SEPARATOR\n")
183
184 #sort the systems
185 system_list = [system for system in self.systems]
186 def sort_name(a,b):
187 return cmp(a.name,b.name)
188 system_list.sort(sort_name)
189
190 for system in system_list:
191 use_this = False
192 if systems is not None:
193 which_systems = systems.split(",")
194 if system.name in which_systems:
195 use_this = True
196
197 if use_this:
198 profile = system.get_conceptual_parent()
199 dist = profile.get_conceptual_parent()
200 if dist.name.find("-xen") != -1:
201 continue
202 data = utils.blender(self.api, True, system)
203 distname = self.make_shorter(dist.name)
204
205 cfg.write("\n")
206 cfg.write("LABEL %s\n" % system.name)
207 cfg.write(" MENU LABEL %s\n" % system.name)
208 cfg.write(" kernel %s.krn\n" % distname)
209
210 if data["kickstart"].startswith("/"):
211 data["kickstart"] = "http://%s:%s/cblr/svc/op/ks/system/%s" % (
212 data["server"],
213 self.api.settings().http_port,
214 system.name
215 )
216
217 append_line = " append initrd=%s.img" % distname
218 append_line = append_line + " ks=%s" % data["kickstart"]
219 append_line = append_line + " %s" % data["kernel_options"]
220
221 # add network info to avoid DHCP only if it is available
222
223 if data.has_key("bonding_master_eth0") and data["bonding_master_eth0"] != "":
224 primary_interface = data["bonding_master_eth0"]
225 else:
226 primary_interface = "eth0"
227
228 # check if ksdevice entry exists and use that for network info
229
230 blended = utils.blender(self.api, False, system) # don't collapse
231
232 if blended["kernel_options"].has_key("ksdevice") and blended["kernel_options"]["ksdevice"] != "":
233 ksdevice = blended["kernel_options"]["ksdevice"]
234 self.logger.info(" - ksdevice %s set for system %s" % (ksdevice,system.name))
235
236 if data.has_key("ip_address_" + ksdevice ) and data["ip_address_" + ksdevice] != "":
237 primary_interface = ksdevice
238 else:
239
240 for (obj_iname, obj_interface) in data['interfaces'].iteritems():
241 mac = obj_interface["mac_address"].upper()
242 ksdevice_mac = ksdevice.upper()
243
244 if mac == ksdevice_mac:
245 primary_interface = obj_iname
246
247
248 if data.has_key("ip_address_" + primary_interface) and data["ip_address_" + primary_interface] != "":
249 append_line = append_line + " ip=%s" % data["ip_address_" + primary_interface]
250
251 if data.has_key("subnet_" + primary_interface) and data["subnet_" + primary_interface] != "":
252 append_line = append_line + " netmask=%s" % data["subnet_" + primary_interface]
253
254 if data.has_key("gateway") and data["gateway"] != "":
255 append_line = append_line + " gateway=%s" % data["gateway"]
256
257 if not exclude_dns and data.has_key("name_servers") and data["name_servers"]:
258 append_line = append_line + " dns=%s\n" % ",".join(data["name_servers"])
259
260 length=len(append_line)
261 if length > 254:
262 self.logger.warning("append line length is greater than 254 chars: (%s chars)" % length)
263
264 cfg.write(append_line)
265
266 self.logger.info("done writing config")
267 cfg.write("\n")
268 cfg.write("MENU END\n")
269 cfg.close()
270
271
272 def generate_standalone_iso(self,imagesdir,isolinuxdir,distname,filesource):
273
274 # Get the distro object for the requested distro
275 # and then get all of its descendants (profiles/sub-profiles/systems)
276 distro = self.api.find_distro(distname)
277 if distro is None:
278 utils.die(self.logger,"distro %s was not found, aborting" % distname)
279 descendants = distro.get_descendants()
280
281 if filesource is None:
282 # Try to determine the source from the distro kernel path
283 self.logger.debug("trying to locate source for distro")
284 found_source = False
285 (source_head, source_tail) = os.path.split(distro.kernel)
286 while source_tail != '':
287 if source_head == os.path.join(self.api.settings().webdir, "ks_mirror"):
288 filesource = os.path.join(source_head, source_tail)
289 found_source = True
290 self.logger.debug("found source in %s" % filesource)
291 break
292 (source_head, source_tail) = os.path.split(source_head)
293 # Can't find the source, raise an error
294 if not found_source:
295 utils.die(self.logger," Error, no installation source found. When building a standalone ISO, you must specify a --source if the distro install tree is not hosted locally")
296
297 self.logger.info("copying kernels and initrds for standalone distro")
298 # buildisodir/isolinux/$distro/vmlinuz, initrd.img
299 # FIXME: this will likely crash on non-Linux breeds
300 f1 = os.path.join(isolinuxdir, "vmlinuz")
301 f2 = os.path.join(isolinuxdir, "initrd.img")
302 if not os.path.exists(distro.kernel):
303 utils.die(self.logger,"path does not exist: %s" % distro.kernel)
304 if not os.path.exists(distro.initrd):
305 utils.die(self.logger,"path does not exist: %s" % distro.initrd)
306 shutil.copyfile(distro.kernel, f1)
307 shutil.copyfile(distro.initrd, f2)
308
309 cmd = "rsync -rlptgu --exclude=boot.cat --exclude=TRANS.TBL --exclude=isolinux/ %s/ %s/../" % (filesource, isolinuxdir)
310 self.logger.info("- copying distro %s files (%s)" % (distname,cmd))
311 rc = utils.subprocess_call(self.logger, cmd, shell=True)
312 if rc:
313 utils.die(self.logger,"rsync of files failed")
314
315 self.logger.info("generating a isolinux.cfg")
316 isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg")
317 cfg = open(isolinuxcfg, "w+")
318 cfg.write(HEADER) # fixme, use template
319
320 for descendant in descendants:
321 data = utils.blender(self.api, True, descendant)
322
323 cfg.write("\n")
324 cfg.write("LABEL %s\n" % descendant.name)
325 cfg.write(" MENU LABEL %s\n" % descendant.name)
326 cfg.write(" kernel vmlinuz\n")
327
328 data["kickstart"] = "cdrom:/isolinux/ks-%s.cfg" % descendant.name
329
330 append_line = " append initrd=initrd.img"
331 append_line = append_line + " ks=%s " % data["kickstart"]
332 append_line = append_line + " %s\n" % data["kernel_options"]
333
334 cfg.write(append_line)
335
336 if descendant.COLLECTION_TYPE == 'profile':
337 kickstart_data = self.api.kickgen.generate_kickstart_for_profile(descendant.name)
338 elif descendant.COLLECTION_TYPE == 'system':
339 kickstart_data = self.api.kickgen.generate_kickstart_for_system(descendant.name)
340
341 cdregex = re.compile("url .*\n", re.IGNORECASE)
342 kickstart_data = cdregex.sub("cdrom\n", kickstart_data)
343
344 ks_name = os.path.join(isolinuxdir, "ks-%s.cfg" % descendant.name)
345 ks_file = open(ks_name, "w+")
346 ks_file.write(kickstart_data)
347 ks_file.close()
348
349 self.logger.info("done writing config")
350 cfg.write("\n")
351 cfg.write("MENU END\n")
352 cfg.close()
353
354 return
355
356
357 def run(self,iso=None,buildisodir=None,profiles=None,systems=None,distro=None,standalone=None,source=None,exclude_dns=None):
358
359 self.settings = self.config.settings()
360
361 # the distro option is for stand-alone builds only
362 if not standalone and distro is not None:
363 utils.die(self.logger,"The --distro option should only be used when creating a standalone ISO")
364 # if building standalone, we only want --distro,
365 # profiles/systems are disallowed
366 if standalone:
367 if profiles is not None or systems is not None:
368 utils.die(self.logger,"When building a standalone ISO, use --distro only instead of --profiles/--systems")
369 elif distro is None:
370 utils.die(self.logger,"When building a standalone ISO, you must specify a --distro")
371 if source != None and not os.path.exists(source):
372 utils.die(self.logger,"The source specified (%s) does not exist" % source)
373
374 # if iso is none, create it in . as "kickstart.iso"
375 if iso is None:
376 iso = "kickstart.iso"
377
378 if buildisodir is None:
379 buildisodir = self.settings.buildisodir
380 else:
381 if not os.path.isdir(buildisodir):
382 utils.die(self.logger,"The --tempdir specified is not a directory")
383
384 (buildisodir_head,buildisodir_tail) = os.path.split(os.path.normpath(buildisodir))
385 if buildisodir_tail != "buildiso":
386 buildisodir = os.path.join(buildisodir, "buildiso")
387
388 self.logger.info("using/creating buildisodir: %s" % buildisodir)
389 if not os.path.exists(buildisodir):
390 os.makedirs(buildisodir)
391 else:
392 shutil.rmtree(buildisodir)
393 os.makedirs(buildisodir)
394
395 # if base of buildisodir does not exist, fail
396 # create all profiles unless filtered by "profiles"
397
398 imagesdir = os.path.join(buildisodir, "images")
399 isolinuxdir = os.path.join(buildisodir, "isolinux")
400
401 self.logger.info("building tree for isolinux")
402 if not os.path.exists(imagesdir):
403 os.makedirs(imagesdir)
404 if not os.path.exists(isolinuxdir):
405 os.makedirs(isolinuxdir)
406
407 self.logger.info("copying miscellaneous files")
408
409 isolinuxbin = "/usr/share/syslinux/isolinux.bin"
410 if not os.path.exists(isolinuxbin):
411 isolinuxbin = "/usr/lib/syslinux/isolinux.bin"
412
413 menu = "/usr/share/syslinux/menu.c32"
414 if not os.path.exists(menu):
415 menu = "/var/lib/cobbler/loaders/menu.c32"
416
417 chain = "/usr/share/syslinux/chain.c32"
418 if not os.path.exists(chain):
419 chain = "/usr/lib/syslinux/chain.c32"
420
421 files = [ isolinuxbin, menu, chain ]
422 for f in files:
423 if not os.path.exists(f):
424 utils.die(self.logger,"Required file not found: %s" % f)
425 else:
426 utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f)), self.api)
427
428 if standalone:
429 self.generate_standalone_iso(imagesdir,isolinuxdir,distro,source)
430 else:
431 self.generate_netboot_iso(imagesdir,isolinuxdir,profiles,systems,exclude_dns)
432
433 # removed --quiet
434 cmd = "mkisofs -o %s -r -b isolinux/isolinux.bin -c isolinux/boot.cat" % iso
435 cmd = cmd + " -no-emul-boot -boot-load-size 4"
436 cmd = cmd + " -boot-info-table -V Cobbler\ Install -R -J -T %s" % buildisodir
437
438 rc = utils.subprocess_call(self.logger, cmd, shell=True)
439 if rc != 0:
440 utils.die(self.logger,"mkisofs failed")
441
442 self.logger.info("ISO build complete")
443 self.logger.info("You may wish to delete: %s" % buildisodir)
444 self.logger.info("The output file is: %s" % iso)
445
446 return True
447
0448
=== added file 'cobbler/action_check.py'
--- cobbler/action_check.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_check.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,482 @@
1"""
2Validates whether the system is reasonably well configured for
3serving up content. This is the code behind 'cobbler check'.
4
5Copyright 2006-2009, Red Hat, Inc
6Michael DeHaan <mdehaan@redhat.com>
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301 USA
22"""
23
24import os
25import re
26import action_sync
27import utils
28import glob
29from utils import _
30import clogger
31
32class BootCheck:
33
34 def __init__(self,config,logger=None):
35 """
36 Constructor
37 """
38 self.config = config
39 self.settings = config.settings()
40 if logger is None:
41 logger = clogger.Logger()
42 self.logger = logger
43
44
45 def run(self):
46 """
47 Returns None if there are no errors, otherwise returns a list
48 of things to correct prior to running application 'for real'.
49 (The CLI usage is "cobbler check" before "cobbler sync")
50 """
51 status = []
52 self.checked_dist = utils.check_dist()
53 self.check_name(status)
54 self.check_selinux(status)
55 if self.settings.manage_dhcp:
56 mode = self.config.api.get_sync().dhcp.what()
57 if mode == "isc":
58 self.check_dhcpd_bin(status)
59 self.check_dhcpd_conf(status)
60 self.check_service(status,"dhcpd")
61 elif mode == "dnsmasq":
62 self.check_dnsmasq_bin(status)
63 self.check_service(status,"dnsmasq")
64
65 if self.settings.manage_dns:
66 mode = self.config.api.get_sync().dns.what()
67 if mode == "bind":
68 self.check_bind_bin(status)
69 self.check_service(status,"named")
70 elif mode == "dnsmasq" and not self.settings.manage_dhcp:
71 self.check_dnsmasq_bin(status)
72 self.check_service(status,"dnsmasq")
73
74 mode = self.config.api.get_sync().tftpd.what()
75 if mode == "in_tftpd":
76 self.check_tftpd_bin(status)
77 self.check_tftpd_dir(status)
78 self.check_tftpd_conf(status)
79 elif mode == "tftpd_py":
80 self.check_ctftpd_bin(status)
81 self.check_ctftpd_dir(status)
82 self.check_ctftpd_conf(status)
83
84 self.check_service(status, "cobblerd")
85
86 self.check_bootloaders(status)
87 self.check_rsync_conf(status)
88 self.check_httpd(status)
89 self.check_iptables(status)
90 self.check_yum(status)
91 self.check_debmirror(status)
92 self.check_for_ksvalidator(status)
93 self.check_for_default_password(status)
94 self.check_for_unreferenced_repos(status)
95 self.check_for_unsynced_repos(status)
96 self.check_for_cman(status)
97
98 return status
99
100 def check_for_ksvalidator(self, status):
101 if self.checked_dist in ["debian", "ubuntu"]:
102 return
103
104 if not os.path.exists("/usr/bin/ksvalidator"):
105 status.append("ksvalidator was not found, install pykickstart")
106
107 return True
108
109 def check_for_cman(self, status):
110 # not doing rpm -q here to be cross-distro friendly
111 if not os.path.exists("/sbin/fence_ilo") and not os.path.exists("/usr/sbin/fence_ilo"):
112 status.append("fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them")
113 return True
114
115 def check_service(self, status, which, notes=""):
116 if notes != "":
117 notes = " (NOTE: %s)" % notes
118 rc = 0
119 if self.checked_dist == "redhat" or self.checked_dist == "suse":
120 if os.path.exists("/etc/rc.d/init.d/%s" % which):
121 rc = utils.subprocess_call(self.logger,"/sbin/service %s status > /dev/null 2>/dev/null" % which, shell=True)
122 if rc != 0:
123 status.append(_("service %s is not running%s") % (which,notes))
124 return False
125 elif self.checked_dist in ["debian", "ubuntu"]:
126 # we still use /etc/init.d
127 if os.path.exists("/etc/init.d/%s" % which):
128 rc = utils.subprocess_call(self.logger,"/etc/init.d/%s status /dev/null 2>/dev/null" % which, shell=True)
129 if rc != 0:
130 status.append(_("service %s is not running%s") % which,notes)
131 return False
132 elif self.checked_dist == "ubuntu":
133 if os.path.exists("/etc/init/%s.conf" % which):
134 rc = utils.subprocess_call(self.logger,"status %s > /dev/null 2>&1" % which, shell=True)
135 if rc != 0:
136 status.append(_("service %s is not running%s") % (which,notes))
137 else:
138 status.append(_("Unknown distribution type, cannot check for running service %s" % which))
139 return False
140 return True
141
142 def check_iptables(self, status):
143 if os.path.exists("/etc/rc.d/init.d/iptables"):
144 rc = utils.subprocess_call(self.logger,"/sbin/service iptables status >/dev/null 2>/dev/null", shell=True)
145 if rc == 0:
146 status.append(_("since iptables may be running, ensure 69, 80, and %(xmlrpc)s are unblocked") % { "xmlrpc" : self.settings.xmlrpc_port })
147
148 def check_yum(self,status):
149 if self.checked_dist in ["debian", "ubuntu"]:
150 return
151
152 if not os.path.exists("/usr/bin/createrepo"):
153 status.append(_("createrepo package is not installed, needed for cobbler import and cobbler reposync, install createrepo?"))
154 if not os.path.exists("/usr/bin/reposync"):
155 status.append(_("reposync is not installed, need for cobbler reposync, install/upgrade yum-utils?"))
156 if not os.path.exists("/usr/bin/yumdownloader"):
157 status.append(_("yumdownloader is not installed, needed for cobbler repo add with --rpm-list parameter, install/upgrade yum-utils?"))
158 if self.settings.reposync_flags.find("-l"):
159 if self.checked_dist == "redhat" or self.checked_dist == "suse":
160 yum_utils_ver = utils.subprocess_get(self.logger,"/usr/bin/rpmquery --queryformat=%{VERSION} yum-utils", shell=True)
161 if yum_utils_ver < "1.1.17":
162 status.append(_("yum-utils need to be at least version 1.1.17 for reposync -l, current version is %s") % yum_utils_ver )
163
164 def check_debmirror(self,status):
165 if not os.path.exists("/usr/bin/debmirror"):
166 status.append(_("debmirror package is not installed, it will be required to manage debian deployments and repositories"))
167 if os.path.exists("/etc/debmirror.conf"):
168 f = open("/etc/debmirror.conf")
169 re_dists = re.compile(r'@dists=')
170 re_arches = re.compile(r'@arches=')
171 for line in f.readlines():
172 if re_dists.search(line) and not line.strip().startswith("#"):
173 status.append(_("comment 'dists' on /etc/debmirror.conf for proper debian support"))
174 if re_arches.search(line) and not line.strip().startswith("#"):
175 status.append(_("comment 'arches' on /etc/debmirror.conf for proper debian support"))
176
177
178 def check_name(self,status):
179 """
180 If the server name in the config file is still set to localhost
181 kickstarts run from koan will not have proper kernel line
182 parameters.
183 """
184 if self.settings.server == "127.0.0.1":
185 status.append(_("The 'server' field in /etc/cobbler/settings must be set to something other than localhost, or kickstarting features will not work. This should be a resolvable hostname or IP for the boot server as reachable by all machines that will use it."))
186 if self.settings.next_server == "127.0.0.1":
187 status.append(_("For PXE to be functional, the 'next_server' field in /etc/cobbler/settings must be set to something other than 127.0.0.1, and should match the IP of the boot server on the PXE network."))
188
189 def check_selinux(self,status):
190 """
191 Suggests various SELinux rules changes to run Cobbler happily with
192 SELinux in enforcing mode. FIXME: this method could use some
193 refactoring in the future.
194 """
195 if self.checked_dist in ["debian", "ubuntu"]:
196 return
197
198 enabled = self.config.api.is_selinux_enabled()
199 if enabled:
200 data2 = utils.subprocess_get(self.logger,"/usr/sbin/getsebool -a",shell=True)
201 for line in data2.split("\n"):
202 if line.find("httpd_can_network_connect ") != -1:
203 if line.find("off") != -1:
204 status.append(_("Must enable a selinux boolean to enable vital web services components, run: setsebool -P httpd_can_network_connect true"))
205 if line.find("rsync_disable_trans ") != -1:
206 if line.find("on") != -1:
207 status.append(_("Must enable the cobbler import and replicate commands, run: setsebool -P rsync_disable_trans=1"))
208
209 data3 = utils.subprocess_get(self.logger,"/usr/sbin/semanage fcontext -l | grep public_content_t",shell=True)
210
211 rule1 = False
212 rule2 = False
213 rule3 = False
214 selinux_msg = "/usr/sbin/semanage fcontext -a -t public_content_t \"%s\""
215 for line in data3.split("\n"):
216 if line.startswith("/tftpboot/.*"):
217 rule1 = True
218 if line.startswith("/var/lib/tftpboot/.*"):
219 rule2 = True
220 if line.startswith("/var/www/cobbler/images/.*"):
221 rule3 = True
222
223 rules = []
224 if os.path.exists("/tftpboot") and not rule1:
225 rules.append(selinux_msg % "/tftpboot/.*")
226 else:
227 if not rule2:
228 rules.append(selinux_msg % "/var/lib/tftpboot/.*")
229 if not rule3:
230 rules.append(selinux_msg % "/var/www/cobbler/images/.*")
231 if len(rules) > 0:
232 status.append("you need to set some SELinux content rules to ensure cobbler serves content correctly in your SELinux environment, run the following: %s" % " && ".join(rules))
233
234 # now check to see that the Django sessions path is accessible
235 # by Apache
236
237 data4 = utils.subprocess_get(self.logger,"/usr/sbin/semanage fcontext -l | grep httpd_sys_content_rw_t",shell=True)
238 selinux_msg = "you need to set some SELinux rules if you want to use cobbler-web (an optional package), run the following: /usr/sbin/semanage fcontext -a -t httpd_sys_content_rw_t \"%s\""
239 rule4 = False
240 for line in data4.split("\n"):
241 if line.startswith("/var/lib/cobbler/webui_sessions/.*"):
242 rule4 = True
243 if not rule4:
244 status.append(selinux_msg % "/var/lib/cobbler/webui_sessions/.*")
245
246
247 def check_for_default_password(self,status):
248 default_pass = self.settings.default_password_crypted
249 if default_pass == "$1$mF86/UHC$WvcIcX2t6crBz2onWxyac.":
250 status.append(_("The default password used by the sample templates for newly installed machines (default_password_crypted in /etc/cobbler/settings) is still set to 'cobbler' and should be changed, try: \"openssl passwd -1 -salt 'random-phrase-here' 'your-password-here'\" to generate new one"))
251
252
253 def check_for_unreferenced_repos(self,status):
254 repos = []
255 referenced = []
256 not_found = []
257 for r in self.config.api.repos():
258 repos.append(r.name)
259 for p in self.config.api.profiles():
260 my_repos = p.repos
261 if my_repos != "<<inherit>>":
262 referenced.extend(my_repos)
263 for r in referenced:
264 if r not in repos and r != "<<inherit>>":
265 not_found.append(r)
266 if len(not_found) > 0:
267 status.append(_("One or more repos referenced by profile objects is no longer defined in cobbler: %s") % ", ".join(not_found))
268
269 def check_for_unsynced_repos(self,status):
270 need_sync = []
271 for r in self.config.repos():
272 if r.mirror_locally == 1:
273 lookfor = os.path.join(self.settings.webdir, "repo_mirror", r.name)
274 if not os.path.exists(lookfor):
275 need_sync.append(r.name)
276 if len(need_sync) > 0:
277 status.append(_("One or more repos need to be processed by cobbler reposync for the first time before kickstarting against them: %s") % ", ".join(need_sync))
278
279
280 def check_httpd(self,status):
281 """
282 Check if Apache is installed.
283 """
284 if self.checked_dist in [ "suse", "redhat" ]:
285 rc = utils.subprocess_get(self.logger,"httpd -v")
286 else:
287 rc = utils.subprocess_get(self.logger,"apache2 -v")
288 if rc.find("Server") == -1:
289 status.append("Apache (httpd) is not installed and/or in path")
290
291
292 def check_dhcpd_bin(self,status):
293 """
294 Check if dhcpd is installed
295 """
296 if not os.path.exists("/usr/sbin/dhcpd"):
297 status.append("dhcpd is not installed")
298
299 def check_dnsmasq_bin(self,status):
300 """
301 Check if dnsmasq is installed
302 """
303 rc = utils.subprocess_get(self.logger,"dnsmasq --help")
304 if rc.find("Valid options") == -1:
305 status.append("dnsmasq is not installed and/or in path")
306
307 def check_bind_bin(self,status):
308 """
309 Check if bind is installed.
310 """
311 rc = utils.subprocess_get(self.logger,"named -v")
312 # it should return something like "BIND 9.6.1-P1-RedHat-9.6.1-6.P1.fc11"
313 if rc.find("BIND") == -1:
314 status.append("named is not installed and/or in path")
315
316 def check_bootloaders(self,status):
317 """
318 Check if network bootloaders are installed
319 """
320 # FIXME: move zpxe.rexx to loaders
321
322 bootloaders = {
323 "elilo" : [ "/var/lib/cobbler/loaders/elilo*.efi" ],
324 "menu.c32" : [ "/usr/share/syslinux/menu.c32",
325 "/usr/lib/syslinux/menu.c32",
326 "/var/lib/cobbler/loaders/menu.c32" ],
327 "yaboot" : [ "/var/lib/cobbler/loaders/yaboot*" ],
328 "pxelinux.0" : [ "/usr/share/syslinux/pxelinux.0",
329 "/usr/lib/syslinux/pxelinux.0",
330 "/var/lib/cobbler/loaders/pxelinux.0" ],
331 "efi" : [ "/var/lib/cobbler/loaders/grub-x86.efi",
332 "/var/lib/cobbler/loaders/grub-x86_64.efi" ],
333 }
334
335 # look for bootloaders at the glob locations above
336 found_bootloaders = []
337 items = bootloaders.keys()
338 for loader_name in items:
339 patterns = bootloaders[loader_name]
340 for pattern in patterns:
341 matches = glob.glob(pattern)
342 if len(matches) > 0:
343 found_bootloaders.append(loader_name)
344 not_found = []
345
346 # invert the list of what we've found so we can report on what we haven't found
347 for loader_name in items:
348 if loader_name not in found_bootloaders:
349 not_found.append(loader_name)
350
351 if len(not_found) > 0:
352 status.append("some network boot-loaders are missing from /var/lib/cobbler/loaders, you may run 'cobbler get-loaders' to download them, or, if you only want to handle x86/x86_64 netbooting, you may ensure that you have installed a *recent* version of the syslinux package installed and can ignore this message entirely. Files in this directory, should you want to support all architectures, should include pxelinux.0, menu.c32, elilo.efi, and yaboot. The 'cobbler get-loaders' command is the easiest way to resolve these requirements.")
353
354 def check_tftpd_bin(self,status):
355 """
356 Check if tftpd is installed
357 """
358 if self.checked_dist in ["debian", "ubuntu"]:
359 return
360
361 if not os.path.exists("/etc/xinetd.d/tftp"):
362 status.append("missing /etc/xinetd.d/tftp, install tftp-server?")
363
364 def check_tftpd_dir(self,status):
365 """
366 Check if cobbler.conf's tftpboot directory exists
367 """
368 if self.checked_dist in ["debian", "ubuntu"]:
369 return
370
371 bootloc = utils.tftpboot_location()
372 if not os.path.exists(bootloc):
373 status.append(_("please create directory: %(dirname)s") % { "dirname" : bootloc })
374
375
376 def check_tftpd_conf(self,status):
377 """
378 Check that configured tftpd boot directory matches with actual
379 Check that tftpd is enabled to autostart
380 """
381 if self.checked_dist in ["debian", "ubuntu"]:
382 return
383
384 if os.path.exists("/etc/xinetd.d/tftp"):
385 f = open("/etc/xinetd.d/tftp")
386 re_disable = re.compile(r'disable.*=.*yes')
387 for line in f.readlines():
388 if re_disable.search(line) and not line.strip().startswith("#"):
389 status.append(_("change 'disable' to 'no' in %(file)s") % { "file" : "/etc/xinetd.d/tftp" })
390 else:
391 status.append("missing configuration file: /etc/xinetd.d/tftp")
392
393 def check_ctftpd_bin(self,status):
394 """
395 Check if the Cobbler tftp server is installed
396 """
397 if self.checked_dist in ["debian", "ubuntu"]:
398 return
399
400 if not os.path.exists("/etc/xinetd.d/ctftp"):
401 status.append("missing /etc/xinetd.d/ctftp")
402
403 def check_ctftpd_dir(self,status):
404 """
405 Check if cobbler.conf's tftpboot directory exists
406 """
407 if self.checked_dist in ["debian", "ubuntu"]:
408 return
409
410 bootloc = utils.tftpboot_location()
411 if not os.path.exists(bootloc):
412 status.append(_("please create directory: %(dirname)s") % { "dirname" : bootloc })
413
414 def check_ctftpd_conf(self,status):
415 """
416 Check that configured tftpd boot directory matches with actual
417 Check that tftpd is enabled to autostart
418 """
419 if self.checked_dist in ["debian", "ubuntu"]:
420 return
421
422 if os.path.exists("/etc/xinetd.d/tftp"):
423 f = open("/etc/xinetd.d/tftp")
424 re_disable = re.compile(r'disable.*=.*no')
425 for line in f.readlines():
426 if re_disable.search(line) and not line.strip().startswith("#"):
427 status.append(_("change 'disable' to 'yes' in %(file)s") % { "file" : "/etc/xinetd.d/tftp" })
428 if os.path.exists("/etc/xinetd.d/ctftp"):
429 f = open("/etc/xinetd.d/ctftp")
430 re_disable = re.compile(r'disable.*=.*yes')
431 for line in f.readlines():
432 if re_disable.search(line) and not line.strip().startswith("#"):
433 status.append(_("change 'disable' to 'no' in %(file)s") % { "file" : "/etc/xinetd.d/ctftp" })
434 else:
435 status.append("missing configuration file: /etc/xinetd.d/ctftp")
436
437 def check_rsync_conf(self,status):
438 """
439 Check that rsync is enabled to autostart
440 """
441 if self.checked_dist in ["debian", "ubuntu"]:
442 return
443
444 if os.path.exists("/etc/xinetd.d/rsync"):
445 f = open("/etc/xinetd.d/rsync")
446 re_disable = re.compile(r'disable.*=.*yes')
447 for line in f.readlines():
448 if re_disable.search(line) and not line.strip().startswith("#"):
449 status.append(_("change 'disable' to 'no' in %(file)s") % { "file" : "/etc/xinetd.d/rsync" })
450 else:
451 status.append(_("file %(file)s does not exist") % { "file" : "/etc/xinetd.d/rsync" })
452
453
454 def check_dhcpd_conf(self,status):
455 """
456 NOTE: this code only applies if cobbler is *NOT* set to generate
457 a dhcp.conf file
458
459 Check that dhcpd *appears* to be configured for pxe booting.
460 We can't assure file correctness. Since a cobbler user might
461 have dhcp on another server, it's okay if it's not there and/or
462 not configured correctly according to automated scans.
463 """
464 if not (self.settings.manage_dhcp == 0):
465 return
466
467 if os.path.exists(self.settings.dhcpd_conf):
468 match_next = False
469 match_file = False
470 f = open(self.settings.dhcpd_conf)
471 for line in f.readlines():
472 if line.find("next-server") != -1:
473 match_next = True
474 if line.find("filename") != -1:
475 match_file = True
476 if not match_next:
477 status.append(_("expecting next-server entry in %(file)s") % { "file" : self.settings.dhcpd_conf })
478 if not match_file:
479 status.append(_("missing file: %(file)s") % { "file" : self.settings.dhcpd_conf })
480 else:
481 status.append(_("missing file: %(file)s") % { "file" : self.settings.dhcpd_conf })
482
0483
=== added file 'cobbler/action_dlcontent.py'
--- cobbler/action_dlcontent.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_dlcontent.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,96 @@
1"""
2Downloads bootloader content for all arches for when the user doesn't want to supply their own.
3
4Copyright 2009, Red Hat, Inc
5Michael DeHaan <mdehaan@redhat.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301 USA
21"""
22
23import os
24import urlgrabber
25import clogger
26
27class ContentDownloader:
28
29 def __init__(self,config,logger=None):
30 """
31 Constructor
32 """
33 self.config = config
34 self.settings = config.settings()
35 if logger is None:
36 logger = clogger.Logger()
37 self.logger = logger
38
39
40 def run(self,force=False):
41 """
42 Download bootloader content for all of the latest bootloaders, since the user
43 has chosen to not supply their own. You may ask "why not get this from yum", though
44 Fedora has no IA64 repo, for instance, and we also want this to be able to work on Debian and
45 further do not want folks to have to install a cross compiler. For those that don't like this approach
46 they can still source their cross-arch bootloader content manually.
47 """
48
49 content_server = "http://dgoodwin.fedorapeople.org/loaders"
50 dest = "/var/lib/cobbler/loaders"
51
52 files = (
53 ( "%s/README" % content_server, "%s/README" % dest ),
54 ( "%s/COPYING.elilo" % content_server, "%s/COPYING.elilo" % dest ),
55 ( "%s/COPYING.yaboot" % content_server, "%s/COPYING.yaboot" % dest),
56 ( "%s/COPYING.syslinux" % content_server, "%s/COPYING.syslinux" % dest),
57 ( "%s/elilo-3.8-ia64.efi" % content_server, "%s/elilo-ia64.efi" % dest ),
58 ( "%s/yaboot-1.3.14-12" % content_server, "%s/yaboot" % dest),
59 ( "%s/pxelinux.0-3.61" % content_server, "%s/pxelinux.0" % dest),
60 ( "%s/menu.c32-3.61" % content_server, "%s/menu.c32" % dest),
61 ( "%s/grub-0.97-x86.efi" % content_server, "%s/grub-x86.efi" % dest),
62 ( "%s/grub-0.97-x86_64.efi" % content_server, "%s/grub-x86_64.efi" % dest),
63 )
64
65 proxies = {}
66 for var in os.environ.keys():
67 if (var.lower() == "http_proxy"):
68 proxies['http'] = os.environ[var]
69
70 if (var.lower() == "ftp_proxy"):
71 proxies['ftp'] = os.environ[var]
72
73 if (len(proxies) > 0):
74 for f in files:
75 src = f[0]
76 dst = f[1]
77 if os.path.exists(dst) and not force:
78 self.logger.info("path %s already exists, not overwriting existing content, use --force if you wish to update" % dst)
79 continue
80 os.chdir(dest)
81 self.logger.info("downloading %s to %s" % (src,dst))
82 urlgrabber.grabber.urlgrab(src, proxies=proxies)
83
84 else:
85 self.logger.info("downloading content required to netboot all arches")
86 for f in files:
87 src = f[0]
88 dst = f[1]
89 if os.path.exists(dst) and not force:
90 self.logger.info("path %s already exists, not overwriting existing content, use --force if you wish to update" % dst)
91 continue
92 self.logger.info("downloading %s to %s" % (src,dst))
93 urlgrabber.urlgrab(src,dst)
94
95 return True
96
097
=== added file 'cobbler/action_hardlink.py'
--- cobbler/action_hardlink.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_hardlink.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,60 @@
1"""
2Hard links cobbler content together to save space.
3
4Copyright 2009, Red Hat, Inc
5Michael DeHaan <mdehaan@redhat.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301 USA
21"""
22
23import os
24import utils
25from cexceptions import *
26import clogger
27
28class HardLinker:
29
30 def __init__(self,config,logger=None):
31 """
32 Constructor
33 """
34 #self.config = config
35 #self.api = config.api
36 #self.settings = config.settings()
37 if logger is None:
38 logger = clogger.Logger()
39 self.logger = logger
40
41
42 def run(self):
43 """
44 Simply hardlinks directories that are cobbler managed.
45 This is a /very/ simple command but may grow more complex
46 and intelligent over time.
47 """
48
49 # FIXME: if these directories become configurable some
50 # changes will be required here.
51
52 if not os.path.exists("/usr/sbin/hardlink"):
53 utils.die(self.logger,"please install 'hardlink' (/usr/sbin/hardlink) to use this feature")
54
55 self.logger.info("now hardlinking to save space, this may take some time.")
56
57 rc = utils.subprocess_call(self.logger,"/usr/sbin/hardlink -c -v /var/www/cobbler/ks_mirror /var/www/cobbler/repo_mirror",shell=True)
58
59 return rc
60
061
=== added file 'cobbler/action_import.py'
--- cobbler/action_import.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_import.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,1332 @@
1"""
2Enables the "cobbler import" command to seed cobbler
3information with available distribution from rsync mirrors
4and mounted DVDs.
5
6Copyright 2006-2009, Red Hat, Inc
7Michael DeHaan <mdehaan@redhat.com>
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2202110-1301 USA
23"""
24
25from cexceptions import *
26import os
27import os.path
28import re
29import traceback
30import glob
31import api
32import utils
33import shutil
34from utils import _
35import item_repo
36import clogger
37
38# FIXME: add --quiet depending on if not --verbose?
39RSYNC_CMD = "rsync -a %s '%s' %s/ks_mirror/%s --exclude-from=/etc/cobbler/rsync.exclude --progress"
40
41class Importer:
42
43 def __init__(self,api,config,mirror,mirror_name,network_root=None,kickstart_file=None,rsync_flags=None,arch=None,breed=None,os_version=None,logger=None):
44 """
45 Performs an import of a install tree (or trees) from the given
46 mirror address. The prefix of the distro is to be specified
47 by mirror name. For instance, if FC-6 is given, FC-6-xen-i386
48 would be a potential distro that could be created. For content
49 available on external servers via a known nfs:// or ftp:// or
50 http:// path, we can import without doing rsync mirorring to
51 cobbler's http directory. This is explained in more detail
52 in the manpage. Leave network_root to None if want mirroring.
53 """
54 self.api = api
55 self.config = config
56 self.mirror = mirror
57 self.mirror_name = mirror_name
58 self.network_root = network_root
59 self.distros = config.distros()
60 self.profiles = config.profiles()
61 self.systems = config.systems()
62 self.settings = config.settings()
63 self.kickstart_file = kickstart_file
64 self.rsync_flags = rsync_flags
65 self.arch = arch
66 self.breed = breed
67 self.os_version = os_version
68 if logger is None:
69 logger = clogger.Logger()
70 self.logger = logger
71
72
73 # ========================================================================
74
75 def run(self):
76
77 """
78 This contains the guts of the import command.
79 """
80
81 # some fixups for the XMLRPC interface, which does not use "None"
82 if self.arch == "": self.arch = None
83 if self.mirror == "": self.mirror = None
84 if self.mirror_name == "": self.mirror_name = None
85 if self.breed == "": self.breed = None
86 if self.kickstart_file == "": self.kickstart_file = None
87 if self.os_version == "": self.os_version = None
88 if self.rsync_flags == "": self.rsync_flags = None
89 if self.network_root == "": self.network_root = None
90
91 # both --import and --name are required arguments
92
93 if self.mirror is None:
94 utils.die(self.logger,"import failed. no --path specified")
95 if self.mirror_name is None:
96 utils.die(self.logger,"import failed. no --name specified")
97
98 # if --arch is supplied, validate it to ensure it's valid
99
100 if self.arch is not None and self.arch != "":
101 self.arch = self.arch.lower()
102 if self.arch == "x86":
103 # be consistent
104 self.arch = "i386"
105 if self.arch not in [ "i386", "ia64", "ppc", "ppc64", "s390", "s390x", "x86_64", ]:
106 utils.die(self.logger,"arch must be i386, ia64, ppc, ppc64, s390, s390x or x86_64")
107
108 # if we're going to do any copying, set where to put things
109 # and then make sure nothing is already there.
110
111 mpath = os.path.join(self.settings.webdir, "ks_mirror", self.mirror_name)
112 if os.path.exists(mpath) and self.arch is None:
113 # FIXME : Raise exception even when network_root is given ?
114 utils.die(self.logger,"Something already exists at this import location (%s). You must specify --arch to avoid potentially overwriting existing files." % mpath)
115
116 # import takes a --kickstart for forcing selection that can't be used in all circumstances
117
118 if self.kickstart_file and not self.breed:
119 utils.die(self.logger,"Kickstart file can only be specified when a specific breed is selected")
120
121 if self.os_version and not self.breed:
122 utils.die(self.logger,"OS version can only be specified when a specific breed is selected")
123
124 #if self.breed and self.breed.lower() not in [ "redhat", "debian", "ubuntu", "windows" ]:
125 #if self.breed and self.breed.lower() not in [ "redhat" ]:
126 if self.breed and self.breed.lower() not in [ "redhat", "vmware" ]:
127 utils.die(self.logger,"Supplied import breed is not supported")
128
129 # if --arch is supplied, make sure the user is not importing a path with a different
130 # arch, which would just be silly.
131
132 if self.arch:
133 # append the arch path to the name if the arch is not already
134 # found in the name.
135 for x in [ "i386", "ia64", "ppc", "ppc64", "s390", "s390x", "x86_64", "x86", ]:
136 if self.mirror_name.lower().find(x) != -1:
137 if self.arch != x :
138 utils.die(self.logger,"Architecture found on pathname (%s) does not fit the one given in command line (%s)"%(x,self.arch))
139 break
140 else:
141 # FIXME : This is very likely removed later at get_proposed_name, and the guessed arch appended again
142 self.mirror_name = self.mirror_name + "-" + self.arch
143
144 # make the output path and mirror content but only if not specifying that a network
145 # accessible support location already exists (this is --available-as on the command line)
146
147 if self.network_root is None:
148
149 # we need to mirror (copy) the files
150
151 self.path = os.path.normpath( "%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name) )
152 self.mkdir(self.path)
153
154 # prevent rsync from creating the directory name twice
155 # if we are copying via rsync
156
157 if not self.mirror.endswith("/"):
158 self.mirror = "%s/" % self.mirror
159
160 if self.mirror.startswith("http://") or self.mirror.startswith("ftp://") or self.mirror.startswith("nfs://"):
161
162 # http mirrors are kind of primative. rsync is better.
163 # that's why this isn't documented in the manpage and we don't support them.
164 # TODO: how about adding recursive FTP as an option?
165
166 utils.die(self.logger,"unsupported protocol")
167
168 else:
169
170 # good, we're going to use rsync..
171 # we don't use SSH for public mirrors and local files.
172 # presence of user@host syntax means use SSH
173
174 spacer = ""
175 if not self.mirror.startswith("rsync://") and not self.mirror.startswith("/"):
176 spacer = ' -e "ssh" '
177 rsync_cmd = RSYNC_CMD
178 if self.rsync_flags:
179 rsync_cmd = rsync_cmd + " " + self.rsync_flags
180
181 # kick off the rsync now
182
183 self.run_this(rsync_cmd, (spacer, self.mirror, self.settings.webdir, self.mirror_name))
184
185 else:
186
187 # rather than mirroring, we're going to assume the path is available
188 # over http, ftp, and nfs, perhaps on an external filer. scanning still requires
189 # --mirror is a filesystem path, but --available-as marks the network path
190
191 if not os.path.exists(self.mirror):
192 utils.die(self.logger, "path does not exist: %s" % self.mirror)
193
194 # find the filesystem part of the path, after the server bits, as each distro
195 # URL needs to be calculated relative to this.
196
197 if not self.network_root.endswith("/"):
198 self.network_root = self.network_root + "/"
199 self.path = os.path.normpath( self.mirror )
200 valid_roots = [ "nfs://", "ftp://", "http://" ]
201 for valid_root in valid_roots:
202 if self.network_root.startswith(valid_root):
203 break
204 else:
205 utils.die(self.logger, "Network root given to --available-as must be nfs://, ftp://, or http://")
206 if self.network_root.startswith("nfs://"):
207 try:
208 (a,b,rest) = self.network_root.split(":",3)
209 except:
210 utils.die(self.logger, "Network root given to --available-as is missing a colon, please see the manpage example.")
211
212 # now walk the filesystem looking for distributions that match certain patterns
213
214 self.logger.info("adding distros")
215 distros_added = []
216 # FIXME : search below self.path for isolinux configurations or known directories from TRY_LIST
217 os.path.walk(self.path, self.distro_adder, distros_added)
218
219 # find out if we can auto-create any repository records from the install tree
220
221 if self.network_root is None:
222 self.logger.info("associating repos")
223 # FIXME: this automagic is not possible (yet) without mirroring
224 self.repo_finder(distros_added)
225
226 # find the most appropriate answer files for each profile object
227
228 self.logger.info("associating kickstarts")
229 self.kickstart_finder(distros_added)
230
231 # ensure bootloaders are present
232 self.api.pxegen.copy_bootloaders()
233
234 return True
235
236 # ----------------------------------------------------------------------
237
238 def mkdir(self, dir):
239
240 """
241 A more tolerant mkdir.
242 FIXME: use the one in utils.py (?)
243 """
244
245 try:
246 os.makedirs(dir)
247 except OSError , ex:
248 if ex.strerror == "Permission denied":
249 utils.die(self.logger, "Permission denied at %s" % dir)
250 except:
251 pass
252
253 # ----------------------------------------------------------------------
254
255 def run_this(self, cmd, args):
256
257 """
258 A simple wrapper around subprocess calls.
259 """
260
261 my_cmd = cmd % args
262 rc = utils.subprocess_call(self.logger,my_cmd,shell=True)
263 if rc != 0:
264 utils.die(self.logger,"Command failed")
265
266 # =======================================================================
267
268 def kickstart_finder(self,distros_added):
269
270 """
271 For all of the profiles in the config w/o a kickstart, use the
272 given kickstart file, or look at the kernel path, from that,
273 see if we can guess the distro, and if we can, assign a kickstart
274 if one is available for it.
275 """
276 for profile in self.profiles:
277 distro = self.distros.find(name=profile.get_conceptual_parent().name)
278 if distro is None or not (distro in distros_added):
279 continue
280
281 kdir = os.path.dirname(distro.kernel)
282 importer = import_factory(kdir,self.path,self.breed,self.logger)
283 if self.kickstart_file == None:
284 for rpm in importer.get_release_files():
285 # FIXME : This redhat specific check should go into the importer.find_release_files method
286 if rpm.find("notes") != -1:
287 continue
288 results = importer.scan_pkg_filename(rpm)
289 # FIXME : If os is not found on tree but set with CLI, no kickstart is searched
290 if results is None:
291 self.logger.warning("No version found on imported tree")
292 continue
293 (flavor, major, minor) = results
294 version , ks = importer.set_variance(flavor, major, minor, distro.arch)
295 if self.os_version:
296 if self.os_version != version:
297 utils.die(self.logger,"CLI version differs from tree : %s vs. %s" % (self.os_version,version))
298 ds = importer.get_datestamp()
299 distro.set_comment("%s.%s" % (version, int(minor)))
300 distro.set_os_version(version)
301 if ds is not None:
302 distro.set_tree_build_time(ds)
303 profile.set_kickstart(ks)
304 self.profiles.add(profile,save=True)
305
306 self.configure_tree_location(distro,importer)
307 self.distros.add(distro,save=True) # re-save
308 self.api.serialize()
309
310 # ==========================================================================
311
312
313 def configure_tree_location(self, distro, importer):
314
315 """
316 Once a distribution is identified, find the part of the distribution
317 that has the URL in it that we want to use for kickstarting the
318 distribution, and create a ksmeta variable $tree that contains this.
319 """
320
321 base = importer.get_rootdir()
322
323 if self.network_root is None:
324 if distro.breed == "debian" or distro.breed == "ubuntu":
325 dists_path = os.path.join( self.path , "dists" )
326 if os.path.isdir( dists_path ):
327 tree = "http://@@http_server@@/cblr/ks_mirror/%s" % (self.mirror_name)
328 else:
329 tree = "http://@@http_server@@/cblr/repo_mirror/%s" % (distro.name)
330 else:
331 dest_link = os.path.join(self.settings.webdir, "links", distro.name)
332 # create the links directory only if we are mirroring because with
333 # SELinux Apache can't symlink to NFS (without some doing)
334 if not os.path.exists(dest_link):
335 try:
336 os.symlink(base, dest_link)
337 except:
338 # this shouldn't happen but I've seen it ... debug ...
339 self.logger.warning("symlink creation failed: %(base)s, %(dest)s") % { "base" : base, "dest" : dest_link }
340 # how we set the tree depends on whether an explicit network_root was specified
341 tree = "http://@@http_server@@/cblr/links/%s" % (distro.name)
342 importer.set_install_tree( distro, tree)
343 else:
344 # where we assign the kickstart source is relative to our current directory
345 # and the input start directory in the crawl. We find the path segments
346 # between and tack them on the network source path to find the explicit
347 # network path to the distro that Anaconda can digest.
348 tail = self.path_tail(self.path, base)
349 tree = self.network_root[:-1] + tail
350 importer.set_install_tree( distro, tree)
351
352 # ============================================================================
353
354 def path_tail(self, apath, bpath):
355 """
356 Given two paths (B is longer than A), find the part in B not in A
357 """
358 position = bpath.find(apath)
359 if position != 0:
360 utils.die(self.logger, "- warning: possible symlink traversal?: %s")
361 rposition = position + len(self.mirror)
362 result = bpath[rposition:]
363 if not result.startswith("/"):
364 result = "/" + result
365 return result
366
367 # ======================================================================
368
369 def repo_finder(self,distros_added):
370
371 """
372 This routine looks through all distributions and tries to find
373 any applicable repositories in those distributions for post-install
374 usage.
375 """
376
377 for distro in distros_added:
378 self.logger.info("traversing distro %s" % distro.name)
379 # FIXME : Shouldn't decide this the value of self.network_root ?
380 if distro.kernel.find("ks_mirror") != -1:
381 basepath = os.path.dirname(distro.kernel)
382 importer = import_factory(basepath,self.path,self.breed,self.logger)
383 top = importer.get_rootdir()
384 self.logger.info("descent into %s" % top)
385 if distro.breed in [ "debian" , "ubuntu" ]:
386 dists_path = os.path.join( self.path , "dists" )
387 if not os.path.isdir( dists_path ):
388 importer.process_repos( self , distro )
389 else:
390 # FIXME : The location of repo definition is known from breed
391 os.path.walk(top, self.repo_scanner, distro)
392 else:
393 self.logger.info("this distro isn't mirrored")
394
395 # ========================================================================
396
397
398 def repo_scanner(self,distro,dirname,fnames):
399
400 """
401 This is an os.path.walk routine that looks for potential yum repositories
402 to be added to the configuration for post-install usage.
403 """
404
405 matches = {}
406 for x in fnames:
407 if x == "base" or x == "repodata":
408 self.logger.info("processing repo at : %s" % dirname)
409 # only run the repo scanner on directories that contain a comps.xml
410 gloob1 = glob.glob("%s/%s/*comps*.xml" % (dirname,x))
411 if len(gloob1) >= 1:
412 if matches.has_key(dirname):
413 self.logger.info("looks like we've already scanned here: %s" % dirname)
414 continue
415 self.logger.info("need to process repo/comps: %s" % dirname)
416 self.process_comps_file(dirname, distro)
417 matches[dirname] = 1
418 else:
419 self.logger.info("directory %s is missing xml comps file, skipping" % dirname)
420 continue
421
422 # =======================================================================================
423
424
425
426 def process_comps_file(self, comps_path, distro):
427 """
428 When importing Fedora/EL certain parts of the install tree can also be used
429 as yum repos containing packages that might not yet be available via updates
430 in yum. This code identifies those areas.
431 """
432
433 processed_repos = {}
434
435 masterdir = "repodata"
436 if not os.path.exists(os.path.join(comps_path, "repodata")):
437 # older distros...
438 masterdir = "base"
439
440 # figure out what our comps file is ...
441 self.logger.info("looking for %(p1)s/%(p2)s/*comps*.xml" % { "p1" : comps_path, "p2" : masterdir })
442 files = glob.glob("%s/%s/*comps*.xml" % (comps_path, masterdir))
443 if len(files) == 0:
444 self.logger.info("no comps found here: %s" % os.path.join(comps_path, masterdir))
445 return # no comps xml file found
446
447 # pull the filename from the longer part
448 comps_file = files[0].split("/")[-1]
449
450 try:
451
452 # store the yum configs on the filesystem so we can use them later.
453 # and configure them in the kickstart post, etc
454
455 counter = len(distro.source_repos)
456
457 # find path segment for yum_url (changing filesystem path to http:// trailing fragment)
458 seg = comps_path.rfind("ks_mirror")
459 urlseg = comps_path[seg+10:]
460
461 # write a yum config file that shows how to use the repo.
462 if counter == 0:
463 dotrepo = "%s.repo" % distro.name
464 else:
465 dotrepo = "%s-%s.repo" % (distro.name, counter)
466
467 fname = os.path.join(self.settings.webdir, "ks_mirror", "config", "%s-%s.repo" % (distro.name, counter))
468
469 repo_url = "http://@@http_server@@/cobbler/ks_mirror/config/%s-%s.repo" % (distro.name, counter)
470
471 repo_url2 = "http://@@http_server@@/cobbler/ks_mirror/%s" % (urlseg)
472
473 distro.source_repos.append([repo_url,repo_url2])
474
475 # NOTE: the following file is now a Cheetah template, so it can be remapped
476 # during sync, that's why we have the @@http_server@@ left as templating magic.
477 # repo_url2 is actually no longer used. (?)
478
479 config_file = open(fname, "w+")
480 config_file.write("[core-%s]\n" % counter)
481 config_file.write("name=core-%s\n" % counter)
482 config_file.write("baseurl=http://@@http_server@@/cobbler/ks_mirror/%s\n" % (urlseg))
483 config_file.write("enabled=1\n")
484 config_file.write("gpgcheck=0\n")
485 config_file.write("priority=$yum_distro_priority\n")
486 config_file.close()
487
488 # don't run creatrepo twice -- this can happen easily for Xen and PXE, when
489 # they'll share same repo files.
490
491 if not processed_repos.has_key(comps_path):
492 utils.remove_yum_olddata(comps_path)
493 #cmd = "createrepo --basedir / --groupfile %s %s" % (os.path.join(comps_path, masterdir, comps_file), comps_path)
494 cmd = "createrepo %s --groupfile %s %s" % (self.settings.createrepo_flags,os.path.join(comps_path, masterdir, comps_file), comps_path)
495 utils.subprocess_call(self.logger, cmd, shell=True)
496 processed_repos[comps_path] = 1
497 # for older distros, if we have a "base" dir parallel with "repodata", we need to copy comps.xml up one...
498 p1 = os.path.join(comps_path, "repodata", "comps.xml")
499 p2 = os.path.join(comps_path, "base", "comps.xml")
500 if os.path.exists(p1) and os.path.exists(p2):
501 shutil.copyfile(p1,p2)
502
503 except:
504 self.logger.error("error launching createrepo (not installed?), ignoring")
505 utils.log_exc(self.logger)
506
507
508 # ========================================================================
509
510 def distro_adder(self,distros_added,dirname,fnames):
511
512 """
513 This is an os.path.walk routine that finds distributions in the directory
514 to be scanned and then creates them.
515 """
516
517 # FIXME: If there are more than one kernel or initrd image on the same directory,
518 # results are unpredictable
519
520 initrd = None
521 kernel = None
522
523 # make sure we don't mismatch PAE and non-PAE types
524 pae_initrd = None
525 pae_kernel = None
526
527 for x in fnames:
528 adtls = []
529
530 fullname = os.path.join(dirname,x)
531 if os.path.islink(fullname) and os.path.isdir(fullname):
532 if fullname.startswith(self.path):
533 # Prevent infinite loop with Sci Linux 5
534 self.logger.warning("avoiding symlink loop")
535 continue
536 self.logger.info("following symlink: %s" % fullname)
537 os.path.walk(fullname, self.distro_adder, distros_added)
538
539 if ( x.startswith("initrd") or x.startswith("ramdisk.image.gz") or x.startswith("vmkboot.gz") ) and x != "initrd.size" and x != "initrd.addrsize":
540 if x.find("PAE") == -1:
541 initrd = os.path.join(dirname,x)
542 else:
543 pae_initrd = os.path.join(dirname, x)
544
545 if ( x.startswith("vmlinu") or x.startswith("kernel.img") or x.startswith("linux") or x.startswith("mboot.c32") ) and x.find("initrd") == -1:
546 if x.find("PAE") == -1:
547 kernel = os.path.join(dirname,x)
548 else:
549 pae_kernel = os.path.join(dirname, x)
550
551 # if we've collected a matching kernel and initrd pair, turn the in and add them to the list
552 if initrd is not None and kernel is not None and dirname.find("isolinux") == -1:
553 adtls.append(self.add_entry(dirname,kernel,initrd))
554 kernel = None
555 initrd = None
556 elif pae_initrd is not None and pae_kernel is not None and dirname.find("isolinux") == -1:
557 adtls.append(self.add_entry(dirname,pae_kernel,pae_initrd))
558 pae_kernel = None
559 pae_initrd = None
560 elif initrd is not None and kernel is not None and dirname.find("VMware") == -1:
561 adtls.append(self.add_entry(dirname,kernel,initrd))
562 kernel = None
563 initrd = None
564 for adtl in adtls:
565 distros_added.extend(adtl)
566
567
568
569
570 # ========================================================================
571
572 def add_entry(self,dirname,kernel,initrd):
573
574 """
575 When we find a directory with a valid kernel/initrd in it, create the distribution objects
576 as appropriate and save them. This includes creating xen and rescue distros/profiles
577 if possible.
578 """
579
580 proposed_name = self.get_proposed_name(dirname,kernel)
581 proposed_arch = self.get_proposed_arch(dirname)
582
583 if self.arch and proposed_arch and self.arch != proposed_arch:
584 utils.die(self.logger,"Arch from pathname (%s) does not match with supplied one %s"%(proposed_arch,self.arch))
585
586 importer = import_factory(dirname,self.path,self.breed,self.logger)
587
588 archs = importer.learn_arch_from_tree()
589 if not archs:
590 if self.arch:
591 archs.append( self.arch )
592 else:
593 if self.arch and self.arch not in archs:
594 utils.die(self.logger, "Given arch (%s) not found on imported tree %s"%(self.arch,importer.get_pkgdir()))
595 if proposed_arch:
596 if archs and proposed_arch not in archs:
597 self.logger.warning("arch from pathname (%s) not found on imported tree %s" % (proposed_arch,importer.get_pkgdir()))
598 return
599
600 archs = [ proposed_arch ]
601
602 if importer.breed == "ubuntu" and dirname.find("ubuntu-installer") == -1:
603 self.logger.info("skipping entry, there are no netboot images")
604 return
605
606
607 if len(archs)>1:
608 if importer.breed in [ "redhat" ]:
609 self.logger.warning("directory %s holds multiple arches : %s" % (dirname, archs))
610 return
611 self.logger.warning("- Warning : Multiple archs found : %s" % (archs))
612
613 distros_added = []
614
615 for pxe_arch in archs:
616
617 name = proposed_name + "-" + pxe_arch
618 existing_distro = self.distros.find(name=name)
619
620 if existing_distro is not None:
621 self.logger.warning("skipping import, as distro name already exists: %s" % name)
622 continue
623
624 else:
625 self.logger.info("creating new distro: %s" % name)
626 distro = self.config.new_distro()
627
628 if name.find("-autoboot") != -1:
629 # this is an artifact of some EL-3 imports
630 continue
631
632 distro.set_name(name)
633 distro.set_kernel(kernel)
634 distro.set_initrd(initrd)
635 distro.set_arch(pxe_arch)
636 distro.set_breed(importer.breed)
637 # If a version was supplied on command line, we set it now
638 if self.os_version:
639 distro.set_os_version(self.os_version)
640
641 self.distros.add(distro,save=True)
642 distros_added.append(distro)
643
644 existing_profile = self.profiles.find(name=name)
645
646 # see if the profile name is already used, if so, skip it and
647 # do not modify the existing profile
648
649 if existing_profile is None:
650 self.logger.info("creating new profile: %s" % name)
651 #FIXME: The created profile holds a default kickstart, and should be breed specific
652 profile = self.config.new_profile()
653 else:
654 self.logger.info("skipping existing profile, name already exists: %s" % name)
655 continue
656
657 # save our minimal profile which just points to the distribution and a good
658 # default answer file
659
660 profile.set_name(name)
661 profile.set_distro(name)
662 if self.kickstart_file:
663 profile.set_kickstart(self.kickstart_file)
664 else:
665 profile.set_kickstart(importer.ks)
666
667 # depending on the name of the profile we can define a good virt-type
668 # for usage with koan
669
670 if name.find("-xen") != -1:
671 profile.set_virt_type("xenpv")
672 elif name.find("vmware") != -1:
673 profile.set_virt_type("vmware")
674 else:
675 profile.set_virt_type("qemu")
676
677 # save our new profile to the collection
678
679 self.profiles.add(profile,save=True)
680
681 # Create a rescue image as well, if this is not a xen distro
682 # but only for red hat profiles
683
684 # this code disabled as it seems to be adding "-rescue" to
685 # distros that are /not/ rescue related, which is wrong.
686 # left as a FIXME for those who find this feature interesting.
687
688 #if name.find("-xen") == -1 and importer.breed == "redhat":
689 # rescue_name = 'rescue-' + name
690 # existing_profile = self.profiles.find(name=rescue_name)
691 #
692 # if existing_profile is None:
693 # self.logger.info("creating new profile: %s" % rescue_name)
694 # profile = self.config.new_profile()
695 # else:
696 # continue
697 #
698 # profile.set_name(rescue_name)
699 # profile.set_distro(name)
700 # profile.set_virt_type("qemu")
701 # profile.kernel_options['rescue'] = None
702 # profile.kickstart = '/var/lib/cobbler/kickstarts/pxerescue.ks'
703 #
704 # self.profiles.add(profile,save=True)
705
706 # self.api.serialize() # not required, is implicit
707
708 return distros_added
709
710 # ========================================================================
711
712 def get_proposed_name(self,dirname,kernel=None):
713
714 """
715 Given a directory name where we have a kernel/initrd pair, try to autoname
716 the distribution (and profile) object based on the contents of that path
717 """
718
719 if self.network_root is not None:
720 name = self.mirror_name + "-".join(self.path_tail(os.path.dirname(self.path),dirname).split("/"))
721 else:
722 # remove the part that says /var/www/cobbler/ks_mirror/name
723 name = "-".join(dirname.split("/")[5:])
724
725 if kernel is not None and kernel.find("PAE") != -1:
726 name = name + "-PAE"
727
728 # These are all Ubuntu's doing, the netboot images are buried pretty
729 # deep. ;-) -JC
730 name = name.replace("-netboot","")
731 name = name.replace("-ubuntu-installer","")
732 name = name.replace("-amd64","")
733 name = name.replace("-i386","")
734
735 # we know that some kernel paths should not be in the name
736
737 name = name.replace("-images","")
738 name = name.replace("-pxeboot","")
739 name = name.replace("-install","")
740 name = name.replace("-isolinux","")
741
742 # some paths above the media root may have extra path segments we want
743 # to clean up
744
745 name = name.replace("-os","")
746 name = name.replace("-tree","")
747 name = name.replace("var-www-cobbler-", "")
748 name = name.replace("ks_mirror-","")
749 name = name.replace("--","-")
750
751 # remove any architecture name related string, as real arch will be appended later
752
753 name = name.replace("chrp","ppc64")
754
755 for separator in [ '-' , '_' , '.' ] :
756 for arch in [ "i386" , "x86_64" , "ia64" , "ppc64", "ppc32", "ppc", "x86" , "s390x", "s390" , "386" , "amd" ]:
757 name = name.replace("%s%s" % ( separator , arch ),"")
758
759 return name
760
761 # ========================================================================
762
763 def get_proposed_arch(self,dirname):
764 """
765 Given an directory name, can we infer an architecture from a path segment?
766 """
767 if dirname.find("x86_64") != -1 or dirname.find("amd") != -1:
768 return "x86_64"
769 if dirname.find("ia64") != -1:
770 return "ia64"
771 if dirname.find("i386") != -1 or dirname.find("386") != -1 or dirname.find("x86") != -1:
772 return "i386"
773 if dirname.find("s390x") != -1:
774 return "s390x"
775 if dirname.find("s390") != -1:
776 return "s390"
777 if dirname.find("ppc64") != -1 or dirname.find("chrp") != -1:
778 return "ppc64"
779 if dirname.find("ppc32") != -1:
780 return "ppc"
781 if dirname.find("ppc") != -1:
782 return "ppc"
783 return None
784
785# ==============================================
786
787
788def guess_breed(kerneldir,path,cli_breed,logger):
789
790 """
791 This tries to guess the distro. Traverses from kernel dir to imported root checking
792 for distro signatures, which are the locations in media where the search for release
793 packages should start. When a debian/ubuntu pool is found, the upper directory should
794 be checked to get the real breed. If we are on a real media, the upper directory will
795 be at the same level, as a local '.' symlink
796 The lowercase names are required for fat32/vfat filesystems
797 """
798 signatures = [
799 [ 'pool' , "debian" ],
800 [ 'VMware/RPMS' , "vmware" ],
801 [ 'imagedd.bz2' , "vmware" ],
802 [ 'RedHat/RPMS' , "redhat" ],
803 [ 'RedHat/rpms' , "redhat" ],
804 [ 'RedHat/Base' , "redhat" ],
805 [ 'Fedora/RPMS' , "redhat" ],
806 [ 'Fedora/rpms' , "redhat" ],
807 [ 'CentOS/RPMS' , "redhat" ],
808 [ 'CentOS/rpms' , "redhat" ],
809 [ 'CentOS' , "redhat" ],
810 [ 'Packages' , "redhat" ],
811 [ 'Fedora' , "redhat" ],
812 [ 'Server' , "redhat" ],
813 [ 'Client' , "redhat" ],
814 [ 'SL' , "redhat" ],
815 [ 'isolinux.bin', None ],
816 ]
817 guess = None
818
819 while kerneldir != os.path.dirname(path) :
820 logger.info("scanning %s for distro signature" % kerneldir)
821 for (x, breedguess) in signatures:
822 d = os.path.join( kerneldir , x )
823 if os.path.exists( d ):
824 guess = breedguess
825 break
826 if guess:
827 break
828
829 kerneldir = os.path.dirname(kerneldir)
830 else:
831 if cli_breed:
832 logger.info("Warning: No distro signature for kernel at %s, using value from command line" % kerneldir)
833 return (cli_breed , kerneldir , None)
834 utils.die(logger, "No distro signature for kernel at %s" % kerneldir )
835
836 if guess == "debian" :
837 for suite in [ "debian" , "ubuntu" ] :
838 # NOTE : Although we break the loop after the first match,
839 # multiple debian derived distros can actually live at the same pool -- JP
840 d = os.path.join( kerneldir , suite )
841 if os.path.islink(d) and os.path.isdir(d):
842 if os.path.realpath(d) == os.path.realpath(kerneldir):
843 return (suite, kerneldir ,x)
844 if os.path.basename( kerneldir ) == suite :
845 return (suite , kerneldir , x)
846
847 return (guess, kerneldir , x)
848
849# ============================================================
850
851
852def import_factory(kerneldir,path,cli_breed,logger):
853 """
854 Given a directory containing a kernel, return an instance of an Importer
855 that can be used to complete the import.
856 """
857
858 breed , rootdir, pkgdir = guess_breed(kerneldir,path,cli_breed,logger)
859 # NOTE : The guess_breed code should be included in the factory, in order to make
860 # the real root directory available, so allowing kernels at different levels within
861 # the same tree (removing the isolinux rejection from distro_adder) -- JP
862
863 if isinstance(rootdir, list):
864 if rootdir[1]:
865 logger.info("found content (breed=%s) at %s" % (breed,os.path.join( rootdir[0] , rootdir[1])))
866 else:
867 logger.info("found content (breed=%s) at %s" % (breed,rootdir[0]))
868 else:
869 logger.info("found content (breed=%s) at %s" % (breed,rootdir))
870
871 if cli_breed:
872 if cli_breed != breed:
873 utils.die(logger, "Requested breed (%s); breed found is %s" % ( cli_breed , breed ) )
874 breed = cli_breed
875
876 if breed == "redhat":
877 return RedHatImporter(logger,rootdir,pkgdir)
878 if breed == "vmware":
879 return VMwareImporter(logger,rootdir,pkgdir)
880 # disabled for 2.0
881 #elif breed == "debian":
882 # return DebianImporter(logger,rootdir,pkgdir)
883 #elif breed == "ubuntu":
884 # return UbuntuImporter(logger,rootdir,pkgdir)
885 elif breed:
886 utils.die(logger, "Unsupported OS breed %s" % breed)
887
888
889class BaseImporter:
890 """
891 Base class for distribution specific importer code.
892 """
893
894 # FIXME : Rename learn_arch_from_tree into guess_arch and simplify.
895 # FIXME : Drop package extension check and make a single search for all names.
896 # FIXME: Next methods to be moved here: kickstart_finder TRY_LIST loop
897
898 # ===================================================================
899
900 def arch_walker(self,foo,dirname,fnames):
901 """
902 See docs on learn_arch_from_tree.
903
904 The TRY_LIST is used to speed up search, and should be dropped for default importer
905 Searched kernel names are kernel-header, linux-headers-, kernel-largesmp, kernel-hugemem
906
907 This method is useful to get the archs, but also to package type and a raw guess of the breed
908 """
909
910 # try to find a kernel header RPM and then look at it's arch.
911 for x in fnames:
912 if self.match_kernelarch_file(x):
913 for arch in [ "i386" , "x86_64" , "ia64" , "ppc64", "ppc", "s390", "s390x" ]:
914 if x.find(arch) != -1:
915 foo[arch] = 1
916 for arch in [ "i686" , "amd64" ]:
917 if x.find(arch) != -1:
918 foo[arch] = 1
919
920 # ===================================================================
921
922 def get_rootdir(self):
923 return self.rootdir
924
925 # ===================================================================
926
927 def get_pkgdir(self):
928 if not self.pkgdir:
929 return None
930 return os.path.join(self.get_rootdir(),self.pkgdir)
931
932 # ===================================================================
933
934 def set_install_tree(self, distro, url):
935 distro.ks_meta["tree"] = url
936
937 # ===================================================================
938
939 def learn_arch_from_tree(self):
940 """
941 If a distribution is imported from DVD, there is a good chance the path doesn't
942 contain the arch and we should add it back in so that it's part of the
943 meaningful name ... so this code helps figure out the arch name. This is important
944 for producing predictable distro names (and profile names) from differing import sources
945 """
946 result = {}
947 # FIXME : this is called only once, should not be a walk
948 if self.get_pkgdir():
949 os.path.walk(self.get_pkgdir(), self.arch_walker, result)
950 if result.pop("amd64",False):
951 result["x86_64"] = 1
952 if result.pop("i686",False):
953 result["i386"] = 1
954 return result.keys()
955
956 def get_datestamp(self):
957 """
958 Allows each breed to return its datetime stamp
959 """
960 return None
961 # ===================================================================
962
963 def __init__(self,logger,rootdir,pkgdir):
964 raise exceptions.NotImplementedError
965
966 # ===================================================================
967
968 def process_repos(self, main_importer, distro):
969 raise exceptions.NotImplementedError
970
971# ===================================================================
972# ===================================================================
973
974class RedHatImporter ( BaseImporter ) :
975
976 def __init__(self,logger,rootdir,pkgdir):
977 self.breed = "redhat"
978 self.ks = "/var/lib/cobbler/kickstarts/default.ks"
979 self.rootdir = rootdir
980 self.pkgdir = pkgdir
981 self.logger = logger
982
983 # ================================================================
984
985 def get_release_files(self):
986 data = glob.glob(os.path.join(self.get_pkgdir(), "*release-*"))
987 data2 = []
988 for x in data:
989 b = os.path.basename(x)
990 if b.find("fedora") != -1 or \
991 b.find("redhat") != -1 or \
992 b.find("centos") != -1:
993 data2.append(x)
994 return data2
995
996 # ================================================================
997
998 def match_kernelarch_file(self, filename):
999 """
1000 Is the given filename a kernel filename?
1001 """
1002
1003 if not filename.endswith("rpm") and not filename.endswith("deb"):
1004 return False
1005 for match in ["kernel-header", "kernel-source", "kernel-smp", "kernel-largesmp", "kernel-hugemem", "linux-headers-", "kernel-devel", "kernel-"]:
1006 if filename.find(match) != -1:
1007 return True
1008 return False
1009
1010 # ================================================================
1011
1012 def scan_pkg_filename(self, rpm):
1013 """
1014 Determine what the distro is based on the release package filename.
1015 """
1016
1017 rpm = os.path.basename(rpm)
1018
1019 # if it looks like a RHEL RPM we'll cheat.
1020 # it may be slightly wrong, but it will be close enough
1021 # for RHEL5 we can get it exactly.
1022
1023 for x in [ "4AS", "4ES", "4WS", "4common", "4Desktop" ]:
1024 if rpm.find(x) != -1:
1025 return ("redhat", 4, 0)
1026 for x in [ "3AS", "3ES", "3WS", "3Desktop" ]:
1027 if rpm.find(x) != -1:
1028 return ("redhat", 3, 0)
1029 for x in [ "2AS", "2ES", "2WS", "2Desktop" ]:
1030 if rpm.find(x) != -1:
1031 return ("redhat", 2, 0)
1032
1033 # now get the flavor:
1034 flavor = "redhat"
1035 if rpm.lower().find("fedora") != -1:
1036 flavor = "fedora"
1037 if rpm.lower().find("centos") != -1:
1038 flavor = "centos"
1039
1040 # get all the tokens and try to guess a version
1041 accum = []
1042 tokens = rpm.split(".")
1043 for t in tokens:
1044 tokens2 = t.split("-")
1045 for t2 in tokens2:
1046 try:
1047 float(t2)
1048 accum.append(t2)
1049 except:
1050 pass
1051
1052 major = float(accum[0])
1053 minor = float(accum[1])
1054 return (flavor, major, minor)
1055
1056 def get_datestamp(self):
1057 """
1058 Based on a RedHat tree find the creation timestamp
1059 """
1060 base = self.get_rootdir()
1061 if os.path.exists("%s/.discinfo" % base):
1062 discinfo = open("%s/.discinfo" % base, "r")
1063 datestamp = discinfo.read().split("\n")[0]
1064 discinfo.close()
1065 else:
1066 return 0
1067 return float(datestamp)
1068
1069 def set_variance(self, flavor, major, minor, arch):
1070
1071 """
1072 find the profile kickstart and set the distro breed/os-version based on what
1073 we can find out from the rpm filenames and then return the kickstart
1074 path to use.
1075 """
1076
1077 if flavor == "fedora":
1078
1079 # this may actually fail because the libvirt/virtinst database
1080 # is not always up to date. We keep a simplified copy of this
1081 # in codes.py. If it fails we set it to something generic
1082 # and don't worry about it.
1083
1084 try:
1085 os_version = "fedora%s" % int(major)
1086 except:
1087 os_version = "other"
1088
1089 if flavor == "redhat" or flavor == "centos":
1090
1091 if major <= 2:
1092 # rhel2.1 is the only rhel2
1093 os_version = "rhel2.1"
1094 else:
1095 try:
1096 # must use libvirt version
1097 os_version = "rhel%s" % (int(major))
1098 except:
1099 os_version = "other"
1100
1101 kickbase = "/var/lib/cobbler/kickstarts"
1102 # Look for ARCH/OS_VERSION.MINOR kickstart first
1103 # ARCH/OS_VERSION next
1104 # OS_VERSION next
1105 # OS_VERSION.MINOR next
1106 # ARCH/default.ks next
1107 # FLAVOR.ks next
1108 kickstarts = [
1109 "%s/%s/%s.%i.ks" % (kickbase,arch,os_version,int(minor)),
1110 "%s/%s/%s.ks" % (kickbase,arch,os_version),
1111 "%s/%s.%i.ks" % (kickbase,os_version,int(minor)),
1112 "%s/%s.ks" % (kickbase,os_version),
1113 "%s/%s/default.ks" % (kickbase,arch),
1114 "%s/%s.ks" % (kickbase,flavor),
1115 ]
1116 for kickstart in kickstarts:
1117 if os.path.exists(kickstart):
1118 return os_version, kickstart
1119
1120 major = int(major)
1121
1122 if flavor == "fedora":
1123 if major >= 8:
1124 return os_version , "/var/lib/cobbler/kickstarts/sample_end.ks"
1125 if major >= 6:
1126 return os_version , "/var/lib/cobbler/kickstarts/sample.ks"
1127
1128 if flavor == "redhat" or flavor == "centos":
1129 if major >= 5:
1130 return os_version , "/var/lib/cobbler/kickstarts/sample.ks"
1131
1132 return os_version , "/var/lib/cobbler/kickstarts/legacy.ks"
1133
1134 self.logger.warning("could not use distro specifics, using rhel 4 compatible kickstart")
1135 return None , "/var/lib/cobbler/kickstarts/legacy.ks"
1136
1137
1138class VMwareImporter (BaseImporter):
1139 """
1140 VMware specific importer code.
1141 """
1142
1143 def __init__(self,logger,rootdir,pkgdir):
1144 self.breed = "vmware"
1145 self.ks = "/var/lib/cobbler/kickstarts/default.ks"
1146 self.rootdir = rootdir
1147 self.pkgdir = pkgdir
1148 self.logger = logger
1149
1150 def learn_arch_from_tree(self):
1151 """
1152 Attempt to figure out the arch from packages in the install tree.
1153 ESX 4 and up is 64bit.
1154 """
1155 result = ["x86_64"]
1156 return result
1157
1158 def get_release_files(self):
1159 """
1160 Find distro release packages.
1161 """
1162 data = glob.glob(os.path.join(self.get_pkgdir(), "*release-*"))
1163 data2 = []
1164 for x in data:
1165 b = os.path.basename(x)
1166 if b.find("vmware") != -1:
1167 data2.append(x)
1168 if len(data2) == 0:
1169 # ESXi maybe?
1170 return glob.glob(os.path.join(self.get_rootdir(), "imagedd.bz2*"))
1171 return data2
1172
1173 def scan_pkg_filename(self, rpm):
1174 """
1175 Determine what the distro is based on the release package filename.
1176 """
1177 rpm = os.path.basename(rpm)
1178
1179 if rpm.lower().find("-esx-") != -1:
1180 flavor = "esx"
1181 elif rpm.lower() == "imagedd.bz2":
1182 flavor = "esxi"
1183
1184 match = re.search(r'^([\-a-zA-Z0-9]+)-([\.0-9]+)-([\.0-9]+)\.', rpm)
1185 if match:
1186 (name, version, release) = [match.group(1), match.group(2), match.group(3)]
1187 major = version.split('.')[0]
1188 minor = release.split('.')[0]
1189 else:
1190 # FIXME: better major/minor detection for esxi
1191 # or if the match falls through for some reason
1192 major = 4
1193 minor = 0
1194
1195 return (flavor, major, minor)
1196
1197 def set_variance(self, flavor, major, minor, arch):
1198 """
1199 Set distro specific versioning.
1200 """
1201 os_version = "%s%s" % (flavor, major)
1202 return os_version , "/var/lib/cobbler/kickstarts/default.ks"
1203
1204
1205 def get_datestamp(self):
1206 """
1207 Based on a VMWare tree find the creation timestamp
1208 """
1209 pass
1210
1211#class DebianImporter ( BaseImporter ) :
1212#
1213# def __init__(self,logger,rootdir,pkgdir):
1214# self.breed = "debian"
1215# self.ks = "/var/lib/cobbler/kickstarts/sample.seed"
1216# self.rootdir = rootdir
1217# self.pkgdir = pkgdir
1218# self.logger = logger
1219#
1220# def get_release_files(self):
1221# if not self.get_pkgdir():
1222# return []
1223# # search for base-files or base-installer ?
1224# return glob.glob(os.path.join(self.get_pkgdir(), "main/b/base-files" , "base-files_*"))
1225#
1226# def match_kernelarch_file(self, filename):
1227# if not filename.endswith("deb"):
1228# return False
1229# if filename.startswith("linux-headers-"):
1230# return True
1231# return False
1232#
1233# def scan_pkg_filename(self, deb):
1234#
1235# deb = os.path.basename(deb)
1236# self.logger.info("processing deb : %s" % deb)
1237#
1238# # get all the tokens and try to guess a version
1239# accum = []
1240# tokens = deb.split("_")
1241# tokens2 = tokens[1].split(".")
1242# for t2 in tokens2:
1243# try:
1244# val = int(t2)
1245# accum.append(val)
1246# except:
1247# pass
1248# # Safeguard for non-guessable versions
1249# if not accum:
1250# return None
1251# accum.append(0)
1252#
1253# return (None, accum[0], accum[1])
1254#
1255# def set_variance(self, flavor, major, minor, arch):
1256#
1257# dist_names = { '4.0' : "etch" , '5.0' : "lenny" }
1258# dist_vers = "%s.%s" % ( major , minor )
1259# os_version = dist_names[dist_vers]
1260#
1261# return os_version , "/var/lib/cobbler/kickstarts/sample.seed"
1262#
1263# def set_install_tree(self, distro, url):
1264# idx = url.find("://")
1265# url = url[idx+3:]
1266#
1267# idx = url.find("/")
1268# distro.ks_meta["hostname"] = url[:idx]
1269# distro.ks_meta["directory"] = url[idx:]
1270# if not distro.os_version :
1271# utils.die(self.logger, "OS version is required for debian distros")
1272# distro.ks_meta["suite"] = distro.os_version
1273#
1274# def process_repos(self, main_importer, distro):
1275#
1276# # Create a disabled repository for the new distro, and the security updates
1277# #
1278# # NOTE : We cannot use ks_meta nor os_version because they get fixed at a later stage
1279#
1280# repo = item_repo.Repo(main_importer.config)
1281# repo.set_breed( "apt" )
1282# repo.set_arch( distro.arch )
1283# repo.set_keep_updated( False )
1284# repo.yumopts["--ignore-release-gpg"] = None
1285# repo.yumopts["--verbose"] = None
1286# repo.set_name( distro.name )
1287# repo.set_os_version( distro.os_version )
1288# # NOTE : The location of the mirror should come from timezone
1289# repo.set_mirror( "http://ftp.%s.debian.org/debian/dists/%s" % ( 'us' , '@@suite@@' ) )
1290#
1291# security_repo = item_repo.Repo(main_importer.config)
1292# security_repo.set_breed( "apt" )
1293# security_repo.set_arch( distro.arch )
1294# security_repo.set_keep_updated( False )
1295# security_repo.yumopts["--ignore-release-gpg"] = None
1296# security_repo.yumopts["--verbose"] = None
1297# security_repo.set_name( distro.name + "-security" )
1298# security_repo.set_os_version( distro.os_version )
1299# # There are no official mirrors for security updates
1300# security_repo.set_mirror( "http://security.debian.org/debian-security/dists/%s/updates" % '@@suite@@' )
1301#
1302# self.logger.info("Added repos for %s" % distro.name)
1303# repos = main_importer.config.repos()
1304# repos.add(repo,save=True)
1305# repos.add(security_repo,save=True)
1306
1307
1308#class UbuntuImporter ( DebianImporter ) :
1309#
1310# def __init__(self,rootdir,pkgdir):
1311# DebianImporter.__init__(self,rootdir,pkgdir)
1312# self.breed = "ubuntu"
1313#
1314# def get_release_files(self):
1315# if not self.get_pkgdir():
1316# return []
1317# return glob.glob(os.path.join(self.get_pkgdir(), "main/u/ubuntu-docs" , "ubuntu-docs_*"))
1318#
1319# def set_variance(self, flavor, major, minor, arch):
1320#
1321# # Release names taken from wikipedia
1322# dist_names = { '6.4':"dapper", '8.4':"hardy", '8.10':"intrepid", '9.4':"jaunty" }
1323# dist_vers = "%s.%s" % ( major , minor )
1324# if not dist_names.has_key( dist_vers ):
1325# dist_names['4ubuntu2.0'] = "IntrepidIbex"
1326# os_version = dist_names[dist_vers]
1327#
1328# return os_version , "/var/lib/cobbler/kickstarts/sample.seed"
1329#
1330# def process_repos(self, main_importer, distro):
1331#
1332# pass
01333
=== added file 'cobbler/action_litesync.py'
--- cobbler/action_litesync.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_litesync.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,167 @@
1"""
2Running small pieces of cobbler sync when certain actions are taken,
3such that we don't need a time consuming sync when adding new
4systems if nothing has changed for systems that have already
5been created.
6
7Copyright 2006-2009, Red Hat, Inc
8Michael DeHaan <mdehaan@redhat.com>
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2302110-1301 USA
24"""
25
26import os
27import os.path
28
29import utils
30import traceback
31import clogger
32import module_loader
33
34class BootLiteSync:
35 """
36 Handles conversion of internal state to the tftpboot tree layout
37 """
38
39 def __init__(self,config,verbose=False,logger=None):
40 """
41 Constructor
42 """
43 self.verbose = verbose
44 self.config = config
45 self.distros = config.distros()
46 self.profiles = config.profiles()
47 self.systems = config.systems()
48 self.images = config.images()
49 self.settings = config.settings()
50 self.repos = config.repos()
51 if logger is None:
52 logger = clogger.Logger()
53 self.logger = logger
54 self.tftpd = module_loader.get_module_from_file(
55 "tftpd","module","in_tftpd"
56 ).get_manager(config,logger)
57 self.sync = config.api.get_sync(verbose,logger=self.logger)
58 self.sync.make_tftpboot()
59
60 def add_single_distro(self, name):
61 # get the distro record
62 distro = self.distros.find(name=name)
63 if distro is None:
64 return
65 # copy image files to images/$name in webdir & tftpboot:
66 self.sync.pxegen.copy_single_distro_files(distro,
67 self.settings.webdir,True)
68 self.tftpd.add_single_distro(distro)
69
70 # generate any templates listed in the distro
71 self.sync.pxegen.write_templates(distro)
72 # cascade sync
73 kids = distro.get_children()
74 for k in kids:
75 self.add_single_profile(k.name, rebuild_menu=False)
76 self.sync.pxegen.make_pxe_menu()
77
78
79 def add_single_image(self, name):
80 image = self.images.find(name=name)
81 self.sync.pxegen.copy_single_image_files(image)
82 kids = image.get_children()
83 for k in kids:
84 self.add_single_system(k.name)
85 self.sync.pxegen.make_pxe_menu()
86
87 def remove_single_distro(self, name):
88 bootloc = utils.tftpboot_location()
89 # delete contents of images/$name directory in webdir
90 utils.rmtree(os.path.join(self.settings.webdir, "images", name))
91 # delete contents of images/$name in tftpboot
92 utils.rmtree(os.path.join(bootloc, "images", name))
93 # delete potential symlink to tree in webdir/links
94 utils.rmfile(os.path.join(self.settings.webdir, "links", name))
95
96 def remove_single_image(self, name):
97 bootloc = utils.tftpboot_location()
98 utils.rmfile(os.path.join(bootloc, "images2", name))
99
100 def add_single_profile(self, name, rebuild_menu=True):
101 # get the profile object:
102 profile = self.profiles.find(name=name)
103 if profile is None:
104 # most likely a subprofile's kid has been
105 # removed already, though the object tree has
106 # not been reloaded ... and this is just noise.
107 return
108 # rebuild the yum configuration files for any attached repos
109 # generate any templates listed in the distro
110 self.sync.pxegen.write_templates(profile)
111 # cascade sync
112 kids = profile.get_children()
113 for k in kids:
114 if k.COLLECTION_TYPE == "profile":
115 self.add_single_profile(k.name, rebuild_menu=False)
116 else:
117 self.add_single_system(k.name)
118 if rebuild_menu:
119 self.sync.pxegen.make_pxe_menu()
120 return True
121
122 def remove_single_profile(self, name, rebuild_menu=True):
123 # delete profiles/$name file in webdir
124 utils.rmfile(os.path.join(self.settings.webdir, "profiles", name))
125 # delete contents on kickstarts/$name directory in webdir
126 utils.rmtree(os.path.join(self.settings.webdir, "kickstarts", name))
127 if rebuild_menu:
128 self.sync.pxegen.make_pxe_menu()
129
130 def update_system_netboot_status(self,name):
131 self.tftpd.update_netboot(name)
132
133 def add_single_system(self, name):
134 # get the system object:
135 system = self.systems.find(name=name)
136 if system is None:
137 return
138 # rebuild system_list file in webdir
139 if self.settings.manage_dhcp:
140 self.sync.dhcp.regen_ethers()
141 if self.settings.manage_dns:
142 self.sync.dns.regen_hosts()
143 # write the PXE files for the system
144 self.tftpd.add_single_system(system)
145
146 def remove_single_system(self, name):
147 bootloc = utils.tftpboot_location()
148 system_record = self.systems.find(name=name)
149 # delete contents of kickstarts_sys/$name in webdir
150 system_record = self.systems.find(name=name)
151
152 itanic = False
153 profile = self.profiles.find(name=system_record.profile)
154 if profile is not None:
155 distro = self.distros.find(name=profile.get_conceptual_parent().name)
156 if distro is not None and distro in [ "ia64", "IA64"]:
157 itanic = True
158
159 for (name,interface) in system_record.interfaces.iteritems():
160 filename = utils.get_config_filename(system_record,interface=name)
161
162 if not itanic:
163 utils.rmfile(os.path.join(bootloc, "pxelinux.cfg", filename))
164 utils.rmfile(os.path.join(bootloc, "grub", filename.upper()))
165 else:
166 utils.rmfile(os.path.join(bootloc, filename))
167
0168
=== added file 'cobbler/action_log.py'
--- cobbler/action_log.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_log.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,71 @@
1"""
2
3Copyright 2009, Red Hat, Inc
4Bill Peck <bpeck@redhat.com>
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1902110-1301 USA
20"""
21
22
23import os
24import os.path
25import sys
26import traceback
27import clogger
28
29import utils
30from cexceptions import *
31import glob
32
33class LogTool:
34 """
35 Helpers for dealing with System logs, consoles, anamon, etc..
36 """
37
38 def __init__(self,config,system,api,logger=None):
39 """
40 Log library constructor requires a cobbler system object.
41 """
42 self.system = system
43 self.config = config
44 self.settings = config.settings()
45 self.api = api
46 if logger is None:
47 logger = clogger.Logger()
48 self.logger = logger
49
50
51 def clear(self):
52 """
53 Clears the system logs
54 """
55
56 #FIXME /var/consoles should come from config.settings()
57 logs = ['/var/consoles/%s' % self.system.name]
58 anamon_dir = '/var/log/cobbler/anamon/%s' % self.system.name
59 if os.path.isdir(anamon_dir):
60 logs.extend(filter(os.path.isfile, glob.glob('%s/*' % anamon_dir)))
61 for log in logs:
62 try:
63 f = open(log, 'w')
64 f.truncate()
65 f.close()
66 except IOError, e:
67 self.logger.info("Failed to Truncate '%s':%s " % (log, e))
68 except OSError, e:
69 self.logger.info("Failed to Truncate '%s':%s " % (log, e))
70 return 0
71
072
=== added file 'cobbler/action_power.py'
--- cobbler/action_power.py 1970-01-01 00:00:00 +0000
+++ cobbler/action_power.py 2011-03-11 21:10:49 +0000
@@ -0,0 +1,150 @@
1"""
2Power management library. For cobbler objects with power management configured
3encapsulate the logic to run power management commands so that the admin does not
4have to use seperate tools and remember how each of the power management tools are
5set up. This makes power cycling a system for reinstallation much easier.
6
7See https://fedorahosted.org/cobbler/wiki/PowerManagement
8
9Copyright 2008-2009, Red Hat, Inc
10Michael DeHaan <mdehaan@redhat.com>
11
12This program is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2 of the License, or
15(at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2502110-1301 USA
26"""
27
28
29import os
30import os.path
31import traceback
32import time
33import re
34
35import utils
36import func_utils
37from cexceptions import *
38import templar
39import clogger
40
41class PowerTool:
42 """
43 Handles conversion of internal state to the tftpboot tree layout
44 """
45
46 def __init__(self,config,system,api,force_user=None,force_pass=None,logger=None):
47 """
48 Power library constructor requires a cobbler system object.
49 """
50 self.system = system
51 self.config = config
52 self.settings = config.settings()
53 self.api = api
54 self.logger = self.api.logger
55 self.force_user = force_user
56 self.force_pass = force_pass
57 if logger is None:
58 logger = clogger.Logger()
59 self.logger = logger
60
61 def power(self, desired_state):
62 """
63 state is either "on" or "off". Rebooting is implemented at the api.py
64 level.
65
66 The user and password need not be supplied. If not supplied they
67 will be taken from the environment, COBBLER_POWER_USER and COBBLER_POWER_PASS.
68 If provided, these will override any other data and be used instead. Users
69 interested in maximum security should take that route.
70 """
71
72 template = self.get_command_template()
73 template_file = open(template, "r")
74
75 meta = utils.blender(self.api, False, self.system)
76 meta["power_mode"] = desired_state
77
78 # allow command line overrides of the username/password
79 if self.force_user is not None:
80 meta["power_user"] = self.force_user
81 if self.force_pass is not None:
82 meta["power_pass"] = self.force_pass
83
84 tmp = templar.Templar(self.api._config)
85 cmd = tmp.render(template_file, meta, None, self.system)
86 template_file.close()
87
88 cmd = cmd.strip()
89
90 self.logger.info("cobbler power configuration is:")
91
92 self.logger.info(" type : %s" % self.system.power_type)
93 self.logger.info(" address: %s" % self.system.power_address)
94 self.logger.info(" user : %s" % self.system.power_user)
95 self.logger.info(" id : %s" % self.system.power_id)
96
97 # if no username/password data, check the environment
98
99 if meta.get("power_user","") == "":
100 meta["power_user"] = os.environ.get("COBBLER_POWER_USER","")
101 if meta.get("power_pass","") == "":
102 meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS","")
103
104 self.logger.info("- %s" % cmd)
105
106 # use shell so we can have mutliple power commands chained together
107 cmd = ['/bin/sh','-c', cmd]
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches