Merge lp:~andreserl/ubuntu/natty/cobbler/lp731620 into lp:ubuntu/natty/cobbler
- Natty (11.04)
- lp731620
- Merge into natty
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 |
Related bugs: |
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.
Commit message
Description of the change
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
1 | === added file '.bzrignore' | |||
2 | --- .bzrignore 1970-01-01 00:00:00 +0000 | |||
3 | +++ .bzrignore 2011-03-11 21:10:49 +0000 | |||
4 | @@ -0,0 +1,1 @@ | |||
5 | 1 | .pc | ||
6 | 0 | 2 | ||
7 | === renamed file '.bzrignore' => '.bzrignore.moved' | |||
8 | === added file 'AUTHORS' | |||
9 | --- AUTHORS 1970-01-01 00:00:00 +0000 | |||
10 | +++ AUTHORS 2011-03-11 21:10:49 +0000 | |||
11 | @@ -0,0 +1,95 @@ | |||
12 | 1 | Cobbler, Koan, and Cobbler-Web are written & maintained by: | ||
13 | 2 | |||
14 | 3 | Michael DeHaan <mdehaan@redhat.com> | ||
15 | 4 | |||
16 | 5 | Patches and other contributions from: | ||
17 | 6 | |||
18 | 7 | Partha Aji <paji@redhat.com> | ||
19 | 8 | Anton Arapov <aarapov@redhat.com> | ||
20 | 9 | Niels Basjes <cobbler@basjes.nl> | ||
21 | 10 | Tim Bielawa <timbielawa@gmail.com> | ||
22 | 11 | Joseph Boyer Jr. <jboyer@liquidnet.com> | ||
23 | 12 | Andrew Brown <ambrown@ncsu.edu> | ||
24 | 13 | David Brown <dmlb2000@gmail.com> | ||
25 | 14 | James Bowes <jbowes@redhat.com> | ||
26 | 15 | James Cammarata <jimi@sgnx.net> | ||
27 | 16 | Jasper Capel <jcapel@redhat.com> | ||
28 | 17 | C. Daniel Chase <dan@cdchase.com> | ||
29 | 18 | Gordon Child <gordon@cpanel.net> | ||
30 | 19 | Cristian Ciupitu <cristian.ciupitu@yahoo.com> | ||
31 | 20 | Carsten Clasohm <cclasohm@redhat.com> | ||
32 | 21 | Ian Ward Comfort <icomfort@rescomp.stanford.edu> | ||
33 | 22 | Rob Crittenden <rcritten@redhat.com> | ||
34 | 23 | Scott Dodson <sdodson@redhat.com> | ||
35 | 24 | Charles Duffy <Charles_Duffy@messageone.com> | ||
36 | 25 | Máirín Duffy <duffy@redhat.com> | ||
37 | 26 | John Eckersberg <jeckersb@redhat.com> | ||
38 | 27 | Lee Faus <lfaus@redhat.com> | ||
39 | 28 | Leonid Flaks <flaks@bnl.gov> | ||
40 | 29 | Eoghan Gaffney <eoghan@noroutetohost.org> | ||
41 | 30 | Dan Guernsey <danpg102@gmail.com> | ||
42 | 31 | Marcel Haerry <haerry+et@puzzle.ch> | ||
43 | 32 | Peter Halliday <phalliday@excelsiorsystems.net> | ||
44 | 33 | Niels Hasse <haase.niels@googlemail.com> | ||
45 | 34 | Dave Hatton <dave@davehatton.it> | ||
46 | 35 | Scott Henson <shenson@redhat.com> | ||
47 | 36 | Garrett Holmstrom <garett.holmstrom@gmail.com> | ||
48 | 37 | Stephan Hauiser <stephan@huiser.nl> | ||
49 | 38 | Tru Huynh <tru@pasteur.fr> | ||
50 | 39 | Matt Hyclak <hyclak@math.ohiou.edu> | ||
51 | 40 | Mihai Ibanescu <mihai.ibanescu@gmail.com> | ||
52 | 41 | Shuichi Ihara <ihara@sun.com> | ||
53 | 42 | Pablo Iranzo Gómez <pablo.iranzo@redhat.com> | ||
54 | 43 | Brian Kearney <bkearney@redhat.com> | ||
55 | 44 | Henry Kemp <henrykemp@gmail.com> | ||
56 | 45 | Ruben Kerkhof <ruben@rubenkerkhof.com> | ||
57 | 46 | Don Khan <khan_don@emc.com> | ||
58 | 47 | Dominic LoBue <git.20.dlobue@neverbox.com> | ||
59 | 48 | Gavin Romig-Koch <gavin@redhat.com> | ||
60 | 49 | James Laska <jlaska@redhat.com> | ||
61 | 50 | Vito Laurenza <vitolaurenza@gmail.com> | ||
62 | 51 | Adrian Likins <alikins@redhat.com> | ||
63 | 52 | David Lutterkort <dlutter@redhat.com> | ||
64 | 53 | Lester M. <needwork@gmail.com> | ||
65 | 54 | Bryan Mason <bjmason@redhat.com> | ||
66 | 55 | Mike McCune <mmccune@redhat.com> | ||
67 | 56 | Mark McLoughlin <markmc@redhat.com> | ||
68 | 57 | Jim Meyering <jim@meyering.net> | ||
69 | 58 | Jeroen van Meeuwen <kanarip@kanarip.com> | ||
70 | 59 | Sean Millichamp <sean@bruenor.org> | ||
71 | 60 | Perry Myers <pmyers@redhat.com> | ||
72 | 61 | Jack Neely <jjneely@ncsu.edu> | ||
73 | 62 | Javier Palacious <javiplx@gmail.com> | ||
74 | 63 | Bill Peck <bpeck@redhat.com> | ||
75 | 64 | Lassi Pölönen <lassi.polonen@helsinki.fi> | ||
76 | 65 | Jasper Poppe <jpoppe@ebay.com> | ||
77 | 66 | Dan Radez <dradez@redhat.com> | ||
78 | 67 | Ben Riggs <rigg0022@umn.edu> | ||
79 | 68 | Jeremy Rosengren <jeremy@rosengren.org> | ||
80 | 69 | Adam Rosenwald <thestrider@gmail.com> | ||
81 | 70 | Christophe Sahut <csahut@nogoa.org> | ||
82 | 71 | Satoru Satoh <ssato@redhat.com> | ||
83 | 72 | Jeff Schroeder <jeffschroeder@computer.org> | ||
84 | 73 | Scott Seago <sseago@redhat.com> | ||
85 | 74 | Justin Sherill <jsherril@redhat.com> | ||
86 | 75 | Anderson Silva <ansilva@redhat.com> | ||
87 | 76 | Joe Smith <yasumoto7@gmail.com> | ||
88 | 77 | Michael Stahnke <mastahnke@gmail.com> | ||
89 | 78 | Dylan Swift <dylan.swift@gmail.com> | ||
90 | 79 | Al Tobey <tobert@gmail.com> | ||
91 | 80 | Thomas Uhde <thomas.uhde@KabelDeutschland.de> | ||
92 | 81 | Ronald van den Blink <ronald@a61.nl> | ||
93 | 82 | Tim Verhoeven <tim.verhoeven.be@gmail.com> | ||
94 | 83 | John L. Villalovos <john@sodarock.com> | ||
95 | 84 | Peter Vreman <peter.vreman@acision.com> | ||
96 | 85 | Adam Wolf <adamwolf@feelslikeburning.com> | ||
97 | 86 | Simon Woolsgrove <simon@woolsgrove.com> | ||
98 | 87 | Todd Zullinger <tmz@pobox.com> | ||
99 | 88 | Kelsey Hightower <kelsey.hightower@gmail.com> | ||
100 | 89 | Chuck Short <chuck.short@canonical.com> | ||
101 | 90 | Jonathan Sabo <jonathan.sabo@gmail.com> | ||
102 | 91 | Douglas Kilpatrick <dkilpatrick@verisign.com> | ||
103 | 92 | |||
104 | 93 | [...send patches to get your name here...] | ||
105 | 94 | |||
106 | 95 | |||
107 | 0 | 96 | ||
108 | === renamed file 'AUTHORS' => 'AUTHORS.moved' | |||
109 | === added file 'CHANGELOG' | |||
110 | --- CHANGELOG 1970-01-01 00:00:00 +0000 | |||
111 | +++ CHANGELOG 2011-03-11 21:10:49 +0000 | |||
112 | @@ -0,0 +1,912 @@ | |||
113 | 1 | Cobbler CHANGELOG | ||
114 | 2 | - Nov 29 2010 | ||
115 | 3 | - (FEAT) --force-path to overwrite virt-path file location | ||
116 | 4 | |||
117 | 5 | - Apr 27 2010 - 2.0.4 | ||
118 | 6 | - (BUGF) fetch extra metadata from upstream repositories more safely | ||
119 | 7 | - (BUGF) allow the creation of subprofiles again | ||
120 | 8 | - (BUGF) don't warn needlessly when repo rpm_list is empty | ||
121 | 9 | - (BUGF) run createrepo on partial yum mirrors | ||
122 | 10 | - (BUGF) change default mode for new directories from 0777 to 0755 | ||
123 | 11 | - (BUGF) fix replication pruning to not prune systems when inappropriate | ||
124 | 12 | - (BUGF) always authorize the CLI | ||
125 | 13 | - (BUGF) fix passthru auth Trac#549 | ||
126 | 14 | - (BUGF) fix for spacewalk bug 529277 | ||
127 | 15 | - (BUGF) fix umask so files are not world writable | ||
128 | 16 | - (BUGF) fix default pxe template to support default system record | ||
129 | 17 | - (BUGF) redo the PXE menuif a profile is removed | ||
130 | 18 | - (BUGF) properly escape snippets | ||
131 | 19 | - (FEAT) Support Mercurial (hg) for scm tracking | ||
132 | 20 | |||
133 | 21 | - Feb 15 2010 - 2.0.3.1 | ||
134 | 22 | - (BUGF) Fix kernel command line parsing | ||
135 | 23 | |||
136 | 24 | - Feb 12 2010 - 2.0.3 | ||
137 | 25 | - (FEAT) API Test Framework | ||
138 | 26 | - (FEAT) Cobbler4j Eclipse bindings | ||
139 | 27 | - (BUGF) Trac544 Create noarch and src repos | ||
140 | 28 | - (BUGF) Snippet Cleanups | ||
141 | 29 | - (FEAT) Cleanup Kickstart Generation | ||
142 | 30 | - (FEAT) Ability to include remote kickstart content | ||
143 | 31 | - (FEAT) Koan ability for remote kickstart content | ||
144 | 32 | - (BUGF) Trac547 Profile Creation in WebUI | ||
145 | 33 | - (BUGF) Trac520 Sort HTML Dropdown Lists | ||
146 | 34 | - (BUGF) Allow koan to use http urls for kernel/initrd | ||
147 | 35 | - (FEAT) Cobbler4j now uses maven to build | ||
148 | 36 | - (FEAT) Allow multiple kernel options with the same name | ||
149 | 37 | - (BUGF) Various logging cleanups | ||
150 | 38 | - (BUGF) Exit with proper error codes | ||
151 | 39 | - (BUGF) Fix multiselect fields in the WUI | ||
152 | 40 | - (BUGF) Trac550 stop leaking FDs in subprocess_call | ||
153 | 41 | - (BUGF) Trac566 link distros on replicate | ||
154 | 42 | - (BUGF) Trac563 Replace dos line endings with unix line endings when saving ksdata | ||
155 | 43 | - (FEAT) Support RHEL6 kernel sizes | ||
156 | 44 | - (BUGF) Preserve hardlinks on replicate | ||
157 | 45 | - Full List 2b3a4f960b564691ca9a0470f677bd902f60b021..b99401d4dc6cf7f6c010eecf6c5d235316b59f73 | ||
158 | 46 | |||
159 | 47 | - Nov 23 2009 - 2.0.2 | ||
160 | 48 | - (FEAT) Added support for Cobbler4j | ||
161 | 49 | - (FEAT) Added method for enabling autostart on qemu domains | ||
162 | 50 | - (BUGF) web ui: move sessions directory to /var | ||
163 | 51 | - (BUGF) Update the vlanpattern regex to cover more common virtual interface formats | ||
164 | 52 | - (BUGF) cobbler check: fix BIND detection | ||
165 | 53 | - (BUGF) Fix error message creating profile without a distro | ||
166 | 54 | - (BUGF) use proper HTTP error codes | ||
167 | 55 | - (BUGF) Create more intuitive system for displaying actions under configuration items. | ||
168 | 56 | - (BUGF) Fixed hardlinking | ||
169 | 57 | - (BUGF) Creating subprofile in WebUI no longer fails on default_ownership | ||
170 | 58 | - (BUGF) No longer delete excluded files in reposync rsync | ||
171 | 59 | - (BUGF) Add fedora12 and fedora13 as valid 'redhat' versions | ||
172 | 60 | - (BUGF) Correct improper distro creation while importing i386 Fedora/RHEL. | ||
173 | 61 | - (BUGF) Better messaging for invalid object errors | ||
174 | 62 | - (BUGF) Added a legacy sync mechanism | ||
175 | 63 | - (BUGF) No longer bundle libraries on distros where they are already available | ||
176 | 64 | |||
177 | 65 | - Sep 18 2009 - 2.0.1 | ||
178 | 66 | - (BUGF) Fixes for image based CLI usage and object validation | ||
179 | 67 | - (BUGF) Fix koan check for images ... they don't need a kickstart | ||
180 | 68 | - (BUGF) Get NFS image mounting working again | ||
181 | 69 | - (BUGF) Show object name on cobbler-web edit pages | ||
182 | 70 | - (BUGF) Make memtest integration look in the right file locations | ||
183 | 71 | - (BUGF) Fix check for dhcpd installation | ||
184 | 72 | - (BUGF) Fix code to detect dhcpd config file installation | ||
185 | 73 | - (BUGF) Cleaned up generated comments in settings files | ||
186 | 74 | - (BUGF) Unhide per-system post-install kernel options | ||
187 | 75 | - (BUGF) Unhide owners fields | ||
188 | 76 | - (BUGF) Fix "cobbler profile/system dumpvars" command | ||
189 | 77 | - (BUGF) Remove acl_engine reference from authz_configfile | ||
190 | 78 | - (BUGF) Add "View Kickstart" link back on profile list page | ||
191 | 79 | - (FEAT) Very Experimental CouchDB serializer, off by default. Touch /etc/cobbler/use.couch | ||
192 | 80 | - (BUGF) Fix pagination for webapp | ||
193 | 81 | - (BUGF) Widen left column for webapp to better show controls | ||
194 | 82 | - (BUGF) Workaround older mod_python scoping bug with utils.uniquify | ||
195 | 83 | - (BUGF) Fix interface additions from web system edit page for new systems | ||
196 | 84 | - (BUGF) Make cobbler reposync --only=N sync only that repo | ||
197 | 85 | - (BUGF) Mark cobbler_web.conf config(noreplace) in the RPM specfile | ||
198 | 86 | - (BUGF) Have cobbler check look for more SELinux things to do | ||
199 | 87 | - (BUGF) Fix saving of "static" network field in webapp | ||
200 | 88 | - (BUGF) Deepcopy interfaces to prevent copying of interface data | ||
201 | 89 | |||
202 | 90 | - Sep 17 2009 - for 2.0 release | ||
203 | 91 | - Development release start | ||
204 | 92 | - (FEAT) add two new default flags to yum reposync (-m and -d) for grabbing comps automatically and also deleting duplicate RPMs | ||
205 | 93 | - (BUGF) validate gateway input against python-netaddr | ||
206 | 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. | ||
207 | 95 | - (FEAT) web app moves to Django | ||
208 | 96 | - (FEAT) koan: Support for virt-autoboot feature (Xen only at this point, needs fixing) | ||
209 | 97 | - (FEAT) koan: use private address range for random MACs | ||
210 | 98 | - (FEAT) yum createrepo flags are now tweakable in settings | ||
211 | 99 | - (FEAT) new snippet for RHN Hosted: keep RHN keys between reinstalls | ||
212 | 100 | - (FEAT) allow per_distro snippets in addition to per_profile/per_system | ||
213 | 101 | - (BUGF) don't add port number to http_server if it's 80. | ||
214 | 102 | - (FEAT) support F11 fence-agent paths | ||
215 | 103 | - (BUGF) koan autodetection now can gather MACs/IPs for bridged interfaces better | ||
216 | 104 | - (FEAT) F11 and RAID support for keep_ssh_host_keys | ||
217 | 105 | - (FEAT) keep_ssh_host_keys gets F11+RAID support | ||
218 | 106 | - (FEAT) per-task logging | ||
219 | 107 | - (BUGF) validateks checkes /every/ kickstart, as different variables may be present | ||
220 | 108 | - (FEAT) CLI now speaks XMLRPC (faster) | ||
221 | 109 | - (FEAT) task engine for webapp | ||
222 | 110 | - (FEAT) background APIs for all actions | ||
223 | 111 | - (FEAT) look at ksdevice when building buildiso CDs to add the proper network lines | ||
224 | 112 | - (BUGF) don't use RPM to check os_version, so RPM won't be called in rpm %post | ||
225 | 113 | - (BUGF) deprecated omapi/omshell features for manage_isc now removed | ||
226 | 114 | - (FEAT) removed configuration files for binary paths, will look for in PATH | ||
227 | 115 | - (FEAT) removed configuration settings indicating where some config files are | ||
228 | 116 | - (FEAT) yum priorities plugin setting for distro repos now tweakable in settings | ||
229 | 117 | - (BUGF) unfinished contrib. debian import/repo support disabled until it can be finished | ||
230 | 118 | - (FEAT) replicate is now greatly improved and smarter | ||
231 | 119 | - (BUGF) aclengine (unfinished feature) removed, (not the same as aclsetup) | ||
232 | 120 | |||
233 | 121 | - - 1.6.9 | ||
234 | 122 | - (FEAT/cobbler) cobbler can now pass the virtio26 os version to virtinst, so virtio drivers can be used for RHEL5 | ||
235 | 123 | .3 for instance | ||
236 | 124 | - (BUGF/cobbler) The URL to the WebUI documentation in the manpage was corrected | ||
237 | 125 | - (BUGF/cobbler) add the --nameserver option for static interfaces when defined (snippet fix) | ||
238 | 126 | |||
239 | 127 | - 1.6.7 | ||
240 | 128 | - (BUGF/koan) Workaround for a bug in ybin, use --verbose for happy return codes | ||
241 | 129 | - (BUGF/cobbler) patch to redhat_register for Satellite | ||
242 | 130 | |||
243 | 131 | 1.6.6 (for more accurate listing, see release16 branch) | ||
244 | 132 | - (BUGF) don't use -m option for drac unless power_id is set | ||
245 | 133 | - (BUGF) don't run createrepo on reposync'd repos, it is redundant | ||
246 | 134 | - (BUGF) fix error message when wrong virt ram value is applied | ||
247 | 135 | - (FEAT) koan now partially works in source code form on EL 2 | ||
248 | 136 | - (FEAT) discover repomd filenames (for F11 and later) | ||
249 | 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. | ||
250 | 138 | - (BUGF) fix typo in network config snippet | ||
251 | 139 | |||
252 | 140 | - ... - 1.6.5 | ||
253 | 141 | - (BUGF) don't use json on python x<=2.3 since we know it's simplejson x<2.0, which has unicode issues | ||
254 | 142 | - (FEAT) support F-11 imports | ||
255 | 143 | - (BUGF) don't add koan virtual interfaces for vlan tagged interfaces | ||
256 | 144 | - (BUGF) pair PAE and non-PAE content in imports better | ||
257 | 145 | - (BUGF) don't try to scp /etc/cobbler/*.ks on replicate, this is an old path | ||
258 | 146 | - (BUGF) set proper umask on .mtime files | ||
259 | 147 | - (BUGF) fix koan error with unspecified arch using --kexec | ||
260 | 148 | - (BUGF) don't use --onboot=on in network config for kickstart for RHEL 3. | ||
261 | 149 | - (FEAT) koan can be built on EL-2 | ||
262 | 150 | |||
263 | 151 | - Fri May 8 2009 - 1.6.4 | ||
264 | 152 | - (BUGF) empty nameserver search paths now don't screw up resolv.conf | ||
265 | 153 | - (BUGF) unicode fix for --template-files feature | ||
266 | 154 | - (BUGF) mod python input fix for repo/profile associations in webapp | ||
267 | 155 | - (BUGF) change "hostname" to "option hostname" in dhcp.template | ||
268 | 156 | - (BUGF) fixes for unicode problem with Cheetah, repos, and json | ||
269 | 157 | - (BUGF) unicode fix for --template-files feature | ||
270 | 158 | - (BUGF) another unicode fix | ||
271 | 159 | - (BUGF) bonding interface setup for RHEL4 now works | ||
272 | 160 | - (BUGF) generate DHCP info even if netboot is disabled | ||
273 | 161 | - (BUGF) Change to network_config snippet to ignore bond masters to prevent anaconda failures when MAC addresses are not specified | ||
274 | 162 | - (BUGF) fix to CLI rename deleting subobjects via cobblerd (important!) | ||
275 | 163 | - (BUGF) fix blender cache problem with using dnsnames instead of record names (ISC DHCP management) | ||
276 | 164 | - (BUGF) quote host name in stock ISC template | ||
277 | 165 | |||
278 | 166 | - XXX - 1.6.3 | ||
279 | 167 | - (BUGF) import with datestamp 0 when .discinfo is not found, do not crash | ||
280 | 168 | - (BUGF) various fixes to "cobbler report" when using non-standard formats | ||
281 | 169 | - (BUGF) rename with same name does not delete | ||
282 | 170 | - (BUGF) Fix for traceback when generating DHCP config and the bonding_master interface does not exist. | ||
283 | 171 | - (BUGF) remove trailing newline from tokens | ||
284 | 172 | - (BUGF) fix unicode handling of some fields under EL4 | ||
285 | 173 | - (BUGF) fix webui search error (fixed better on devel) | ||
286 | 174 | - (BUGF) fix duplicate power reference | ||
287 | 175 | - (BUGF) fix error message that makes it appear dnsmasq had a problem restarting, when it did not | ||
288 | 176 | - (BUGF) spec requires python-urlgrabber | ||
289 | 177 | - (BUGF) change settings default from 'ksdevice=eth0' to 'bootif' | ||
290 | 178 | - (BUGF) keep DHCP restart quiet | ||
291 | 179 | - (BUGF) better hostname setting with DHCP management on | ||
292 | 180 | - (BUGF) fix bug in repo breed auto-detection code | ||
293 | 181 | - (BUGF) close file descriptors by using subprocess, not os.system | ||
294 | 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. | ||
295 | 183 | |||
296 | 184 | - Mon Mar 30 2009 - 1.6.2 | ||
297 | 185 | - (BUGF) Fix for cache cleanup problem in cobblerd | ||
298 | 186 | |||
299 | 187 | - Fri Mar 27 2009 - 1.6.1 | ||
300 | 188 | - (FEAT) Improved anaconda monitoring code | ||
301 | 189 | - (FEAT) download comps.xml always (even if yum does not have the option) | ||
302 | 190 | - (FEAT) performance upgrades for cobblerd service to avoid reloads | ||
303 | 191 | - (FEAT) more code for s390 imports (WIP) | ||
304 | 192 | - (BUGF) import works better with rawhide | ||
305 | 193 | - (FEAT) snippet to preserve SSH host keys across reinstalls | ||
306 | 194 | - (FEAT) email trigger to notify when builds finish | ||
307 | 195 | - (FEAT) triggers now are written in Python, old system still exists. | ||
308 | 196 | - (FEAT) s390x zpxe support | ||
309 | 197 | - (BUGF) retry power 5 times before giving up | ||
310 | 198 | - (BUGF) fix for RHEL3 ppc imports | ||
311 | 199 | - (FEAT) use nameserver variable in network config in Anaconda when set | ||
312 | 200 | - (BUGF) sleep 5 seconds between power cycling systems | ||
313 | 201 | - (FEAT) support for /usr/bin/cobbler-register | ||
314 | 202 | - (FEAT) web UI search feature | ||
315 | 203 | - (FEAT) very simple "cobbler hardlink" command to optimize space in /var/www/cobbler | ||
316 | 204 | - (FEAT) new "change" trigger that runs on all adds/edits/removes/syncs | ||
317 | 205 | - (FEAT) an SCM trigger that knows about /var/lib/cobbler kickstarts, snippets, and config directories, and audits them for changes | ||
318 | 206 | - (BUGF) update ctime on object copies | ||
319 | 207 | - (BUGF) fix cobbler check code that makes sure default password is not in use | ||
320 | 208 | - (BUGF) remove duplicate text box for management classes from server edit page | ||
321 | 209 | - (BUGF) fix stderr output on Ctrl+C | ||
322 | 210 | - (BUGF) potential performance savings WRT duplicate python objects | ||
323 | 211 | - (BUGF) don't deserialize during sync, it makes it take twice as long | ||
324 | 212 | - (FEAT) Ubuntu support for import (added/improved) | ||
325 | 213 | - (BUGF) make DHCP managemnet work with bonding | ||
326 | 214 | - (BUGF) teach serializer_catalog to fly with JSON | ||
327 | 215 | - (BUGF) don't use yumdownloader when rpm_list is [] | ||
328 | 216 | - (BUGF) fix default kickstart location | ||
329 | 217 | - (BUGF) properly "flatten" environment values for webapp | ||
330 | 218 | - (BUGF) fix for MSIE rendering in web app | ||
331 | 219 | - (BUGF) stop yumdownloader including system yum repos | ||
332 | 220 | - (DOCS) update webui project page link | ||
333 | 221 | - (BUGF) remove caching logic from remote.py | ||
334 | 222 | - (FEAT) added --exclude-dns option to buildiso | ||
335 | 223 | - (BUGF) fix string comparisons to tolerate unicode | ||
336 | 224 | - (BUGF) fix dealing with name servers and name servers search, esp in web app | ||
337 | 225 | |||
338 | 226 | - Tue Mar 3 2009 - 1.4.3 | ||
339 | 227 | - (BUGF) fix OMAPI support's (note: deprecated) usage of subprocess | ||
340 | 228 | - (BUGF) don't traceback on invalid cmd ("cobbler distro list --name=foo") | ||
341 | 229 | - (BUGF) fix import usage with --kickstart option (no more traceback) | ||
342 | 230 | - (BUGF) fix removal of images with child system objects | ||
343 | 231 | - (BUGF) make --rpmlist on repo use same parsing routes as the rest of cobbler | ||
344 | 232 | - (BUGF) default value for server override should be <<inherit>> not <inherit> | ||
345 | 233 | - (BUGF) ensure if virt bridge is set to "" it will apply the value from settings | ||
346 | 234 | - (BUGF) cobbler check should say path to config file is /etc/cobbler, not /var/lib | ||
347 | 235 | - (FEAT) enable cobblerweb username/pass logins when authing with spacewalk | ||
348 | 236 | - (BUGF) allow --kopts to take parameters that are shell quoted. | ||
349 | 237 | - (BUGF) allow kernel options to start with '-' | ||
350 | 238 | - (BUGF) Use shlex for parsing --kopts to allow a wider variety of kernel options | ||
351 | 239 | - (BUGF) prevent potential traceback when --template-file data isn't a hash | ||
352 | 240 | - (BUGF) anaconda doesn't honor nameserver always, set manually | ||
353 | 241 | - (BUGF) various post install network snippet fixes | ||
354 | 242 | - (BUGF) fix OMAPI support's (note: deprecated) usage of subprocess | ||
355 | 243 | - (SPEC) fix build for rawhide now that yaboot is included | ||
356 | 244 | - (BUGF) allow src and noarch arches for repo objects | ||
357 | 245 | - (BUGF) move to PyYAML for YAML implementation since it is better maintained | ||
358 | 246 | - (BUGF) fixed web-interface editing of ownership | ||
359 | 247 | - (BUGF) fixed web-interface editing of management classes | ||
360 | 248 | - (BUGF) don't run full sync in import, sync makes the install system unavailable for very short periods of time | ||
361 | 249 | - (FEAT) XMLRPC functions for searching objects, just like the Python API has | ||
362 | 250 | - (BUGF) make "find repo" CLI command search repos, not systems | ||
363 | 251 | |||
364 | 252 | - XXX - 1.4.2 | ||
365 | 253 | - (BUGF) fix WTI power templates | ||
366 | 254 | - (FEAT) add WTI power type | ||
367 | 255 | - (BUGF) remove Python 2.6/3000 warnings | ||
368 | 256 | - (BUGF) fix typo in network template (DNS enumeration) | ||
369 | 257 | - (BUGF) make buildiso work for systems that are using bonding | ||
370 | 258 | - (BUGF) blending fix for --template-files | ||
371 | 259 | - (BUGF) cobbler check ignores comments in TFTP config | ||
372 | 260 | - (BUGF) fix image type field editing in the webapp | ||
373 | 261 | - (BUGF) allow deletion of eth0 if other interfaces are present | ||
374 | 262 | - (BUGF) fix server-override setting in CLI for profile objects | ||
375 | 263 | - (BUGF) systems and profiles are now sorted for "cobbler buildiso" | ||
376 | 264 | - (BUGF) ensure that directories exist when installing a template file | ||
377 | 265 | - (BUGF) fix for typo in network config snippet | ||
378 | 266 | - (BUGF) fix for func integration script (should overwrite config, not append) | ||
379 | 267 | - (BUGF) append nameservers and gateway, if set, for buildiso | ||
380 | 268 | |||
381 | 269 | - Fri Jan 09 2009 - 1.4.1 | ||
382 | 270 | - (BUGF) Cobbler check looks for right httpd on SUSE | ||
383 | 271 | - (BUGF) post_install_network_config snippet had bash errors | ||
384 | 272 | - (BUGF) don't run restorecon programatically | ||
385 | 273 | - (FEAT) have cobbler check mention when semanage rules should be applied | ||
386 | 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. | ||
387 | 275 | - (BUGF) fix external kickstart URLs (not templated) and per-system overrides. | ||
388 | 276 | - (BUGF) fix 'cobbler check' code for SuSE services | ||
389 | 277 | - (FEAT) batch editing on the system page. | ||
390 | 278 | |||
391 | 279 | - Fri Dec 19 2008 - 1.4 | ||
392 | 280 | - (----) Stable release of 1.3 development branch | ||
393 | 281 | |||
394 | 282 | - Fri Dec 19 2008 - 1.3 | ||
395 | 283 | - (FEAT) ACLs to extend authz (see Wiki) | ||
396 | 284 | - (FEAT) puppet integration with --mgmt-classes and external nodes URL | ||
397 | 285 | - (FEAT) added puppet external nodes script, cobbler-ext-nodes | ||
398 | 286 | see https://fedorahosted.org/cobbler/wiki/UsingCobblerWithConfigManagementSystem | ||
399 | 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 | ||
400 | 288 | - (FEAT) added livecd based physical machine cloner script to "contrib" | ||
401 | 289 | - (FEAT) enable import for debian ISOs and mirrors (1 distro at a time for now) | ||
402 | 290 | - (FEAT) auto-create rescue profile objects | ||
403 | 291 | - (FEAT) included network_config snippet and added --static=0/1 to system objects | ||
404 | 292 | - (FEAT) cobbler report gains additional options for Wiki formatting, csv, and showing only certain fields | ||
405 | 293 | - (FEAT) changed default kernel options to include ksdevice=bootif (not ksdevice=eth0) and added ipappend 2 to PXE | ||
406 | 294 | - (FEAT) distro edits now no longer require a sync to rebuild the PXE menu | ||
407 | 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 | ||
408 | 296 | - (BUGF) add missing import of "_" in remote.py | ||
409 | 297 | - (FEAT) upgraded webui editing for multiple NICs | ||
410 | 298 | - (FEAT) "template_universe" variable created for snake's usage, variable contains all template variables and is also passed to the template. | ||
411 | 299 | - (FEAT) refactored import with better Debian/Ubuntu support | ||
412 | 300 | - (FEAT) Func integration snippets and new settings | ||
413 | 301 | - (FEAT) settings file and modules.conf now generated by setup.py using templates | ||
414 | 302 | - (FEAT) --template-files makes cobbler more of a full config management system! | ||
415 | 303 | - (FEAT) cobbler reposync now supports --tries=N and --no-fail | ||
416 | 304 | - (FEAT) duplicate hostname prevention, on by default | ||
417 | 305 | - (FEAT) make import work for Scientific Linux | ||
418 | 306 | - (FEAT) distro remove will remove mirrored content when it's safe to do so | ||
419 | 307 | - (FEAT) repo remove will remove mirrored repo content | ||
420 | 308 | - (FEAT) added snippet for better post-install network configuration | ||
421 | 309 | - (BUGF) duplicate repo supression to prevent errors in certain Andaconda's | ||
422 | 310 | - (FEAT) post_network_snippet/interfaces can set up VLANs | ||
423 | 311 | - (FEAT) call unittests with nose, which offers cleaner output, see tests/README | ||
424 | 312 | - (FEAT) update included elilo to 3.8 | ||
425 | 313 | - (BUGF) quote append line for elilo | ||
426 | 314 | - (BUGF) added ExcludeArch: ppc64 | ||
427 | 315 | - (FEAT) --environment parameter added to reposync | ||
428 | 316 | - (BUGF) have triggers ignore dotfiles so directories can be version controlled (and so on) | ||
429 | 317 | - (FEAT) init scripts and specfiles now install on SuSE | ||
430 | 318 | - (TEST) added remote tests, moved existing unit tests to api.py methods | ||
431 | 319 | - (FEAT) import can auto assign kickstarts based on distro (feature for beaker) | ||
432 | 320 | - (FEAT) import now saves the dot version of the OS in the comment field | ||
433 | 321 | - (FEAT) import now adds tree build time | ||
434 | 322 | - (FEAT) --comment field added to all objects | ||
435 | 323 | - (FEAT) keep creation and modification times with each object | ||
436 | 324 | - (FEAT) added ppc imports and arches to supplement s390x (and assoc koan chage) | ||
437 | 325 | - (FEAT) added number of interfaces required to each image | ||
438 | 326 | - ~~~ 1.3.2 | ||
439 | 327 | - (BUGF) fix for possible import of insecure modules by Cheetah in Cobbler web. | ||
440 | 328 | - (FEAT) new version function | ||
441 | 329 | - (FEAT) misc WUI organization | ||
442 | 330 | - (FEAT) allow auth against multiple LDAP servers | ||
443 | 331 | - (FEAT) replicate now copies image objects | ||
444 | 332 | - (BUGF) replicate now uses higher level API methods to avoid some profile sync errors when distros fail | ||
445 | 333 | - (FEAT) /etc/cobbler/pxe and /etc/cobbler/power are new config file paths | ||
446 | 334 | - (FEAT) /var/lib/cobbler/kickstarts is the new home for kicktart files | ||
447 | 335 | - (FEAT) webui sidebar reorg | ||
448 | 336 | - (FEAT) manage_dhcpd feature (ISC) now checks service status before restarting | ||
449 | 337 | - (BUGF) omapi for manage_dhcp feature (ISC) now defaults to off | ||
450 | 338 | - (FEAT) added module whitelist to settings file | ||
451 | 339 | - (BUGF) don't let the service handler connect to itself over mod_python/proxy, RH 5.3 does not like | ||
452 | 340 | - (FEAT) mtimes and ctimes and uids in the API | ||
453 | 341 | - (FEAT) new functions to get objects based on last modified time, for sync with other apps | ||
454 | 342 | - ~~~ 1.3.3 Test release | ||
455 | 343 | - (FEAT) Python 2.6 specfile changes | ||
456 | 344 | - ~~~ 1.3.X | ||
457 | 345 | - (FEAT) cobbler check output is always logged to /var/log/cobbler/check.log | ||
458 | 346 | - (FEAT) new redhat_register snippet and --redhat-management-key options! | ||
459 | 347 | - (BUGF) SELinux optimizations to symlink/hardlink/chcon/restorecon behavior | ||
460 | 348 | - (----) no SELinux support on EL 4 | ||
461 | 349 | - (FEAT) yum_post_install_mirror now on by default | ||
462 | 350 | |||
463 | 351 | - ??? - 1.2.9 | ||
464 | 352 | - (BUGF) do not allow unsafe Cheetah imports | ||
465 | 353 | |||
466 | 354 | - Wed Oct 15 2008 - 1.2.8 | ||
467 | 355 | - (BUGF) make cobbler read /etc/cobbler/settings.py (introduced in 1.2.6) | ||
468 | 356 | |||
469 | 357 | - Tue Oct 14 2008 - 1.2.7 | ||
470 | 358 | - (BUGF) go easier on restrictings when importing subprofiles to prevent load errors | ||
471 | 359 | - (FEAT) added debuginator script to scripts/ (not shipped with RPM) | ||
472 | 360 | |||
473 | 361 | - Fri Oct 10 2008 - 1.2.6 | ||
474 | 362 | - (BUGF) fix image vs system parentage problem affecting cobbler replicate | ||
475 | 363 | - (BUGF) fix restart-services trigger to not restart dns unneccessarily | ||
476 | 364 | - (BUGF) add missing variable newname to signature for remote copy_ functions | ||
477 | 365 | - (BUGF) fix for ownership ownership module when editing kickstarts | ||
478 | 366 | |||
479 | 367 | - Fri Sep 26 2008 - 1.2.5 | ||
480 | 368 | - (BUGF) expose --arch for "cobbler image add" | ||
481 | 369 | - (BUGF) unbreak dnsmasq DHCP management, similar to ISC bug | ||
482 | 370 | - (BUGF) fix --arch for cobbler distro add/edit | ||
483 | 371 | - (BUGF) fix merge error with remote.py's remove_profile function (fix webapp) | ||
484 | 372 | - (BUGF) make keep_updated and mirror_locally checkboxes in WebUI display correctly | ||
485 | 373 | |||
486 | 374 | - Mon Sep 08 2008 - 1.2.4 | ||
487 | 375 | - (BUGF) simple rebuild to remove cli_report.py, which is not in git | ||
488 | 376 | |||
489 | 377 | - Sun Sep 07 2008 - 1.2.3 | ||
490 | 378 | - (BUGF) fix to manage_isc.py code | ||
491 | 379 | |||
492 | 380 | - Fri Sep 05 2008 - 1.2.2 | ||
493 | 381 | - (BUGF) fix to where elilo location is loaded in manage_isc.py | ||
494 | 382 | - (BUGF) populate netboot_enabled in WebUI correctly | ||
495 | 383 | - (BUGF) make RPM own some unowned directories in "triggers" | ||
496 | 384 | - (BUGF) add named_conf setting to settings | ||
497 | 385 | |||
498 | 386 | - Tue Sep 02 2008 - 1.2.1 | ||
499 | 387 | - (BUGF) fix merge problem with 1.2 | ||
500 | 388 | |||
501 | 389 | - Fri Aug 29 2008 - 1.2.0 | ||
502 | 390 | - (FEAT) All development work from 1.X merged in | ||
503 | 391 | - (FEAT) when --netboot-enabled is toggled, rather than deleting the PXE config, create a local boot PXE config | ||
504 | 392 | - (BUGF) disable some s390 aspects of cobbler check until it is supported | ||
505 | 393 | - (FEAT) new --os-version, better validation for --breed, --breed/--os-version also for images | ||
506 | 394 | |||
507 | 395 | - ??? - 1.1.1 | ||
508 | 396 | - (FEAT) make template replacement use regex module | ||
509 | 397 | - (BUGF) remove bootloader check in settings as that code doesn't need it | ||
510 | 398 | - (BUGF) refinements to image handling | ||
511 | 399 | - (FEAT) getks command added to command line | ||
512 | 400 | - (BUGF) don't print traceback during certain SystemExits | ||
513 | 401 | - (BUGF) --help now works more intuitively on odd command line usage | ||
514 | 402 | - (BUGF) use pxesystem for systems, not pxeprofile | ||
515 | 403 | - (FEAT) make Cheetah formatting errors contain help text for users | ||
516 | 404 | - (FEAT) --kopts-post can configure post-install kernel options | ||
517 | 405 | - (BUGF) subtemplates are now errorCatcher Echo compatible | ||
518 | 406 | |||
519 | 407 | - ??? - 1.1.0 | ||
520 | 408 | - devel branch | ||
521 | 409 | - added cobbler aclsetup command for running cobbler as non-root | ||
522 | 410 | - added cobbler find command to do searches from the command line | ||
523 | 411 | - fix mkdir invocation | ||
524 | 412 | - improved cobbler replicate, it now can rsync needed files | ||
525 | 413 | - further templatize ISC dhcp config file (pay attention to /etc/cobbler/dhcp.template.rpmnew !) | ||
526 | 414 | - fix for NFS imported URLs during kickstart generation | ||
527 | 415 | - added yumreposync_flags to settings, default "-l" for use plugins | ||
528 | 416 | - added an extra mkdir for rhn's reposync, though I believe the -l cures it already | ||
529 | 417 | - allow mod python bits to work via non-80 http ports | ||
530 | 418 | - when mirroring repos, act as 686 not 386 to get all the kernel updates | ||
531 | 419 | - upgrades to cobbler buildiso | ||
532 | 420 | - added patch to allow --in-place editing of ksmeta/kopts | ||
533 | 421 | - added patch to allow multiple duplicate kernel options | ||
534 | 422 | - fix kickstart serving when the tree is on NFS | ||
535 | 423 | - s390x import, added support for s390x "pseudo-PXE" trees | ||
536 | 424 | - added support for tracking image objects and virtual ISO images | ||
537 | 425 | - support for multiple copies of the same kernel option in kopts | ||
538 | 426 | - add cobbler bash completion script | ||
539 | 427 | - fix bug with 255 kernel options line warning not firing soon enough | ||
540 | 428 | - add findks.cgi support back as http://server/cblr/svc/op/findks | ||
541 | 429 | - merge patch to surface status over API | ||
542 | 430 | - make yum repos served up for /etc/yum.repos.d fully dynamic (mod_python) | ||
543 | 431 | - cobbler find API calls and command line usage can now use fnmatch (wildcards) | ||
544 | 432 | - return code cleanup (0/1 now more predictable) | ||
545 | 433 | - added comments to /etc/cobbler/modules.conf | ||
546 | 434 | - during import non-xen kernels will default --virt-type to qemu | ||
547 | 435 | - when editing/adding profiles, auto-rebuild the PXE menu | ||
548 | 436 | - added http://cobbler.example.org/cblr/svc/op/list/what/systems (or profiles, etc) | ||
549 | 437 | - in the webui, only show compatible repos when editing a profile | ||
550 | 438 | - refresh cobblerd cache before adding objects | ||
551 | 439 | - system object IP's ok in CIDR notation (AAA.BBB.CCC.DDD/EE) for defining PXE behavior. | ||
552 | 440 | - split partition select template into two parts (old one still ships) | ||
553 | 441 | - cleanup some stock kickstarts so we always use $kickstart_start | ||
554 | 442 | - hook ctrl+c during serializer writes to prevent possible corruption of data in /var/lib/cobbler | ||
555 | 443 | - added 'serializer_catalog' as the new default serializer. It is backward compatible and much faster. | ||
556 | 444 | - removed serializer_shelve | ||
557 | 445 | - webui page lookups don't load the full object collection | ||
558 | 446 | - systems can also inherit from images | ||
559 | 447 | - changes to PXE images directly | ||
560 | 448 | - bootloaders is no longer a config file setting | ||
561 | 449 | - we can now look for syslinux in one of two places (/usr/lib, /usr/share) | ||
562 | 450 | - cobbler hardlinks a bit more when it can for /var/www image copies | ||
563 | 451 | - add Xen FV and VMware virt types to WebUI | ||
564 | 452 | |||
565 | 453 | - Thu Jul 17 2008 - 1.0.4 (tentative) | ||
566 | 454 | - Backported findks.cgi to mod_python, minor mod_python svc handler changes | ||
567 | 455 | |||
568 | 456 | - Wed Jun 03 2008 - 1.0.3 | ||
569 | 457 | - Fix typo in replicate code | ||
570 | 458 | - remove rhpl reference | ||
571 | 459 | - scrub references to manage_*_mode and rewrite the restart-services trigger | ||
572 | 460 | - add new settings to control whether the restart-trigger restarts things | ||
573 | 461 | - yum reposync should also pull i686 kernels, not just i386 | ||
574 | 462 | - make cobblerd close file handles | ||
575 | 463 | - fix kickstart serving when the tree is on NFS | ||
576 | 464 | - fix missing reposync createdir (also now in stable branch) | ||
577 | 465 | - add back missing remove_profile/remove_repo | ||
578 | 466 | - remove profile_change support | ||
579 | 467 | |||
580 | 468 | - Mon Jun 09 2008 - 1.0.2 | ||
581 | 469 | - Fix mkdir invocation | ||
582 | 470 | - Fix error message output from failed kickstart rendering | ||
583 | 471 | - manpage edits | ||
584 | 472 | - make buildiso work for SuSE | ||
585 | 473 | |||
586 | 474 | - Tue Jun 03 2008 - 1.0.1 | ||
587 | 475 | - Fix misformatted warning in "check" | ||
588 | 476 | - Do not have RPM own tftpboot, just generate files in TFTP dir as detected | ||
589 | 477 | - Default arches to 'i386' not 'x86' for consistency, esp. in import | ||
590 | 478 | - When querying kickstart templates, do not return directories | ||
591 | 479 | - Make triggers for add/delete work for renames and copies (same triggers) | ||
592 | 480 | - Do not cache snippets so they can be tweaked w/o starting the service | ||
593 | 481 | - Make manpage reference /etc/cobbler/settings, not /var/lib | ||
594 | 482 | - Added manage_forward_zones/manage_reverse_zones to included config file | ||
595 | 483 | - Fix python double-use-of-parameter error | ||
596 | 484 | |||
597 | 485 | - Mon May 12 2008 - 0.9.2 | ||
598 | 486 | - run createrepo with less preconditions during cobbler reposync | ||
599 | 487 | - doc upgrades and error handling for "cobbler replicate" | ||
600 | 488 | - improved error message that occurs when copying from nfs w/ rootsquash | ||
601 | 489 | - mac duplication checking improvements for CLI | ||
602 | 490 | - add warning to cobbler check if selinux is on and Apache boolean not set | ||
603 | 491 | - added warning to cobbler check if templates use the default password | ||
604 | 492 | - setting per-system kickstart template to "" or "delete" restores inheritance | ||
605 | 493 | - if repos in profiles no longer exist, remove noisy warning, move to "check" | ||
606 | 494 | - move warning about reposync to check also (check is more useful at runtime now) | ||
607 | 495 | - build pxe trees for systems even if interface0 is undefined | ||
608 | 496 | - add sync() back into XMLRPC API, missing in 0.9.1 | ||
609 | 497 | - added 'distro_name', 'profile_name', and 'system_name' to generated template vars | ||
610 | 498 | - it's now possible to undefine a --ksmeta or kopts symbol defined in a parent with "!foo" | ||
611 | 499 | - log errors while rendering kickstarts | ||
612 | 500 | - comments added to the config file, neat! | ||
613 | 501 | - settings file is now /etc/cobbler/settings | ||
614 | 502 | |||
615 | 503 | - Fri May 09 2008 - 0.9.1 | ||
616 | 504 | - patch to allow yumopts to override gpgcheck | ||
617 | 505 | - applied patch to send hostname from ISC | ||
618 | 506 | - added patch to allow --kopts/--ksmeta items to be cleared with --kopts=delete | ||
619 | 507 | - tftpboot location is now inferred from xinetd config (added for F9 compat) | ||
620 | 508 | - added authn_ldap and stub for authz_configfile | ||
621 | 509 | - authz_configfile allows filtering ldap/other users by config file | ||
622 | 510 | - WebUI now has checkbox on distro/profile for deleting child objects | ||
623 | 511 | - cli has different semantics between "add" and "edit" now for safety reasons | ||
624 | 512 | - cobbler wants to keep IPs/MACs unique now in configuration (can be disabled) | ||
625 | 513 | - added --clobber option to allow add to overwrite existing objects (for scripts) | ||
626 | 514 | - updated/tested kerberos support for those needing to auth against it | ||
627 | 515 | - update menu.c32 to 3.62 to allow for timeouts during menu (and future submenu) | ||
628 | 516 | - update PXE defaults to invoke menu.c32 automatically w/ timeout | ||
629 | 517 | - removed dependency on rhpl | ||
630 | 518 | - import can now take an --arch (and is recommended usage) | ||
631 | 519 | - now possible to override snippets on a profile/system specific basis | ||
632 | 520 | - provide a different default sample kickstart for imports of F8 and later | ||
633 | 521 | - support for kerberos authentication | ||
634 | 522 | - revamped pre/post install triggers system (triggered via cgi from kickstart wget) | ||
635 | 523 | - logrotate should not send emails to root when restarting services | ||
636 | 524 | - default core (but not repo add) repos to priority 1 (lowest) if using priorities plugin | ||
637 | 525 | - change default authentication to deny_all, xmlrpc_rw_enabled now on by default | ||
638 | 526 | - additional fix for mod_python select box submissions | ||
639 | 527 | - set repo arch if found in the URL and no --arch is specified | ||
640 | 528 | - CGI scripts have been moved under mod_python for speed/consolidation | ||
641 | 529 | - kickstart templates are now evaluated dynamically | ||
642 | 530 | - optional MAC registration is now built-in to requesting kickstarts | ||
643 | 531 | - legacy static file generation from /var/www/cobbler removed | ||
644 | 532 | - implement "cobbler ___ dumpvars --name=X" feature to show template vars | ||
645 | 533 | - validateks now works against all URLs as opposed to rendered local files | ||
646 | 534 | - now possible to create new kickstarts in webui, and delete unused ones | ||
647 | 535 | - support for OMAPI for avoid dhcp restarts | ||
648 | 536 | - support for managing BIND | ||
649 | 537 | - xen kernel (PV) distros do not get added to PXE menus as they won't boot there | ||
650 | 538 | - cobbler buildiso command to build non live ISOs | ||
651 | 539 | - cobbler replicate command | ||
652 | 540 | - added cobbler repo option --mirror-locally to reference external repos without mirroring | ||
653 | 541 | - all virt parameters on profiles can now be overriden on cobbler profile objects | ||
654 | 542 | - added some additional links for kickstart viewing/editing to the web page | ||
655 | 543 | |||
656 | 544 | - ??? - 0.8.3 | ||
657 | 545 | - Make createrepo get run for local cobbler reposync invocations as needed | ||
658 | 546 | - fix WebUI documentation URL | ||
659 | 547 | - fix bug in /etc/cobbler/modules.conf regarding pluggable authn/z | ||
660 | 548 | - fix default flags for yumdownloader | ||
661 | 549 | - fix for RHEL 4u6 DVD/tree import x86_64 arch detection | ||
662 | 550 | - fix for dnsmasq template file host config path | ||
663 | 551 | - fix dnsmasq template to point at the correct hosts file | ||
664 | 552 | - force all names to be alphanumeric | ||
665 | 553 | - all mod python pieces now happy with Unicode output | ||
666 | 554 | |||
667 | 555 | * Fri Feb 22 2008 - 0.8.2 | ||
668 | 556 | - fix to webui to allow repos to be edited there on profile page | ||
669 | 557 | - disable local socket XMLRPC as nothing is using it. | ||
670 | 558 | - fixed findks.cgi so it supports multiple NICs | ||
671 | 559 | - import now supports both --path and --mirror as aliases, as before | ||
672 | 560 | - added change_profile.cgi for changing profiles from CGI | ||
673 | 561 | - added register_mac.cgi | ||
674 | 562 | |||
675 | 563 | * Wed Feb 20 2008 - 0.8.1 | ||
676 | 564 | - bugfix in reposync code | ||
677 | 565 | - don't print tracebacks on SystemExit from optparse | ||
678 | 566 | - manpage tweaks | ||
679 | 567 | |||
680 | 568 | * Fri Feb 15 2008 - 0.8.0 (TBD) | ||
681 | 569 | - stable release of 0.7.* branch plus ... | ||
682 | 570 | - fixed potential user problem with source_repos in upgrade scenario | ||
683 | 571 | - additional higher level API functions for find, fixes for other higher level API functions | ||
684 | 572 | - better messaging when insufficient permissions on needed files | ||
685 | 573 | - update permissions on reposync fixes | ||
686 | 574 | |||
687 | 575 | * Thu Jan 31 2008 - 0.7.2 (0.8 rc) | ||
688 | 576 | - default_virt_file_size and default_virt_ram added to settings | ||
689 | 577 | - enforce permissions/selinux context after reposync | ||
690 | 578 | - better API for copying/renames, API consistancy cleanup | ||
691 | 579 | - support for renames that resolve dependencies, inclusion in CLI+webapp | ||
692 | 580 | - remove leading newline in rendered template files, which apparently breaks AutoYAST? | ||
693 | 581 | - recursive syncs automatically sync all subobjects when editing parent objects (default behavior) | ||
694 | 582 | - deletes can now be done recursively (optional --recursive on distro/profile remove) | ||
695 | 583 | - 'cobbler list' is now (re)sorted | ||
696 | 584 | |||
697 | 585 | * Wed Jan 09 2008 - 0.7.1 | ||
698 | 586 | - allow imports to force usage of a specific kickstart template with --kickstart | ||
699 | 587 | - added --yumopts parameter to repos (works just like --kopts/--ksmeta) | ||
700 | 588 | - minor doc fixes | ||
701 | 589 | - fix for name of F8 comps.xml file | ||
702 | 590 | - added option --rsync-flags to import command | ||
703 | 591 | - added http_port to settings to run Apache on non-80 | ||
704 | 592 | - rsync during createrepo now keeps filesystem permissions/groups | ||
705 | 593 | - ... | ||
706 | 594 | |||
707 | 595 | * Mon Dec 10 2007 - 0.7.0 | ||
708 | 596 | - Testing branch | ||
709 | 597 | - Fix bug related to <<inherit>> and kickstart args | ||
710 | 598 | - Make CLI functions modular and use optparse | ||
711 | 599 | - Quote wget args to avoid creating stray files on target system | ||
712 | 600 | - Support Xen FV as virt type (requires F8+) | ||
713 | 601 | - Implemented fully pluggable authn/authz system | ||
714 | 602 | - WebUI is now mod_python based | ||
715 | 603 | - Greatly enhanced logging (goes to /var/log/cobbler/cobbler.log) | ||
716 | 604 | - ... | ||
717 | 605 | |||
718 | 606 | * Wed Nov 14 2007 - 0.6.4 | ||
719 | 607 | - Changed permissions of auth.conf | ||
720 | 608 | - Fixes for working with rhn_yum_plugin | ||
721 | 609 | - still allow repo configuration for distro repos that have just 1 repo (like C5.1) | ||
722 | 610 | - disable CGI weblogging by default (backend logging TBA) | ||
723 | 611 | - fix WebUI handling of keep_updated (repo field) and netboot_enabled (system field) | ||
724 | 612 | - disable the blender_cache as it's running afoul of the sync code | ||
725 | 613 | - update htaccess file to only authenticate the webui, not nopxe.cgi and findks.cgi | ||
726 | 614 | |||
727 | 615 | * Wed Nov 07 2007 - 0.6.3 | ||
728 | 616 | - Be able to define and use Multiple NICs per system | ||
729 | 617 | - Add --virt-cpus to profile editing | ||
730 | 618 | - Fix bug where WUI (XMLRPC) auth wasn't supported on EL4 | ||
731 | 619 | - Add --virt-bridge to profile editing and NICs | ||
732 | 620 | - Added serializer_shelve (as option) for added performance/persistance over YAML, experimental in /etc/cobbler/modules.conf, see Wiki | ||
733 | 621 | - Backup state files and migrate state structures upon RPM upgrade | ||
734 | 622 | - Added some more redundant files (for unsupported distros) to the rsync.exclude file | ||
735 | 623 | - added pre-sync and post-sync triggers, service restarts are now handled by /var/lib/cobbler/triggers | ||
736 | 624 | - webui now uses htaccess (see manpage and Wiki for setup instructions) | ||
737 | 625 | - added pagination to the WUI to keep pages from growing overly long | ||
738 | 626 | - added --server-override parameter for help with multi-subnet configurations (also see Wiki) | ||
739 | 627 | - removed yum-utils as a hard requirement, cobbler check now looks for yum-utils | ||
740 | 628 | - fixed bug where cobbler would try to copy hardlinks to themselves during sync | ||
741 | 629 | - misc random bugfixing | ||
742 | 630 | |||
743 | 631 | * Fri Sep 28 2007 - 0.6.2 | ||
744 | 632 | - cobbler repo auto-add to discover yum repos automatically | ||
745 | 633 | - fix bug that allows empty mac addresses (None) in dhcpd.conf | ||
746 | 634 | - kickstarts automatically save kickstart file used to /root/cobbler.ks | ||
747 | 635 | - allow multiple (comma-seperated) values for --virt-size | ||
748 | 636 | - removed deprecated 'enchant' function (use SSH and koan instead) | ||
749 | 637 | - cleanup of a few unused settings | ||
750 | 638 | - allow for serialization modules to be selected in /etc/cobbler/modules.conf | ||
751 | 639 | - patch to allow for reposync of specific repos, even if not set to update | ||
752 | 640 | - added --dhcp-tag section for better DHCP customization (esp with multiple subnets) | ||
753 | 641 | - added Apache proxying around XMLRPC port for wider network access | ||
754 | 642 | - refactor XMLRPC API and establish a read-write API | ||
755 | 643 | - allow for configuring of read-write XMLRPC users in /etc/cobbler/auth.conf | ||
756 | 644 | - WebUI | ||
757 | 645 | - packaged /var/lib/cobbler/settings as a config file | ||
758 | 646 | - added BuildRequires to help build on other platforms | ||
759 | 647 | - relocate cgi-bin files to cgi-bin/cobbler for namespacing | ||
760 | 648 | - fix syslog logging for systems not in the cobbler DB. | ||
761 | 649 | - fix bug in which non-lowercase intermediate objects could be deleted | ||
762 | 650 | |||
763 | 651 | * Thu Aug 30 2007 - 0.6.1 | ||
764 | 652 | - re enable --resolve in yumdownloader (cobbler repo mgmt feature) | ||
765 | 653 | - fix get_distros_for_koan API function in cobblerd (not used by koan) | ||
766 | 654 | - allow find API to search by arbitrary fields | ||
767 | 655 | - status and logging now shows system names | ||
768 | 656 | - upgraded init scripts | ||
769 | 657 | - zeroconf/avahi publishing for cobblerd service | ||
770 | 658 | - logRequests = 0 for XMLRPC. Make it be quiet. | ||
771 | 659 | - ignore subdirectories of /var/lib/cobbler/snippets | ||
772 | 660 | - fixed bug in graph rendering that allowed for upward property propogation in some cases | ||
773 | 661 | - fixed bug that did not correctly evaluate repository settings of inherited sub-profiles/objects | ||
774 | 662 | - tweaked domU sample kickstart to include wget | ||
775 | 663 | - added some more unit tests | ||
776 | 664 | - fix typo down one error path in cobbler sync. | ||
777 | 665 | - fix reposync handling when using rsync protocol and directory paths do not contain arch | ||
778 | 666 | - allow basic usage of Cheetah variables in config files @@server@@, etc. | ||
779 | 667 | - fix auto-repo attachment for distros with split trees (i.e. RHEL5) | ||
780 | 668 | |||
781 | 669 | * Thu Aug 09 2007 - 0.6.0 | ||
782 | 670 | - bugfix in error path in "cobbler check" | ||
783 | 671 | - stable release for 0.5.x | ||
784 | 672 | |||
785 | 673 | * Thu Jul 26 2007 - 0.5.2 (RC) | ||
786 | 674 | - Have cobbler check ensure services are started | ||
787 | 675 | - Add cobbler validateks command to look for broken rendered kickstarts | ||
788 | 676 | - Added -v/--version | ||
789 | 677 | - Added SNIPPET::foo capability to pull /var/lib/cobbler/snippets/foo into templates (anywhere) | ||
790 | 678 | - Import can now take an --available-as=nfs://server:/mount/point to do cobbler import without mirroring | ||
791 | 679 | - Feature to enable "pxe_just_once" for boot loop prevention | ||
792 | 680 | |||
793 | 681 | * Fri Jul 20 2007 - 0.5.1 | ||
794 | 682 | - Added logging for cobblerd -- /var/log/cobbler/cobblerd.log | ||
795 | 683 | - Cobblerd now ignores XMLRPC IOError | ||
796 | 684 | - Added findks.cgi | ||
797 | 685 | - Misc bugfixing | ||
798 | 686 | - Added --virt-path, --virt-type | ||
799 | 687 | |||
800 | 688 | * Wed Jun 24 2007 - 0.5.0 | ||
801 | 689 | - Remove hardcode of /var/www/cobbler in cobblerd | ||
802 | 690 | - Improve various warning warning messages | ||
803 | 691 | - cobbler (objecttype) (objectname) now gives info about the object instead of just all objects | ||
804 | 692 | - Added --hostname to "cobbler system add", --ip-address (or --ip) is also a better alias for the misnamed --pxe-address | ||
805 | 693 | - Optionally use dnsmasq for DHCP (and DNS!) instead of ISC dhcpd. | ||
806 | 694 | - Add --mac and remove requirement for --name to be an ip, mac, or hostname. | ||
807 | 695 | - Manpage cleanup | ||
808 | 696 | - Patch to allow pre and post triggers | ||
809 | 697 | - Patch to allow --createrepo-flags and to cache on import, fix multiple calls to createrepo | ||
810 | 698 | - Various modifications to allow for profile inheritance | ||
811 | 699 | - All variables in object tree now available for use in templating, nicer blending algorithms | ||
812 | 700 | - Optional override of --kickstart in system object | ||
813 | 701 | |||
814 | 702 | * Thu Apr 26 2007 - 0.4.8 | ||
815 | 703 | - Make import friendlier for older distros | ||
816 | 704 | - Make import friendlier for newer createrepos that don't have --basedir | ||
817 | 705 | |||
818 | 706 | * Fri Apr 20 2007 - 0.4.7 | ||
819 | 707 | - Disable mod_python tracker piece for RHEL5 (replacement eventual). | ||
820 | 708 | - Kickstart tracking now understands Apache logs | ||
821 | 709 | - Added support for --rpm-list parameter to "repo add" for download of partial content from repositories | ||
822 | 710 | (ex: cobbler and koan from FC6extras, w/o games). | ||
823 | 711 | - More consistant naming on imports, regardless of data source. | ||
824 | 712 | - Teach cobbler to remove .olddata dirs, which can happen if createrepo crashes or is killed mid-process | ||
825 | 713 | - Default yum_core_repos_from_server to 0 | ||
826 | 714 | - Implemented triggers for add/delete commands | ||
827 | 715 | - BootAPI and Config object classes are now Borg patterned to prevent duplication of config info from the API. | ||
828 | 716 | - cobbler_syslogd -> cobblerd, now has XMLRPC component for koan >= 0.2.9 clients. Old clients still work. | ||
829 | 717 | - Make cobbler_import work for Centos 5 | ||
830 | 718 | - Removed requirements on what files that are parameters to --kernel and --initrd must be named. | ||
831 | 719 | - Added support for "rename", "copy", and "edit" commands -- before there just was "add" and "remove" | ||
832 | 720 | |||
833 | 721 | * Thu Apr 05 2007 - 0.4.6 | ||
834 | 722 | - Bind cobbler_syslogd to all addresses | ||
835 | 723 | - Store repos as list, not string | ||
836 | 724 | - Fix traceback in cobbler_sync with older configurations (pre-kickstart tracking) | ||
837 | 725 | - Make cobbler import feature better understand older RHEL and in-between builds of Fedora. | ||
838 | 726 | - Make cobbler repo add/reposync understand http://, ftp://, and some limited support for RHN. | ||
839 | 727 | - Add settings parameter to toggle core repo mirror behavior on/off. | ||
840 | 728 | - Manpage cleanup. | ||
841 | 729 | |||
842 | 730 | * Fri Mar 23 2007 - 0.4.5 | ||
843 | 731 | - Removed legacy --virt-name parameter, requires koan upgrade to 0.2.8 | ||
844 | 732 | |||
845 | 733 | * Fri Mar 23 2007 - 0.4.4 | ||
846 | 734 | - Generate PXE configuration files from templates in /etc/cobbler to be more customizable | ||
847 | 735 | - Fix bug with wrong kickstart metadata being used for import | ||
848 | 736 | - Fix bug with argument parsing for --repos | ||
849 | 737 | - Much cleaner distro/profile names with --import | ||
850 | 738 | - For import, the "tree" parameter is now attached to the distro, not the profile | ||
851 | 739 | - Add "links" directory in webdir for symlinking to full kickstart tree paths. | ||
852 | 740 | - Misc tweaks to shorten kernel parameter length | ||
853 | 741 | - Giving invalid arguments to "report" will show an error message | ||
854 | 742 | - Distros, Profiles, and System names are now case insensitive. | ||
855 | 743 | |||
856 | 744 | * Wed Feb 28 2007 - 0.4.3 | ||
857 | 745 | - Added netboot_enabled option for systems to control install loops in programmatic context. | ||
858 | 746 | - Disabling anchors in YAML serialization (which make files harder to edit) | ||
859 | 747 | - Fix bug in ksmeta argument processing, takes whitespace again, not commas | ||
860 | 748 | - Fix bug in old-style deserialization with str and int concatenation | ||
861 | 749 | |||
862 | 750 | * Mon Feb 19 2007 - 0.4.2 | ||
863 | 751 | - Fix bug in "cobbler system remove" | ||
864 | 752 | |||
865 | 753 | * Mon Feb 19 2007 - 0.4.1 | ||
866 | 754 | - Bundle menu.c32 for older distros | ||
867 | 755 | - Unbundle Cheetah as it's available at http://www.python.org/pyvault/centos-4-i386/ | ||
868 | 756 | |||
869 | 757 | * Mon Feb 19 2007 - 0.4.0 | ||
870 | 758 | - Added feature to minimize the need to run "cobbler sync" for add commands | ||
871 | 759 | Now only need to run sync when files change behind the scenes or when | ||
872 | 760 | manually editing YAML | ||
873 | 761 | - Moving back to Cheetah for templating (old kickstarts should escape $ with \$) | ||
874 | 762 | - PXE menus for the default profile. Type "menu" at the prompt to get a menu, or wait for local boot. | ||
875 | 763 | - Manpage cleanup and clarification | ||
876 | 764 | - Bugfix: cobbler will no longer create repo files on remotes when --local-filename is not used for "repo add" | ||
877 | 765 | |||
878 | 766 | * Mon Jan 28 2007 - 0.3.9 | ||
879 | 767 | - Make init scripts correspond with FC-E guidelines | ||
880 | 768 | |||
881 | 769 | * Thu Jan 24 2007 - 0.3.8 | ||
882 | 770 | - Fixed minor bug in logfile processing related to 0.3.7 | ||
883 | 771 | |||
884 | 772 | * Thu Jan 24 2007 - 0.3.7 | ||
885 | 773 | - Default/examples kickstarts are now fully automatic (added hd type/size detection). | ||
886 | 774 | - Kickstart tracking now includes remote syslog support, just run "cobbler sync" to enable. | ||
887 | 775 | - "cobbler status" command improved to include syslog info/times. | ||
888 | 776 | - Added fc6 kickstart file that was left out of the RPM earlier | ||
889 | 777 | - Added mini domU kickstart | ||
890 | 778 | - bugfix: don't install mod_python watcher on older Apache installs (like RHEL4) as it | ||
891 | 779 | somehow corrupts downloads on older copies. kickstart tracking by syslog still works | ||
892 | 780 | on those platforms. (This only applies to the cobbler server, not clients). | ||
893 | 781 | |||
894 | 782 | * Thu Dec 21 2006 - 0.3.6 | ||
895 | 783 | - locking feature now enabled | ||
896 | 784 | - "enchant" now supports provisioning virtual images remotely when using --is-virt=yes | ||
897 | 785 | - cobbler no longer restarts httpd if the config file already exists. | ||
898 | 786 | - "cobbler repo sync" is now an alias for "cobbler reposync" | ||
899 | 787 | - "cobbler list --something" can now be invoked as "cobbler something list" | ||
900 | 788 | - "cobbler list" just shows names of items now | ||
901 | 789 | - "cobbler report" is now used for showing full information output | ||
902 | 790 | - "list" (as well as report) are now sorted alphabetically | ||
903 | 791 | - basic kickstart tracking feature. requests on /var/www/cobbler get logged to /var/log/cobbler. | ||
904 | 792 | |||
905 | 793 | * Wed Dec 20 2006 - 0.3.5 | ||
906 | 794 | - Fixed bug in cobbler import related to orphan detection | ||
907 | 795 | - Made default rsync.exclude more strict (OO langpacks and KDE translation) | ||
908 | 796 | - Now runs createrepo during "cobbler import" to build more correct repodata | ||
909 | 797 | - Added additional repo mirroring commands: "cobbler repo add", etc | ||
910 | 798 | - Documentation on repo mirroring features. | ||
911 | 799 | - fix bug in rsync:// import code that saved distributions in the wrong path | ||
912 | 800 | - The --dryrun option on "cobbler sync" is now unsupported. | ||
913 | 801 | - Fixed bug in virt specific profile information not being used with koan | ||
914 | 802 | - import now takes --name in addition to --mirror-name to be more consistant | ||
915 | 803 | - rsync repo import shouldn't assume SSH unless no rsync:// in mirror URL | ||
916 | 804 | - strict host key checking disabled for "cobbler enchant" feature | ||
917 | 805 | |||
918 | 806 | * Mon Dec 05 2006 - 0.3.4 | ||
919 | 807 | - Don't rsync PPC content or ISO's on cobbler import | ||
920 | 808 | - Manpage cleanup | ||
921 | 809 | |||
922 | 810 | * Tue Nov 14 2006 - 0.3.3 | ||
923 | 811 | - During "cobbler sync" only PXE-related directories in /tftpboot | ||
924 | 812 | are deleted. This allows /tftpboot to be used for other | ||
925 | 813 | purposes. | ||
926 | 814 | |||
927 | 815 | * Thr Oct 25 2006 - 0.3.2 | ||
928 | 816 | - By default, boot and install in text mode | ||
929 | 817 | |||
930 | 818 | * Wed Oct 25 2006 - 0.3.1 | ||
931 | 819 | - The app now refers to "virt" in many places instead of "xen". | ||
932 | 820 | It's been coded such that files will migrate forward without | ||
933 | 821 | any major issues, and the newer version of koan can still hit | ||
934 | 822 | older releases (for now). The CLI still takes the --xen options | ||
935 | 823 | as well as the new --virt options, as they are aliased. The API | ||
936 | 824 | now exclusively just uses methods with "virt" in them, however. | ||
937 | 825 | - ... | ||
938 | 826 | |||
939 | 827 | * Tue Oct 24 2006 - 0.3.0 | ||
940 | 828 | - Reload httpd during sync | ||
941 | 829 | - New profiles without set kickstarts default to /etc/cobbler/default.ks | ||
942 | 830 | though this can be changed in /var/lib/cobbler/settings | ||
943 | 831 | - Better forward upgrades for /var/lib/cobbler/settings. New entries | ||
944 | 832 | get added when they are referenced. | ||
945 | 833 | |||
946 | 834 | * Tue Oct 24 2006 - 0.2.9 | ||
947 | 835 | - Bug fix, enchant now detects if koan_path is not set | ||
948 | 836 | - import now can do ssh rsync as well as just rsyncd | ||
949 | 837 | - Misc bug fixes related to not choking on bad info | ||
950 | 838 | - Fixed bug where --pxe-address wasn't surfaced | ||
951 | 839 | - Sync is a little less verbose | ||
952 | 840 | |||
953 | 841 | * Wed Oct 18 2006 - 0.2.8 | ||
954 | 842 | - Performance speedups to "import" command | ||
955 | 843 | - Bug fix, imported paths (again) convert slashes to underscores | ||
956 | 844 | |||
957 | 845 | * Tue Oct 17 2006 - 0.2.7 | ||
958 | 846 | - Removed pexpect to enhance support for other distros | ||
959 | 847 | - enchant syntax changed (see NEWS) | ||
960 | 848 | - now builds on RHEL4 | ||
961 | 849 | |||
962 | 850 | * Tue Oct 17 2006 - 0.2.6 | ||
963 | 851 | - Removing Cheetah and replacing w/ simpler templating system | ||
964 | 852 | - Don't delete localmirror on sync | ||
965 | 853 | |||
966 | 854 | * Mon Oct 16 2006 - 0.2.5 | ||
967 | 855 | - New "import" feature for rsync:// mirrors and filesystem directories | ||
968 | 856 | - Manpage clarification | ||
969 | 857 | - "enchant" is now a subcommand of "cobbler system" and takes less arguments. | ||
970 | 858 | - Several random bugfixes (mainly along error paths) | ||
971 | 859 | |||
972 | 860 | * Wed Oct 11 2006 - 0.2.4 | ||
973 | 861 | - Changes to make things work with python 2.3 (RHEL4, etc) | ||
974 | 862 | - Updated YAML code to ensure better backward compatibility | ||
975 | 863 | |||
976 | 864 | * Mon Oct 9 2006 - 0.2.3 | ||
977 | 865 | - Cobbler now creates a profile and system listing (YAML) in /var needed | ||
978 | 866 | by the next version of koan (which will be 0.2.1) | ||
979 | 867 | - bugfix: enchant should reboot the target box | ||
980 | 868 | - bugfix: enchant should fail if path to koan isn't configured | ||
981 | 869 | |||
982 | 870 | * Fri Oct 6 2006 - 0.2.2 | ||
983 | 871 | - bugfix: "--pxe-hostname" made available in CLI and renamed as "--pxe-address" | ||
984 | 872 | - workaround: elilo doesn't do MAC address pxe config files, use IP for ia64 | ||
985 | 873 | - bugfix: added next-server line for per-MAC dhcp configs | ||
986 | 874 | - bugfix: fixed manpage errors | ||
987 | 875 | |||
988 | 876 | * Thu Sep 28 2006 - 0.2.1 | ||
989 | 877 | - New ability to "enchant" remote systems (see NEWS) | ||
990 | 878 | - Misc. bugfixes | ||
991 | 879 | |||
992 | 880 | * Fri Sep 22 2006 - 0.2.0 | ||
993 | 881 | - New dhcp.d conf management features (see NEWS) | ||
994 | 882 | - IA64 support (see NEWS) | ||
995 | 883 | - dhcpd.conf MAC & hostname association features | ||
996 | 884 | |||
997 | 885 | * Thu Sep 21 2006 - 0.1.1-8 | ||
998 | 886 | - (RPM) Added doc files to doc section, removed INSTALLED_FILES | ||
999 | 887 | |||
1000 | 888 | * Wed Sep 20 2006 - 0.1.1-7 | ||
1001 | 889 | - Split HTTP and TFTP content to seperate directories | ||
1002 | 890 | to enable running in SELinux targetted/enforcing mode. | ||
1003 | 891 | - Make the Virt MAC address a property of a system, not a profile | ||
1004 | 892 | - Misc. fixes, mainly along the error path | ||
1005 | 893 | |||
1006 | 894 | * Fri Sep 15 2006 - 0.1.1-6 | ||
1007 | 895 | - Make koan own it's directory, add GPL "COPYING" file. | ||
1008 | 896 | |||
1009 | 897 | * Wed Aug 16 2006 - 0.1.1-5 | ||
1010 | 898 | - Spec file tweaks only for FC-Extras | ||
1011 | 899 | |||
1012 | 900 | * Thu Jul 20 2006 - 0.1.1-4 | ||
1013 | 901 | - Fixed python import paths in yaml code, which errantly assumed yaml was installed as a module. | ||
1014 | 902 | |||
1015 | 903 | * Wed Jul 12 2006 - 0.1.1-3 | ||
1016 | 904 | - Added templating support using Cheetah | ||
1017 | 905 | |||
1018 | 906 | * Thu Jul 9 2006 - 0.1.0-2 | ||
1019 | 907 | - Fedora-Extras rpm spec tweaks | ||
1020 | 908 | |||
1021 | 909 | * Tue Jun 28 2006 - 0.1.0-1 | ||
1022 | 910 | - rpm genesis | ||
1023 | 911 | |||
1024 | 912 | |||
1025 | 0 | 913 | ||
1026 | === renamed file 'CHANGELOG' => 'CHANGELOG.moved' | |||
1027 | === added file 'COPYING' | |||
1028 | --- COPYING 1970-01-01 00:00:00 +0000 | |||
1029 | +++ COPYING 2011-03-11 21:10:49 +0000 | |||
1030 | @@ -0,0 +1,340 @@ | |||
1031 | 1 | GNU GENERAL PUBLIC LICENSE | ||
1032 | 2 | Version 2, June 1991 | ||
1033 | 3 | |||
1034 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., | ||
1035 | 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
1036 | 6 | Everyone is permitted to copy and distribute verbatim copies | ||
1037 | 7 | of this license document, but changing it is not allowed. | ||
1038 | 8 | |||
1039 | 9 | Preamble | ||
1040 | 10 | |||
1041 | 11 | The licenses for most software are designed to take away your | ||
1042 | 12 | freedom to share and change it. By contrast, the GNU General Public | ||
1043 | 13 | License is intended to guarantee your freedom to share and change free | ||
1044 | 14 | software--to make sure the software is free for all its users. This | ||
1045 | 15 | General Public License applies to most of the Free Software | ||
1046 | 16 | Foundation's software and to any other program whose authors commit to | ||
1047 | 17 | using it. (Some other Free Software Foundation software is covered by | ||
1048 | 18 | the GNU Lesser General Public License instead.) You can apply it to | ||
1049 | 19 | your programs, too. | ||
1050 | 20 | |||
1051 | 21 | When we speak of free software, we are referring to freedom, not | ||
1052 | 22 | price. Our General Public Licenses are designed to make sure that you | ||
1053 | 23 | have the freedom to distribute copies of free software (and charge for | ||
1054 | 24 | this service if you wish), that you receive source code or can get it | ||
1055 | 25 | if you want it, that you can change the software or use pieces of it | ||
1056 | 26 | in new free programs; and that you know you can do these things. | ||
1057 | 27 | |||
1058 | 28 | To protect your rights, we need to make restrictions that forbid | ||
1059 | 29 | anyone to deny you these rights or to ask you to surrender the rights. | ||
1060 | 30 | These restrictions translate to certain responsibilities for you if you | ||
1061 | 31 | distribute copies of the software, or if you modify it. | ||
1062 | 32 | |||
1063 | 33 | For example, if you distribute copies of such a program, whether | ||
1064 | 34 | gratis or for a fee, you must give the recipients all the rights that | ||
1065 | 35 | you have. You must make sure that they, too, receive or can get the | ||
1066 | 36 | source code. And you must show them these terms so they know their | ||
1067 | 37 | rights. | ||
1068 | 38 | |||
1069 | 39 | We protect your rights with two steps: (1) copyright the software, and | ||
1070 | 40 | (2) offer you this license which gives you legal permission to copy, | ||
1071 | 41 | distribute and/or modify the software. | ||
1072 | 42 | |||
1073 | 43 | Also, for each author's protection and ours, we want to make certain | ||
1074 | 44 | that everyone understands that there is no warranty for this free | ||
1075 | 45 | software. If the software is modified by someone else and passed on, we | ||
1076 | 46 | want its recipients to know that what they have is not the original, so | ||
1077 | 47 | that any problems introduced by others will not reflect on the original | ||
1078 | 48 | authors' reputations. | ||
1079 | 49 | |||
1080 | 50 | Finally, any free program is threatened constantly by software | ||
1081 | 51 | patents. We wish to avoid the danger that redistributors of a free | ||
1082 | 52 | program will individually obtain patent licenses, in effect making the | ||
1083 | 53 | program proprietary. To prevent this, we have made it clear that any | ||
1084 | 54 | patent must be licensed for everyone's free use or not licensed at all. | ||
1085 | 55 | |||
1086 | 56 | The precise terms and conditions for copying, distribution and | ||
1087 | 57 | modification follow. | ||
1088 | 58 | |||
1089 | 59 | GNU GENERAL PUBLIC LICENSE | ||
1090 | 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
1091 | 61 | |||
1092 | 62 | 0. This License applies to any program or other work which contains | ||
1093 | 63 | a notice placed by the copyright holder saying it may be distributed | ||
1094 | 64 | under the terms of this General Public License. The "Program", below, | ||
1095 | 65 | refers to any such program or work, and a "work based on the Program" | ||
1096 | 66 | means either the Program or any derivative work under copyright law: | ||
1097 | 67 | that is to say, a work containing the Program or a portion of it, | ||
1098 | 68 | either verbatim or with modifications and/or translated into another | ||
1099 | 69 | language. (Hereinafter, translation is included without limitation in | ||
1100 | 70 | the term "modification".) Each licensee is addressed as "you". | ||
1101 | 71 | |||
1102 | 72 | Activities other than copying, distribution and modification are not | ||
1103 | 73 | covered by this License; they are outside its scope. The act of | ||
1104 | 74 | running the Program is not restricted, and the output from the Program | ||
1105 | 75 | is covered only if its contents constitute a work based on the | ||
1106 | 76 | Program (independent of having been made by running the Program). | ||
1107 | 77 | Whether that is true depends on what the Program does. | ||
1108 | 78 | |||
1109 | 79 | 1. You may copy and distribute verbatim copies of the Program's | ||
1110 | 80 | source code as you receive it, in any medium, provided that you | ||
1111 | 81 | conspicuously and appropriately publish on each copy an appropriate | ||
1112 | 82 | copyright notice and disclaimer of warranty; keep intact all the | ||
1113 | 83 | notices that refer to this License and to the absence of any warranty; | ||
1114 | 84 | and give any other recipients of the Program a copy of this License | ||
1115 | 85 | along with the Program. | ||
1116 | 86 | |||
1117 | 87 | You may charge a fee for the physical act of transferring a copy, and | ||
1118 | 88 | you may at your option offer warranty protection in exchange for a fee. | ||
1119 | 89 | |||
1120 | 90 | 2. You may modify your copy or copies of the Program or any portion | ||
1121 | 91 | of it, thus forming a work based on the Program, and copy and | ||
1122 | 92 | distribute such modifications or work under the terms of Section 1 | ||
1123 | 93 | above, provided that you also meet all of these conditions: | ||
1124 | 94 | |||
1125 | 95 | a) You must cause the modified files to carry prominent notices | ||
1126 | 96 | stating that you changed the files and the date of any change. | ||
1127 | 97 | |||
1128 | 98 | b) You must cause any work that you distribute or publish, that in | ||
1129 | 99 | whole or in part contains or is derived from the Program or any | ||
1130 | 100 | part thereof, to be licensed as a whole at no charge to all third | ||
1131 | 101 | parties under the terms of this License. | ||
1132 | 102 | |||
1133 | 103 | c) If the modified program normally reads commands interactively | ||
1134 | 104 | when run, you must cause it, when started running for such | ||
1135 | 105 | interactive use in the most ordinary way, to print or display an | ||
1136 | 106 | announcement including an appropriate copyright notice and a | ||
1137 | 107 | notice that there is no warranty (or else, saying that you provide | ||
1138 | 108 | a warranty) and that users may redistribute the program under | ||
1139 | 109 | these conditions, and telling the user how to view a copy of this | ||
1140 | 110 | License. (Exception: if the Program itself is interactive but | ||
1141 | 111 | does not normally print such an announcement, your work based on | ||
1142 | 112 | the Program is not required to print an announcement.) | ||
1143 | 113 | |||
1144 | 114 | These requirements apply to the modified work as a whole. If | ||
1145 | 115 | identifiable sections of that work are not derived from the Program, | ||
1146 | 116 | and can be reasonably considered independent and separate works in | ||
1147 | 117 | themselves, then this License, and its terms, do not apply to those | ||
1148 | 118 | sections when you distribute them as separate works. But when you | ||
1149 | 119 | distribute the same sections as part of a whole which is a work based | ||
1150 | 120 | on the Program, the distribution of the whole must be on the terms of | ||
1151 | 121 | this License, whose permissions for other licensees extend to the | ||
1152 | 122 | entire whole, and thus to each and every part regardless of who wrote it. | ||
1153 | 123 | |||
1154 | 124 | Thus, it is not the intent of this section to claim rights or contest | ||
1155 | 125 | your rights to work written entirely by you; rather, the intent is to | ||
1156 | 126 | exercise the right to control the distribution of derivative or | ||
1157 | 127 | collective works based on the Program. | ||
1158 | 128 | |||
1159 | 129 | In addition, mere aggregation of another work not based on the Program | ||
1160 | 130 | with the Program (or with a work based on the Program) on a volume of | ||
1161 | 131 | a storage or distribution medium does not bring the other work under | ||
1162 | 132 | the scope of this License. | ||
1163 | 133 | |||
1164 | 134 | 3. You may copy and distribute the Program (or a work based on it, | ||
1165 | 135 | under Section 2) in object code or executable form under the terms of | ||
1166 | 136 | Sections 1 and 2 above provided that you also do one of the following: | ||
1167 | 137 | |||
1168 | 138 | a) Accompany it with the complete corresponding machine-readable | ||
1169 | 139 | source code, which must be distributed under the terms of Sections | ||
1170 | 140 | 1 and 2 above on a medium customarily used for software interchange; or, | ||
1171 | 141 | |||
1172 | 142 | b) Accompany it with a written offer, valid for at least three | ||
1173 | 143 | years, to give any third party, for a charge no more than your | ||
1174 | 144 | cost of physically performing source distribution, a complete | ||
1175 | 145 | machine-readable copy of the corresponding source code, to be | ||
1176 | 146 | distributed under the terms of Sections 1 and 2 above on a medium | ||
1177 | 147 | customarily used for software interchange; or, | ||
1178 | 148 | |||
1179 | 149 | c) Accompany it with the information you received as to the offer | ||
1180 | 150 | to distribute corresponding source code. (This alternative is | ||
1181 | 151 | allowed only for noncommercial distribution and only if you | ||
1182 | 152 | received the program in object code or executable form with such | ||
1183 | 153 | an offer, in accord with Subsection b above.) | ||
1184 | 154 | |||
1185 | 155 | The source code for a work means the preferred form of the work for | ||
1186 | 156 | making modifications to it. For an executable work, complete source | ||
1187 | 157 | code means all the source code for all modules it contains, plus any | ||
1188 | 158 | associated interface definition files, plus the scripts used to | ||
1189 | 159 | control compilation and installation of the executable. However, as a | ||
1190 | 160 | special exception, the source code distributed need not include | ||
1191 | 161 | anything that is normally distributed (in either source or binary | ||
1192 | 162 | form) with the major components (compiler, kernel, and so on) of the | ||
1193 | 163 | operating system on which the executable runs, unless that component | ||
1194 | 164 | itself accompanies the executable. | ||
1195 | 165 | |||
1196 | 166 | If distribution of executable or object code is made by offering | ||
1197 | 167 | access to copy from a designated place, then offering equivalent | ||
1198 | 168 | access to copy the source code from the same place counts as | ||
1199 | 169 | distribution of the source code, even though third parties are not | ||
1200 | 170 | compelled to copy the source along with the object code. | ||
1201 | 171 | |||
1202 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program | ||
1203 | 173 | except as expressly provided under this License. Any attempt | ||
1204 | 174 | otherwise to copy, modify, sublicense or distribute the Program is | ||
1205 | 175 | void, and will automatically terminate your rights under this License. | ||
1206 | 176 | However, parties who have received copies, or rights, from you under | ||
1207 | 177 | this License will not have their licenses terminated so long as such | ||
1208 | 178 | parties remain in full compliance. | ||
1209 | 179 | |||
1210 | 180 | 5. You are not required to accept this License, since you have not | ||
1211 | 181 | signed it. However, nothing else grants you permission to modify or | ||
1212 | 182 | distribute the Program or its derivative works. These actions are | ||
1213 | 183 | prohibited by law if you do not accept this License. Therefore, by | ||
1214 | 184 | modifying or distributing the Program (or any work based on the | ||
1215 | 185 | Program), you indicate your acceptance of this License to do so, and | ||
1216 | 186 | all its terms and conditions for copying, distributing or modifying | ||
1217 | 187 | the Program or works based on it. | ||
1218 | 188 | |||
1219 | 189 | 6. Each time you redistribute the Program (or any work based on the | ||
1220 | 190 | Program), the recipient automatically receives a license from the | ||
1221 | 191 | original licensor to copy, distribute or modify the Program subject to | ||
1222 | 192 | these terms and conditions. You may not impose any further | ||
1223 | 193 | restrictions on the recipients' exercise of the rights granted herein. | ||
1224 | 194 | You are not responsible for enforcing compliance by third parties to | ||
1225 | 195 | this License. | ||
1226 | 196 | |||
1227 | 197 | 7. If, as a consequence of a court judgment or allegation of patent | ||
1228 | 198 | infringement or for any other reason (not limited to patent issues), | ||
1229 | 199 | conditions are imposed on you (whether by court order, agreement or | ||
1230 | 200 | otherwise) that contradict the conditions of this License, they do not | ||
1231 | 201 | excuse you from the conditions of this License. If you cannot | ||
1232 | 202 | distribute so as to satisfy simultaneously your obligations under this | ||
1233 | 203 | License and any other pertinent obligations, then as a consequence you | ||
1234 | 204 | may not distribute the Program at all. For example, if a patent | ||
1235 | 205 | license would not permit royalty-free redistribution of the Program by | ||
1236 | 206 | all those who receive copies directly or indirectly through you, then | ||
1237 | 207 | the only way you could satisfy both it and this License would be to | ||
1238 | 208 | refrain entirely from distribution of the Program. | ||
1239 | 209 | |||
1240 | 210 | If any portion of this section is held invalid or unenforceable under | ||
1241 | 211 | any particular circumstance, the balance of the section is intended to | ||
1242 | 212 | apply and the section as a whole is intended to apply in other | ||
1243 | 213 | circumstances. | ||
1244 | 214 | |||
1245 | 215 | It is not the purpose of this section to induce you to infringe any | ||
1246 | 216 | patents or other property right claims or to contest validity of any | ||
1247 | 217 | such claims; this section has the sole purpose of protecting the | ||
1248 | 218 | integrity of the free software distribution system, which is | ||
1249 | 219 | implemented by public license practices. Many people have made | ||
1250 | 220 | generous contributions to the wide range of software distributed | ||
1251 | 221 | through that system in reliance on consistent application of that | ||
1252 | 222 | system; it is up to the author/donor to decide if he or she is willing | ||
1253 | 223 | to distribute software through any other system and a licensee cannot | ||
1254 | 224 | impose that choice. | ||
1255 | 225 | |||
1256 | 226 | This section is intended to make thoroughly clear what is believed to | ||
1257 | 227 | be a consequence of the rest of this License. | ||
1258 | 228 | |||
1259 | 229 | 8. If the distribution and/or use of the Program is restricted in | ||
1260 | 230 | certain countries either by patents or by copyrighted interfaces, the | ||
1261 | 231 | original copyright holder who places the Program under this License | ||
1262 | 232 | may add an explicit geographical distribution limitation excluding | ||
1263 | 233 | those countries, so that distribution is permitted only in or among | ||
1264 | 234 | countries not thus excluded. In such case, this License incorporates | ||
1265 | 235 | the limitation as if written in the body of this License. | ||
1266 | 236 | |||
1267 | 237 | 9. The Free Software Foundation may publish revised and/or new versions | ||
1268 | 238 | of the General Public License from time to time. Such new versions will | ||
1269 | 239 | be similar in spirit to the present version, but may differ in detail to | ||
1270 | 240 | address new problems or concerns. | ||
1271 | 241 | |||
1272 | 242 | Each version is given a distinguishing version number. If the Program | ||
1273 | 243 | specifies a version number of this License which applies to it and "any | ||
1274 | 244 | later version", you have the option of following the terms and conditions | ||
1275 | 245 | either of that version or of any later version published by the Free | ||
1276 | 246 | Software Foundation. If the Program does not specify a version number of | ||
1277 | 247 | this License, you may choose any version ever published by the Free Software | ||
1278 | 248 | Foundation. | ||
1279 | 249 | |||
1280 | 250 | 10. If you wish to incorporate parts of the Program into other free | ||
1281 | 251 | programs whose distribution conditions are different, write to the author | ||
1282 | 252 | to ask for permission. For software which is copyrighted by the Free | ||
1283 | 253 | Software Foundation, write to the Free Software Foundation; we sometimes | ||
1284 | 254 | make exceptions for this. Our decision will be guided by the two goals | ||
1285 | 255 | of preserving the free status of all derivatives of our free software and | ||
1286 | 256 | of promoting the sharing and reuse of software generally. | ||
1287 | 257 | |||
1288 | 258 | NO WARRANTY | ||
1289 | 259 | |||
1290 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||
1291 | 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | ||
1292 | 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||
1293 | 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||
1294 | 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
1295 | 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | ||
1296 | 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | ||
1297 | 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||
1298 | 268 | REPAIR OR CORRECTION. | ||
1299 | 269 | |||
1300 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
1301 | 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||
1302 | 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||
1303 | 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||
1304 | 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||
1305 | 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||
1306 | 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||
1307 | 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||
1308 | 278 | POSSIBILITY OF SUCH DAMAGES. | ||
1309 | 279 | |||
1310 | 280 | END OF TERMS AND CONDITIONS | ||
1311 | 281 | |||
1312 | 282 | How to Apply These Terms to Your New Programs | ||
1313 | 283 | |||
1314 | 284 | If you develop a new program, and you want it to be of the greatest | ||
1315 | 285 | possible use to the public, the best way to achieve this is to make it | ||
1316 | 286 | free software which everyone can redistribute and change under these terms. | ||
1317 | 287 | |||
1318 | 288 | To do so, attach the following notices to the program. It is safest | ||
1319 | 289 | to attach them to the start of each source file to most effectively | ||
1320 | 290 | convey the exclusion of warranty; and each file should have at least | ||
1321 | 291 | the "copyright" line and a pointer to where the full notice is found. | ||
1322 | 292 | |||
1323 | 293 | <one line to give the program's name and a brief idea of what it does.> | ||
1324 | 294 | Copyright (C) <year> <name of author> | ||
1325 | 295 | |||
1326 | 296 | This program is free software; you can redistribute it and/or modify | ||
1327 | 297 | it under the terms of the GNU General Public License as published by | ||
1328 | 298 | the Free Software Foundation; either version 2 of the License, or | ||
1329 | 299 | (at your option) any later version. | ||
1330 | 300 | |||
1331 | 301 | This program is distributed in the hope that it will be useful, | ||
1332 | 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1333 | 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1334 | 304 | GNU General Public License for more details. | ||
1335 | 305 | |||
1336 | 306 | You should have received a copy of the GNU General Public License along | ||
1337 | 307 | with this program; if not, write to the Free Software Foundation, Inc., | ||
1338 | 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
1339 | 309 | |||
1340 | 310 | Also add information on how to contact you by electronic and paper mail. | ||
1341 | 311 | |||
1342 | 312 | If the program is interactive, make it output a short notice like this | ||
1343 | 313 | when it starts in an interactive mode: | ||
1344 | 314 | |||
1345 | 315 | Gnomovision version 69, Copyright (C) year name of author | ||
1346 | 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||
1347 | 317 | This is free software, and you are welcome to redistribute it | ||
1348 | 318 | under certain conditions; type `show c' for details. | ||
1349 | 319 | |||
1350 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate | ||
1351 | 321 | parts of the General Public License. Of course, the commands you use may | ||
1352 | 322 | be called something other than `show w' and `show c'; they could even be | ||
1353 | 323 | mouse-clicks or menu items--whatever suits your program. | ||
1354 | 324 | |||
1355 | 325 | You should also get your employer (if you work as a programmer) or your | ||
1356 | 326 | school, if any, to sign a "copyright disclaimer" for the program, if | ||
1357 | 327 | necessary. Here is a sample; alter the names: | ||
1358 | 328 | |||
1359 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program | ||
1360 | 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. | ||
1361 | 331 | |||
1362 | 332 | <signature of Ty Coon>, 1 April 1989 | ||
1363 | 333 | Ty Coon, President of Vice | ||
1364 | 334 | |||
1365 | 335 | This General Public License does not permit incorporating your program into | ||
1366 | 336 | proprietary programs. If your program is a subroutine library, you may | ||
1367 | 337 | consider it more useful to permit linking proprietary applications with the | ||
1368 | 338 | library. If this is what you want to do, use the GNU Lesser General | ||
1369 | 339 | Public License instead of this License. | ||
1370 | 340 | |||
1371 | 0 | 341 | ||
1372 | === renamed file 'COPYING' => 'COPYING.moved' | |||
1373 | === added file 'MANIFEST.in' | |||
1374 | --- MANIFEST.in 1970-01-01 00:00:00 +0000 | |||
1375 | +++ MANIFEST.in 2011-03-11 21:10:49 +0000 | |||
1376 | @@ -0,0 +1,13 @@ | |||
1377 | 1 | include COPYING AUTHORS README CHANGELOG | ||
1378 | 2 | include cobbler.spec | ||
1379 | 3 | |||
1380 | 4 | recursive-include aux * | ||
1381 | 5 | recursive-include config * | ||
1382 | 6 | recursive-include docs * | ||
1383 | 7 | recursive-include installer_templates * | ||
1384 | 8 | recursive-include kickstarts * | ||
1385 | 9 | recursive-include snippets * | ||
1386 | 10 | recursive-include scripts * | ||
1387 | 11 | recursive-include templates * | ||
1388 | 12 | recursive-include web * | ||
1389 | 13 | |||
1390 | 0 | 14 | ||
1391 | === renamed file 'MANIFEST.in' => 'MANIFEST.in.moved' | |||
1392 | === added file 'README' | |||
1393 | --- README 1970-01-01 00:00:00 +0000 | |||
1394 | +++ README 2011-03-11 21:10:49 +0000 | |||
1395 | @@ -0,0 +1,9 @@ | |||
1396 | 1 | Cobbler README | ||
1397 | 2 | |||
1398 | 3 | Docs are currently available two ways: | ||
1399 | 4 | - Install the RPM and run "man cobbler" | ||
1400 | 5 | - Run "perldoc cobbler.pod" from a source checkout | ||
1401 | 6 | |||
1402 | 7 | To build the RPM: | ||
1403 | 8 | - Run "make" | ||
1404 | 9 | |||
1405 | 0 | 10 | ||
1406 | === renamed file 'README' => 'README.moved' | |||
1407 | === added directory 'aux' | |||
1408 | === renamed directory 'aux' => 'aux.moved' | |||
1409 | === added file 'aux/anamon' | |||
1410 | --- aux/anamon 1970-01-01 00:00:00 +0000 | |||
1411 | +++ aux/anamon 2011-03-11 21:10:49 +0000 | |||
1412 | @@ -0,0 +1,280 @@ | |||
1413 | 1 | #!/usr/bin/python | ||
1414 | 2 | |||
1415 | 3 | """ | ||
1416 | 4 | This is a script used to automatically log details from an Anaconda | ||
1417 | 5 | install back to a cobbler server. | ||
1418 | 6 | |||
1419 | 7 | Copyright 2008, Red Hat, Inc | ||
1420 | 8 | various@redhat.com | ||
1421 | 9 | |||
1422 | 10 | This program is free software; you can redistribute it and/or modify | ||
1423 | 11 | it under the terms of the GNU General Public License as published by | ||
1424 | 12 | the Free Software Foundation; either version 2 of the License, or | ||
1425 | 13 | (at your option) any later version. | ||
1426 | 14 | |||
1427 | 15 | This program is distributed in the hope that it will be useful, | ||
1428 | 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1429 | 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1430 | 18 | GNU General Public License for more details. | ||
1431 | 19 | |||
1432 | 20 | You should have received a copy of the GNU General Public License | ||
1433 | 21 | along with this program; if not, write to the Free Software | ||
1434 | 22 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
1435 | 23 | 02110-1301 USA | ||
1436 | 24 | """ | ||
1437 | 25 | |||
1438 | 26 | import os | ||
1439 | 27 | import sys | ||
1440 | 28 | import string | ||
1441 | 29 | import time | ||
1442 | 30 | import re | ||
1443 | 31 | import base64 | ||
1444 | 32 | import shlex | ||
1445 | 33 | |||
1446 | 34 | # on older installers (EL 2) we might not have xmlrpclib | ||
1447 | 35 | # and can't do logging, however this is more widely | ||
1448 | 36 | # supported than remote syslog and also provides more | ||
1449 | 37 | # detail. | ||
1450 | 38 | try: | ||
1451 | 39 | import xmlrpclib | ||
1452 | 40 | except ImportError, e: | ||
1453 | 41 | print "xmlrpclib not available, exiting" | ||
1454 | 42 | sys.exit(0) | ||
1455 | 43 | |||
1456 | 44 | # shlex.split support arrived in python-2.3, the following will provide some | ||
1457 | 45 | # accomodation for older distros (e.g. RHEL3) | ||
1458 | 46 | if not hasattr(shlex, "split"): | ||
1459 | 47 | shlex.split = lambda s: s.split(" ") | ||
1460 | 48 | |||
1461 | 49 | class WatchedFile: | ||
1462 | 50 | def __init__(self, fn, alias): | ||
1463 | 51 | self.fn = fn | ||
1464 | 52 | self.alias = alias | ||
1465 | 53 | self.reset() | ||
1466 | 54 | |||
1467 | 55 | def reset(self): | ||
1468 | 56 | self.where = 0 | ||
1469 | 57 | self.last_size = 0 | ||
1470 | 58 | self.lfrag='' | ||
1471 | 59 | self.re_list={} | ||
1472 | 60 | self.seen_line={} | ||
1473 | 61 | |||
1474 | 62 | def exists(self): | ||
1475 | 63 | return os.access(self.fn, os.F_OK) | ||
1476 | 64 | |||
1477 | 65 | def lookfor(self,pattern): | ||
1478 | 66 | self.re_list[pattern] = re.compile(pattern,re.MULTILINE) | ||
1479 | 67 | self.seen_line[pattern] = 0 | ||
1480 | 68 | |||
1481 | 69 | def seen(self,pattern): | ||
1482 | 70 | if self.seen_line.has_key(pattern): | ||
1483 | 71 | return self.seen_line[pattern] | ||
1484 | 72 | else: | ||
1485 | 73 | return 0 | ||
1486 | 74 | |||
1487 | 75 | def changed(self): | ||
1488 | 76 | if not self.exists(): | ||
1489 | 77 | return 0 | ||
1490 | 78 | size = os.stat(self.fn)[6] | ||
1491 | 79 | if size > self.last_size: | ||
1492 | 80 | self.last_size = size | ||
1493 | 81 | return 1 | ||
1494 | 82 | else: | ||
1495 | 83 | return 0 | ||
1496 | 84 | |||
1497 | 85 | def uploadWrapper(self, blocksize = 262144): | ||
1498 | 86 | """upload a file in chunks using the uploadFile call""" | ||
1499 | 87 | retries = 3 | ||
1500 | 88 | fo = file(self.fn, "r") | ||
1501 | 89 | totalsize = os.path.getsize(self.fn) | ||
1502 | 90 | ofs = 0 | ||
1503 | 91 | while True: | ||
1504 | 92 | lap = time.time() | ||
1505 | 93 | contents = fo.read(blocksize) | ||
1506 | 94 | size = len(contents) | ||
1507 | 95 | data = base64.encodestring(contents) | ||
1508 | 96 | if size == 0: | ||
1509 | 97 | offset = -1 | ||
1510 | 98 | sz = ofs | ||
1511 | 99 | else: | ||
1512 | 100 | offset = ofs | ||
1513 | 101 | sz = size | ||
1514 | 102 | del contents | ||
1515 | 103 | tries = 0 | ||
1516 | 104 | while tries <= retries: | ||
1517 | 105 | debug("upload_log_data('%s', '%s', %s, %s, ...)\n" % (name, self.alias, sz, offset)) | ||
1518 | 106 | if session.upload_log_data(name, self.alias, sz, offset, data): | ||
1519 | 107 | break | ||
1520 | 108 | else: | ||
1521 | 109 | tries = tries + 1 | ||
1522 | 110 | if size == 0: | ||
1523 | 111 | break | ||
1524 | 112 | ofs += size | ||
1525 | 113 | fo.close() | ||
1526 | 114 | |||
1527 | 115 | def update(self): | ||
1528 | 116 | if not self.exists(): | ||
1529 | 117 | return | ||
1530 | 118 | if not self.changed(): | ||
1531 | 119 | return | ||
1532 | 120 | try: | ||
1533 | 121 | self.uploadWrapper() | ||
1534 | 122 | except: | ||
1535 | 123 | raise | ||
1536 | 124 | |||
1537 | 125 | class MountWatcher: | ||
1538 | 126 | |||
1539 | 127 | def __init__(self,mp): | ||
1540 | 128 | self.mountpoint = mp | ||
1541 | 129 | self.zero() | ||
1542 | 130 | |||
1543 | 131 | def zero(self): | ||
1544 | 132 | self.line='' | ||
1545 | 133 | self.time = time.time() | ||
1546 | 134 | |||
1547 | 135 | def update(self): | ||
1548 | 136 | found = 0 | ||
1549 | 137 | if os.path.exists('/proc/mounts'): | ||
1550 | 138 | fd = open('/proc/mounts') | ||
1551 | 139 | while 1: | ||
1552 | 140 | line = fd.readline() | ||
1553 | 141 | if not line: | ||
1554 | 142 | break | ||
1555 | 143 | parts = string.split(line) | ||
1556 | 144 | mp = parts[1] | ||
1557 | 145 | if mp == self.mountpoint: | ||
1558 | 146 | found = 1 | ||
1559 | 147 | if line != self.line: | ||
1560 | 148 | self.line = line | ||
1561 | 149 | self.time = time.time() | ||
1562 | 150 | fd.close() | ||
1563 | 151 | if not found: | ||
1564 | 152 | self.zero() | ||
1565 | 153 | |||
1566 | 154 | def stable(self): | ||
1567 | 155 | self.update() | ||
1568 | 156 | if self.line and (time.time() - self.time > 60): | ||
1569 | 157 | return 1 | ||
1570 | 158 | else: | ||
1571 | 159 | return 0 | ||
1572 | 160 | |||
1573 | 161 | def anamon_loop(): | ||
1574 | 162 | alog = WatchedFile("/tmp/anaconda.log", "anaconda.log") | ||
1575 | 163 | alog.lookfor("step installpackages$") | ||
1576 | 164 | |||
1577 | 165 | slog = WatchedFile("/tmp/syslog", "sys.log") | ||
1578 | 166 | xlog = WatchedFile("/tmp/X.log", "X.log") | ||
1579 | 167 | llog = WatchedFile("/tmp/lvmout", "lvmout.log") | ||
1580 | 168 | storage_log = WatchedFile("/tmp/storage.log", "storage.log") | ||
1581 | 169 | prgm_log = WatchedFile("/tmp/program.log", "program.log") | ||
1582 | 170 | vnc_log = WatchedFile("/tmp/vncserver.log", "vncserver.log") | ||
1583 | 171 | kcfg = WatchedFile("/tmp/ks.cfg", "ks.cfg") | ||
1584 | 172 | scrlog = WatchedFile("/tmp/ks-script.log", "ks-script.log") | ||
1585 | 173 | dump = WatchedFile("/tmp/anacdump.txt", "anacdump.txt") | ||
1586 | 174 | mod = WatchedFile("/tmp/modprobe.conf", "modprobe.conf") | ||
1587 | 175 | |||
1588 | 176 | # Setup '/mnt/sysimage' watcher | ||
1589 | 177 | sysimage = MountWatcher("/mnt/sysimage") | ||
1590 | 178 | |||
1591 | 179 | # Monitor for {install,upgrade}.log changes | ||
1592 | 180 | package_logs = list() | ||
1593 | 181 | package_logs.append(WatchedFile("/mnt/sysimage/root/install.log", "install.log")) | ||
1594 | 182 | package_logs.append(WatchedFile("/mnt/sysimage/tmp/install.log", "tmp+install.log")) | ||
1595 | 183 | package_logs.append(WatchedFile("/mnt/sysimage/root/upgrade.log", "upgrade.log")) | ||
1596 | 184 | package_logs.append(WatchedFile("/mnt/sysimage/tmp/upgrade.log", "tmp+upgrade.log")) | ||
1597 | 185 | |||
1598 | 186 | # Monitor for bootloader configuration changes | ||
1599 | 187 | bootloader_cfgs = list() | ||
1600 | 188 | bootloader_cfgs.append(WatchedFile("/mnt/sysimage/boot/grub/grub.conf", "grub.conf")) | ||
1601 | 189 | bootloader_cfgs.append(WatchedFile("/mnt/sysimage/boot/etc/yaboot.conf", "yaboot.conf")) | ||
1602 | 190 | bootloader_cfgs.append(WatchedFile("/mnt/sysimage/boot/efi/efi/redhat/elilo.conf", "elilo.conf")) | ||
1603 | 191 | bootloader_cfgs.append(WatchedFile("/mnt/sysimage/etc/zipl.conf", "zipl.conf")) | ||
1604 | 192 | |||
1605 | 193 | # Were we asked to watch specific files? | ||
1606 | 194 | watchlist = list() | ||
1607 | 195 | waitlist = list() | ||
1608 | 196 | if watchfiles: | ||
1609 | 197 | # Create WatchedFile objects for each requested file | ||
1610 | 198 | for watchfile in watchfiles: | ||
1611 | 199 | if os.path.exists(watchfile): | ||
1612 | 200 | watchfilebase = os.path.basename(watchfile) | ||
1613 | 201 | watchlog = WatchedFile(watchfile, watchfilebase) | ||
1614 | 202 | watchlist.append(watchlog) | ||
1615 | 203 | |||
1616 | 204 | # Use the default watchlist and waitlist | ||
1617 | 205 | else: | ||
1618 | 206 | watchlist = [alog, slog, dump, scrlog, mod, llog, kcfg, storage_log, prgm_log, vnc_log, xlog] | ||
1619 | 207 | waitlist.extend(package_logs) | ||
1620 | 208 | waitlist.extend(bootloader_cfgs) | ||
1621 | 209 | |||
1622 | 210 | # Monitor loop | ||
1623 | 211 | while 1: | ||
1624 | 212 | time.sleep(5) | ||
1625 | 213 | |||
1626 | 214 | # Not all log files are available at the start, we'll loop through the | ||
1627 | 215 | # waitlist to determine when each file can be added to the watchlist | ||
1628 | 216 | for watch in waitlist: | ||
1629 | 217 | if alog.seen("step installpackages$") or (sysimage.stable() and watch.exists()): | ||
1630 | 218 | debug("Adding %s to watch list\n" % watch.alias) | ||
1631 | 219 | watchlist.append(watch) | ||
1632 | 220 | waitlist.remove(watch) | ||
1633 | 221 | |||
1634 | 222 | # Send any updates | ||
1635 | 223 | for wf in watchlist: | ||
1636 | 224 | wf.update() | ||
1637 | 225 | |||
1638 | 226 | # If asked to run_once, exit now | ||
1639 | 227 | if exit: | ||
1640 | 228 | break | ||
1641 | 229 | |||
1642 | 230 | # Establish some defaults | ||
1643 | 231 | name = "" | ||
1644 | 232 | server = "" | ||
1645 | 233 | port = "80" | ||
1646 | 234 | daemon = 1 | ||
1647 | 235 | debug = lambda x,**y: None | ||
1648 | 236 | watchfiles = [] | ||
1649 | 237 | exit = False | ||
1650 | 238 | |||
1651 | 239 | # Process command-line args | ||
1652 | 240 | n = 0 | ||
1653 | 241 | while n < len(sys.argv): | ||
1654 | 242 | arg = sys.argv[n] | ||
1655 | 243 | if arg == '--name': | ||
1656 | 244 | n = n+1 | ||
1657 | 245 | name = sys.argv[n] | ||
1658 | 246 | elif arg == '--watchfile': | ||
1659 | 247 | n = n+1 | ||
1660 | 248 | watchfiles.extend(shlex.split(sys.argv[n])) | ||
1661 | 249 | elif arg == '--exit': | ||
1662 | 250 | exit = True | ||
1663 | 251 | elif arg == '--server': | ||
1664 | 252 | n = n+1 | ||
1665 | 253 | server = sys.argv[n] | ||
1666 | 254 | elif arg == '--port': | ||
1667 | 255 | n = n+1 | ||
1668 | 256 | port = sys.argv[n] | ||
1669 | 257 | elif arg == '--debug': | ||
1670 | 258 | debug = lambda x,**y: sys.stderr.write(x % y) | ||
1671 | 259 | elif arg == '--fg': | ||
1672 | 260 | daemon = 0 | ||
1673 | 261 | n = n+1 | ||
1674 | 262 | |||
1675 | 263 | # Create an xmlrpc session handle | ||
1676 | 264 | session = xmlrpclib.Server("http://%s:%s/cobbler_api" % (server, port)) | ||
1677 | 265 | |||
1678 | 266 | # Fork and loop | ||
1679 | 267 | if daemon: | ||
1680 | 268 | if not os.fork(): | ||
1681 | 269 | # Redirect the standard I/O file descriptors to the specified file. | ||
1682 | 270 | DEVNULL = getattr(os, "devnull", "/dev/null") | ||
1683 | 271 | os.open(DEVNULL, os.O_RDWR) # standard input (0) | ||
1684 | 272 | os.dup2(0, 1) # Duplicate standard input to standard output (1) | ||
1685 | 273 | os.dup2(0, 2) # Duplicate standard input to standard error (2) | ||
1686 | 274 | |||
1687 | 275 | anamon_loop() | ||
1688 | 276 | sys.exit(1) | ||
1689 | 277 | sys.exit(0) | ||
1690 | 278 | else: | ||
1691 | 279 | anamon_loop() | ||
1692 | 280 | |||
1693 | 0 | 281 | ||
1694 | === added file 'aux/anamon.init' | |||
1695 | --- aux/anamon.init 1970-01-01 00:00:00 +0000 | |||
1696 | +++ aux/anamon.init 2011-03-11 21:10:49 +0000 | |||
1697 | @@ -0,0 +1,101 @@ | |||
1698 | 1 | #!/bin/bash | ||
1699 | 2 | ## BEGIN INIT INFO | ||
1700 | 3 | # Provides: anamon | ||
1701 | 4 | # Default-Start: 3 5 | ||
1702 | 5 | # Default-Stop: 0 1 2 4 6 | ||
1703 | 6 | # Required-Start: | ||
1704 | 7 | # Should-Start: $network | ||
1705 | 8 | # Short-Description: Starts the cobbler anamon boot notification program | ||
1706 | 9 | # Description: anamon runs the first time a machine is booted after | ||
1707 | 10 | # installation. | ||
1708 | 11 | ## END INIT INFO | ||
1709 | 12 | |||
1710 | 13 | # | ||
1711 | 14 | # anamon: Starts the cobbler post-install boot notification program | ||
1712 | 15 | # | ||
1713 | 16 | # chkconfig: 35 99 95 | ||
1714 | 17 | # | ||
1715 | 18 | # description: anamon runs the first time a machine is booted after | ||
1716 | 19 | # installation. | ||
1717 | 20 | # | ||
1718 | 21 | |||
1719 | 22 | LOCKFILE="/var/lock/subsys/anamon" | ||
1720 | 23 | CFGFILE="/etc/sysconfig/anamon" | ||
1721 | 24 | |||
1722 | 25 | # Source function library. | ||
1723 | 26 | . /etc/init.d/functions | ||
1724 | 27 | |||
1725 | 28 | # Source anamon config | ||
1726 | 29 | . $CFGFILE | ||
1727 | 30 | |||
1728 | 31 | LOGFILES=${LOGFILES:-/var/log/boot.log} | ||
1729 | 32 | |||
1730 | 33 | # FIXME - can we rely on the koan snippet to update /etc/profile.d/cobbler.sh? | ||
1731 | 34 | if [ -z "$COBBLER_SERVER" ]; then | ||
1732 | 35 | echo "No COBBLER_SERVER defined in $CFGFILE" | ||
1733 | 36 | exit 1 | ||
1734 | 37 | fi | ||
1735 | 38 | |||
1736 | 39 | if [ -z "$COBBLER_NAME" ]; then | ||
1737 | 40 | echo "No COBBLER_NAME defined in $CFGFILE" | ||
1738 | 41 | exit 1 | ||
1739 | 42 | fi | ||
1740 | 43 | |||
1741 | 44 | if [ -z "$LOGFILES" ]; then | ||
1742 | 45 | echo "No LOGFILES defined in $CFGFILE" | ||
1743 | 46 | exit 1 | ||
1744 | 47 | fi | ||
1745 | 48 | |||
1746 | 49 | start() { | ||
1747 | 50 | echo -n $"Starting anamon: " | ||
1748 | 51 | daemon /usr/local/sbin/anamon --watchfile \"$LOGFILES\" --name $COBBLER_NAME --server $COBBLER_SERVER --port ${COBBLER_PORT:-80} --exit | ||
1749 | 52 | RETVAL=$? | ||
1750 | 53 | [ $RETVAL -eq 0 ] && touch $LOCKFILE | ||
1751 | 54 | echo | ||
1752 | 55 | |||
1753 | 56 | # Disable service start | ||
1754 | 57 | chkconfig anamon off | ||
1755 | 58 | |||
1756 | 59 | return $RETVAL | ||
1757 | 60 | } | ||
1758 | 61 | |||
1759 | 62 | stop () { | ||
1760 | 63 | echo -n $"Shutting down anamon: " | ||
1761 | 64 | killproc /usr/local/sbin/anamon | ||
1762 | 65 | RETVAL=$? | ||
1763 | 66 | [ $RETVAL -eq 0 ] && rm -f $LOCKFILE | ||
1764 | 67 | echo | ||
1765 | 68 | return $RETVAL | ||
1766 | 69 | } | ||
1767 | 70 | |||
1768 | 71 | restart() { | ||
1769 | 72 | stop | ||
1770 | 73 | start | ||
1771 | 74 | } | ||
1772 | 75 | |||
1773 | 76 | case "$1" in | ||
1774 | 77 | start) | ||
1775 | 78 | start | ||
1776 | 79 | ;; | ||
1777 | 80 | stop) | ||
1778 | 81 | stop | ||
1779 | 82 | ;; | ||
1780 | 83 | restart) | ||
1781 | 84 | restart | ||
1782 | 85 | ;; | ||
1783 | 86 | condrestart) | ||
1784 | 87 | if [ -f $LOCKFILE ]; then | ||
1785 | 88 | restart | ||
1786 | 89 | fi | ||
1787 | 90 | ;; | ||
1788 | 91 | status) | ||
1789 | 92 | status anamon | ||
1790 | 93 | RETVAL=$? | ||
1791 | 94 | ;; | ||
1792 | 95 | *) | ||
1793 | 96 | echo $"Usage: $0 {start|stop|status|restart|condrestart}" | ||
1794 | 97 | RETVAL=2 | ||
1795 | 98 | ;; | ||
1796 | 99 | esac | ||
1797 | 100 | |||
1798 | 101 | exit $RETVAL | ||
1799 | 0 | 102 | ||
1800 | === added directory 'cobbler' | |||
1801 | === renamed directory 'cobbler' => 'cobbler.moved' | |||
1802 | === added file 'cobbler.spec' | |||
1803 | --- cobbler.spec 1970-01-01 00:00:00 +0000 | |||
1804 | +++ cobbler.spec 2011-03-11 21:10:49 +0000 | |||
1805 | @@ -0,0 +1,266 @@ | |||
1806 | 1 | %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} | ||
1807 | 2 | %{!?pyver: %define pyver %(%{__python} -c "import sys ; print sys.version[:3]" || echo 0)} | ||
1808 | 3 | |||
1809 | 4 | %define _binaries_in_noarch_packages_terminate_build 0 | ||
1810 | 5 | %global debug_package %{nil} | ||
1811 | 6 | Summary: Boot server configurator | ||
1812 | 7 | Name: cobbler | ||
1813 | 8 | License: GPLv2+ | ||
1814 | 9 | AutoReq: no | ||
1815 | 10 | Version: 2.1.0 | ||
1816 | 11 | Release: 2%{?dist} | ||
1817 | 12 | Source0: http://shenson.fedorapeople.org/cobbler/cobbler-%{version}.tar.gz | ||
1818 | 13 | Group: Applications/System | ||
1819 | 14 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot | ||
1820 | 15 | BuildArch: noarch | ||
1821 | 16 | Url: http://fedorahosted.org/cobbler | ||
1822 | 17 | |||
1823 | 18 | BuildRequires: redhat-rpm-config | ||
1824 | 19 | BuildRequires: PyYAML | ||
1825 | 20 | BuildRequires: python-cheetah | ||
1826 | 21 | |||
1827 | 22 | Requires: python >= 2.3 | ||
1828 | 23 | Requires: httpd | ||
1829 | 24 | Requires: tftp-server | ||
1830 | 25 | Requires: mod_wsgi | ||
1831 | 26 | Requires: createrepo | ||
1832 | 27 | Requires: python-cheetah | ||
1833 | 28 | Requires: python-netaddr | ||
1834 | 29 | Requires: python-simplejson | ||
1835 | 30 | Requires: python-urlgrabber | ||
1836 | 31 | Requires: PyYAML | ||
1837 | 32 | Requires: rsync | ||
1838 | 33 | |||
1839 | 34 | %if 0%{?fedora} >= 11 || 0%{?rhel} >= 6 | ||
1840 | 35 | Requires: python(abi) >= %{pyver} | ||
1841 | 36 | Requires: genisoimage | ||
1842 | 37 | %else | ||
1843 | 38 | Requires: mkisofs | ||
1844 | 39 | %endif | ||
1845 | 40 | %if 0%{?fedora} >= 8 | ||
1846 | 41 | BuildRequires: python-setuptools-devel | ||
1847 | 42 | %else | ||
1848 | 43 | BuildRequires: python-setuptools | ||
1849 | 44 | %endif | ||
1850 | 45 | %if 0%{?fedora} >= 6 || 0%{?rhel} >= 5 | ||
1851 | 46 | Requires: yum-utils | ||
1852 | 47 | %endif | ||
1853 | 48 | |||
1854 | 49 | Requires(post): /sbin/chkconfig | ||
1855 | 50 | Requires(preun): /sbin/chkconfig | ||
1856 | 51 | Requires(preun): /sbin/service | ||
1857 | 52 | |||
1858 | 53 | %description | ||
1859 | 54 | |||
1860 | 55 | Cobbler is a network install server. Cobbler supports PXE, | ||
1861 | 56 | virtualized installs, and re-installing existing Linux machines. The | ||
1862 | 57 | last two modes use a helper tool, 'koan', that integrates with | ||
1863 | 58 | cobbler. There is also a web interface 'cobbler-web'. Cobbler's | ||
1864 | 59 | advanced features include importing distributions from DVDs and rsync | ||
1865 | 60 | mirrors, kickstart templating, integrated yum mirroring, and built-in | ||
1866 | 61 | DHCP/DNS Management. Cobbler has a XMLRPC API for integration with | ||
1867 | 62 | other applications. | ||
1868 | 63 | |||
1869 | 64 | %prep | ||
1870 | 65 | %setup -q | ||
1871 | 66 | |||
1872 | 67 | %build | ||
1873 | 68 | %{__python} setup.py build | ||
1874 | 69 | |||
1875 | 70 | %install | ||
1876 | 71 | test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT | ||
1877 | 72 | %{__python} setup.py install --optimize=1 --root=$RPM_BUILD_ROOT $PREFIX | ||
1878 | 73 | mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d | ||
1879 | 74 | install -p -m 644 config/cobbler.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/ | ||
1880 | 75 | install -p -m 644 config/cobbler_web.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/ | ||
1881 | 76 | |||
1882 | 77 | mkdir -p $RPM_BUILD_ROOT/var/spool/koan | ||
1883 | 78 | |||
1884 | 79 | %if 0%{?fedora} >= 9 || 0%{?rhel} > 5 | ||
1885 | 80 | mkdir -p $RPM_BUILD_ROOT/var/lib/tftpboot/images | ||
1886 | 81 | %else | ||
1887 | 82 | mkdir -p $RPM_BUILD_ROOT/tftpboot/images | ||
1888 | 83 | %endif | ||
1889 | 84 | |||
1890 | 85 | rm -f $RPM_BUILD_ROOT/etc/cobbler/cobblerd | ||
1891 | 86 | |||
1892 | 87 | %clean | ||
1893 | 88 | test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT | ||
1894 | 89 | |||
1895 | 90 | %post | ||
1896 | 91 | if [ "$1" = "1" ]; | ||
1897 | 92 | then | ||
1898 | 93 | # This happens upon initial install. Upgrades will follow the next else | ||
1899 | 94 | /sbin/chkconfig --add cobblerd | ||
1900 | 95 | elif [ "$1" -ge "2" ]; | ||
1901 | 96 | then | ||
1902 | 97 | # backup config | ||
1903 | 98 | if [ -e /var/lib/cobbler/distros ]; then | ||
1904 | 99 | cp /var/lib/cobbler/distros* /var/lib/cobbler/backup 2>/dev/null | ||
1905 | 100 | cp /var/lib/cobbler/profiles* /var/lib/cobbler/backup 2>/dev/null | ||
1906 | 101 | cp /var/lib/cobbler/systems* /var/lib/cobbler/backup 2>/dev/null | ||
1907 | 102 | cp /var/lib/cobbler/repos* /var/lib/cobbler/backup 2>/dev/null | ||
1908 | 103 | cp /var/lib/cobbler/networks* /var/lib/cobbler/backup 2>/dev/null | ||
1909 | 104 | cp /var/lib/cobbler/mgmtclasses* /var/lib/cobbler/backup 2>/dev/null | ||
1910 | 105 | cp /var/lib/cobbler/packages* /var/lib/cobbler/backup 2>/dev/null | ||
1911 | 106 | cp /var/lib/cobbler/files* /var/lib/cobbler/backup 2>/dev/null | ||
1912 | 107 | fi | ||
1913 | 108 | if [ -e /var/lib/cobbler/config ]; then | ||
1914 | 109 | cp -a /var/lib/cobbler/config /var/lib/cobbler/backup 2>/dev/null | ||
1915 | 110 | fi | ||
1916 | 111 | # upgrade older installs | ||
1917 | 112 | # move power and pxe-templates from /etc/cobbler, backup new templates to *.rpmnew | ||
1918 | 113 | for n in power pxe; do | ||
1919 | 114 | rm -f /etc/cobbler/$n*.rpmnew | ||
1920 | 115 | find /etc/cobbler -maxdepth 1 -name "$n*" -type f | while read f; do | ||
1921 | 116 | newf=/etc/cobbler/$n/`basename $f` | ||
1922 | 117 | [ -e $newf ] && mv $newf $newf.rpmnew | ||
1923 | 118 | mv $f $newf | ||
1924 | 119 | done | ||
1925 | 120 | done | ||
1926 | 121 | # upgrade older installs | ||
1927 | 122 | # copy kickstarts from /etc/cobbler to /var/lib/cobbler/kickstarts | ||
1928 | 123 | rm -f /etc/cobbler/*.ks.rpmnew | ||
1929 | 124 | find /etc/cobbler -maxdepth 1 -name "*.ks" -type f | while read f; do | ||
1930 | 125 | newf=/var/lib/cobbler/kickstarts/`basename $f` | ||
1931 | 126 | [ -e $newf ] && mv $newf $newf.rpmnew | ||
1932 | 127 | cp $f $newf | ||
1933 | 128 | done | ||
1934 | 129 | /sbin/service cobblerd condrestart | ||
1935 | 130 | fi | ||
1936 | 131 | |||
1937 | 132 | %preun | ||
1938 | 133 | if [ $1 = 0 ]; then | ||
1939 | 134 | /sbin/service cobblerd stop >/dev/null 2>&1 || : | ||
1940 | 135 | chkconfig --del cobblerd || : | ||
1941 | 136 | fi | ||
1942 | 137 | |||
1943 | 138 | %postun | ||
1944 | 139 | if [ "$1" -ge "1" ]; then | ||
1945 | 140 | /sbin/service cobblerd condrestart >/dev/null 2>&1 || : | ||
1946 | 141 | /sbin/service httpd condrestart >/dev/null 2>&1 || : | ||
1947 | 142 | fi | ||
1948 | 143 | |||
1949 | 144 | |||
1950 | 145 | %files | ||
1951 | 146 | |||
1952 | 147 | %defattr(-,root,root,-) | ||
1953 | 148 | |||
1954 | 149 | %{_bindir}/cobbler | ||
1955 | 150 | %{_bindir}/cobbler-ext-nodes | ||
1956 | 151 | %{_bindir}/cobblerd | ||
1957 | 152 | %{_sbindir}/tftpd.py* | ||
1958 | 153 | |||
1959 | 154 | %config(noreplace) %{_sysconfdir}/cobbler | ||
1960 | 155 | /etc/init.d/cobblerd | ||
1961 | 156 | |||
1962 | 157 | %{python_sitelib}/cobbler | ||
1963 | 158 | |||
1964 | 159 | %config(noreplace) /var/lib/cobbler | ||
1965 | 160 | |||
1966 | 161 | /var/log/cobbler | ||
1967 | 162 | /var/www/cobbler | ||
1968 | 163 | |||
1969 | 164 | %{_mandir}/man1/cobbler.1.gz | ||
1970 | 165 | |||
1971 | 166 | %config(noreplace) /etc/httpd/conf.d/cobbler.conf | ||
1972 | 167 | |||
1973 | 168 | %if 0%{?fedora} >= 9 || 0%{?rhel} >= 5 | ||
1974 | 169 | %exclude %{python_sitelib}/cobbler/sub_process.py* | ||
1975 | 170 | %endif | ||
1976 | 171 | %if 0%{?fedora} >= 9 || 0%{?rhel} > 5 | ||
1977 | 172 | %{python_sitelib}/cobbler*.egg-info | ||
1978 | 173 | /var/lib/tftpboot/images | ||
1979 | 174 | %else | ||
1980 | 175 | /tftpboot/images | ||
1981 | 176 | %endif | ||
1982 | 177 | |||
1983 | 178 | %doc AUTHORS CHANGELOG README COPYING | ||
1984 | 179 | |||
1985 | 180 | %package -n koan | ||
1986 | 181 | |||
1987 | 182 | Summary: Helper tool that performs cobbler orders on remote machines | ||
1988 | 183 | Group: Applications/System | ||
1989 | 184 | Requires: python >= 2.0 | ||
1990 | 185 | %if 0%{?fedora} >= 11 || 0%{?rhel} >= 6 | ||
1991 | 186 | Requires: python(abi) >= %{pyver} | ||
1992 | 187 | %endif | ||
1993 | 188 | |||
1994 | 189 | |||
1995 | 190 | %description -n koan | ||
1996 | 191 | |||
1997 | 192 | Koan stands for kickstart-over-a-network and allows for both | ||
1998 | 193 | network installation of new virtualized guests and reinstallation | ||
1999 | 194 | of an existing system. For use with a boot-server configured with Cobbler | ||
2000 | 195 | |||
2001 | 196 | %files -n koan | ||
2002 | 197 | %defattr(-,root,root,-) | ||
2003 | 198 | %dir /var/spool/koan | ||
2004 | 199 | %dir /var/lib/koan/config | ||
2005 | 200 | %{_bindir}/koan | ||
2006 | 201 | %{_bindir}/cobbler-register | ||
2007 | 202 | %{python_sitelib}/koan | ||
2008 | 203 | |||
2009 | 204 | %if 0%{?fedora} >= 9 || 0%{?rhel} >= 5 | ||
2010 | 205 | %exclude %{python_sitelib}/koan/sub_process.py* | ||
2011 | 206 | %exclude %{python_sitelib}/koan/opt_parse.py* | ||
2012 | 207 | %exclude %{python_sitelib}/koan/text_wrap.py* | ||
2013 | 208 | %endif | ||
2014 | 209 | |||
2015 | 210 | %{_mandir}/man1/koan.1.gz | ||
2016 | 211 | %{_mandir}/man1/cobbler-register.1.gz | ||
2017 | 212 | %dir /var/log/koan | ||
2018 | 213 | %doc AUTHORS COPYING CHANGELOG README | ||
2019 | 214 | |||
2020 | 215 | |||
2021 | 216 | %package -n cobbler-web | ||
2022 | 217 | |||
2023 | 218 | Summary: Web interface for Cobbler | ||
2024 | 219 | Group: Applications/System | ||
2025 | 220 | Requires: cobbler | ||
2026 | 221 | Requires: Django | ||
2027 | 222 | %if 0%{?fedora} >= 11 || 0%{?rhel} >= 6 | ||
2028 | 223 | Requires: python(abi) >= %{pyver} | ||
2029 | 224 | %endif | ||
2030 | 225 | |||
2031 | 226 | %description -n cobbler-web | ||
2032 | 227 | |||
2033 | 228 | Web interface for Cobbler that allows visiting | ||
2034 | 229 | http://server/cobbler_web to configure the install server. | ||
2035 | 230 | |||
2036 | 231 | %files -n cobbler-web | ||
2037 | 232 | %defattr(-,root,root,-) | ||
2038 | 233 | %doc AUTHORS COPYING CHANGELOG README | ||
2039 | 234 | %config(noreplace) /etc/httpd/conf.d/cobbler_web.conf | ||
2040 | 235 | %defattr(-,apache,apache,-) | ||
2041 | 236 | /usr/share/cobbler/web | ||
2042 | 237 | %dir /var/lib/cobbler/webui_sessions | ||
2043 | 238 | /var/www/cobbler_webui_content/ | ||
2044 | 239 | |||
2045 | 240 | %changelog | ||
2046 | 241 | * Thu Jun 17 2010 Scott Henson <shenson@redhat.com> - 2.1.0-1 | ||
2047 | 242 | - Bump upstream release | ||
2048 | 243 | |||
2049 | 244 | * Tue Apr 27 2010 Scott Henson <shenson@redhat.com> - 2.0.4-1 | ||
2050 | 245 | - Bug fix release, see Changelog for details | ||
2051 | 246 | |||
2052 | 247 | * Thu Apr 15 2010 Devan Goodwin <dgoodwin@rm-rf.ca> 2.0.3.2-1 | ||
2053 | 248 | - Tagging for new build tools. | ||
2054 | 249 | |||
2055 | 250 | * Mon Mar 1 2010 Scott Henson <shenson@redhat.com> - 2.0.3.1-3 | ||
2056 | 251 | - Bump release because I forgot cobbler-web | ||
2057 | 252 | |||
2058 | 253 | * Mon Mar 1 2010 Scott Henson <shenson@redhat.com> - 2.0.3.1-2 | ||
2059 | 254 | - Remove requires on mkinitrd as it is not used | ||
2060 | 255 | |||
2061 | 256 | * Mon Feb 15 2010 Scott Henson <shenson@redhat.com> - 2.0.3.1-1 | ||
2062 | 257 | - Upstream Brown Paper Bag Release (see CHANGELOG) | ||
2063 | 258 | |||
2064 | 259 | * Thu Feb 11 2010 Scott Henson <shenson@redhat.com> - 2.0.3-1 | ||
2065 | 260 | - Upstream changes (see CHANGELOG) | ||
2066 | 261 | |||
2067 | 262 | * Mon Nov 23 2009 John Eckersberg <jeckersb@redhat.com> - 2.0.2-1 | ||
2068 | 263 | - Upstream changes (see CHANGELOG) | ||
2069 | 264 | |||
2070 | 265 | * Tue Sep 15 2009 Michael DeHaan <mdehaan@redhat.com> - 2.0.0-1 | ||
2071 | 266 | - First release with unified spec files | ||
2072 | 0 | 267 | ||
2073 | === renamed file 'cobbler.spec' => 'cobbler.spec.moved' | |||
2074 | === added file 'cobbler/__init__.py' | |||
2075 | === added file 'cobbler/action_acl.py' | |||
2076 | --- cobbler/action_acl.py 1970-01-01 00:00:00 +0000 | |||
2077 | +++ cobbler/action_acl.py 2011-03-11 21:10:49 +0000 | |||
2078 | @@ -0,0 +1,120 @@ | |||
2079 | 1 | """ | ||
2080 | 2 | Configures acls for various users/groups so they can access the cobbler command | ||
2081 | 3 | line as non-root. Now that CLI is largely remoted (XMLRPC) this is largely just | ||
2082 | 4 | useful for not having to log in (access to shared-secret) file but also grants | ||
2083 | 5 | access to hand-edit various config files and other useful things. | ||
2084 | 6 | |||
2085 | 7 | Copyright 2006-2009, Red Hat, Inc | ||
2086 | 8 | Michael DeHaan <mdehaan@redhat.com> | ||
2087 | 9 | |||
2088 | 10 | This program is free software; you can redistribute it and/or modify | ||
2089 | 11 | it under the terms of the GNU General Public License as published by | ||
2090 | 12 | the Free Software Foundation; either version 2 of the License, or | ||
2091 | 13 | (at your option) any later version. | ||
2092 | 14 | |||
2093 | 15 | This program is distributed in the hope that it will be useful, | ||
2094 | 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2095 | 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2096 | 18 | GNU General Public License for more details. | ||
2097 | 19 | |||
2098 | 20 | You should have received a copy of the GNU General Public License | ||
2099 | 21 | along with this program; if not, write to the Free Software | ||
2100 | 22 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
2101 | 23 | 02110-1301 USA | ||
2102 | 24 | """ | ||
2103 | 25 | |||
2104 | 26 | import os | ||
2105 | 27 | import os.path | ||
2106 | 28 | import shutil | ||
2107 | 29 | import sys | ||
2108 | 30 | import glob | ||
2109 | 31 | import traceback | ||
2110 | 32 | import errno | ||
2111 | 33 | import utils | ||
2112 | 34 | from cexceptions import * | ||
2113 | 35 | from utils import _ | ||
2114 | 36 | import clogger | ||
2115 | 37 | |||
2116 | 38 | class AclConfig: | ||
2117 | 39 | |||
2118 | 40 | def __init__(self,config,logger=None): | ||
2119 | 41 | """ | ||
2120 | 42 | Constructor | ||
2121 | 43 | """ | ||
2122 | 44 | self.config = config | ||
2123 | 45 | self.api = config.api | ||
2124 | 46 | self.settings = config.settings() | ||
2125 | 47 | if logger is None: | ||
2126 | 48 | logger = clogger.Logger() | ||
2127 | 49 | self.logger = logger | ||
2128 | 50 | |||
2129 | 51 | def run(self,adduser=None,addgroup=None,removeuser=None,removegroup=None): | ||
2130 | 52 | """ | ||
2131 | 53 | Automate setfacl commands | ||
2132 | 54 | """ | ||
2133 | 55 | |||
2134 | 56 | ok = False | ||
2135 | 57 | if adduser: | ||
2136 | 58 | ok = True | ||
2137 | 59 | self.modacl(True,True,adduser) | ||
2138 | 60 | if addgroup: | ||
2139 | 61 | ok = True | ||
2140 | 62 | self.modacl(True,False,addgroup) | ||
2141 | 63 | if removeuser: | ||
2142 | 64 | ok = True | ||
2143 | 65 | self.modacl(False,True,removeuser) | ||
2144 | 66 | if removegroup: | ||
2145 | 67 | ok = True | ||
2146 | 68 | self.modacl(False,False,removegroup) | ||
2147 | 69 | if not ok: | ||
2148 | 70 | raise CX("no arguments specified, nothing to do") | ||
2149 | 71 | |||
2150 | 72 | def modacl(self,isadd,isuser,who): | ||
2151 | 73 | |||
2152 | 74 | webdir = self.settings.webdir | ||
2153 | 75 | snipdir = self.settings.snippetsdir | ||
2154 | 76 | tftpboot = utils.tftpboot_location() | ||
2155 | 77 | |||
2156 | 78 | PROCESS_DIRS = { | ||
2157 | 79 | "/var/log/cobbler" : "rwx", | ||
2158 | 80 | "/var/log/cobbler/tasks" : "rwx", | ||
2159 | 81 | "/var/lib/cobbler" : "rwx", | ||
2160 | 82 | "/etc/cobbler" : "rwx", | ||
2161 | 83 | tftpboot : "rwx", | ||
2162 | 84 | "/var/lib/cobbler/triggers" : "rwx" | ||
2163 | 85 | } | ||
2164 | 86 | if not snipdir.startswith("/var/lib/cobbler/"): | ||
2165 | 87 | PROCESS_DIRS[snipdir] = "r" | ||
2166 | 88 | |||
2167 | 89 | cmd = "-R" | ||
2168 | 90 | |||
2169 | 91 | if isadd: | ||
2170 | 92 | cmd = "%s -m" % cmd | ||
2171 | 93 | else: | ||
2172 | 94 | cmd = "%s -x" % cmd | ||
2173 | 95 | |||
2174 | 96 | if isuser: | ||
2175 | 97 | cmd = "%s u:%s" % (cmd,who) | ||
2176 | 98 | else: | ||
2177 | 99 | cmd = "%s g:%s" % (cmd,who) | ||
2178 | 100 | |||
2179 | 101 | for d in PROCESS_DIRS: | ||
2180 | 102 | how = PROCESS_DIRS[d] | ||
2181 | 103 | if isadd: | ||
2182 | 104 | cmd2 = "%s:%s" % (cmd,how) | ||
2183 | 105 | else: | ||
2184 | 106 | cmd2 = cmd | ||
2185 | 107 | |||
2186 | 108 | cmd2 = "%s %s" % (cmd2,d) | ||
2187 | 109 | rc = utils.subprocess_call(self.logger,"setfacl -d %s" % cmd2,shell=True) | ||
2188 | 110 | if not rc == 0: | ||
2189 | 111 | utils.die(self.logger,"command failed") | ||
2190 | 112 | rc = utils.subprocess_call(self.logger,"setfacl %s" % cmd2,shell=True) | ||
2191 | 113 | if not rc == 0: | ||
2192 | 114 | utils.die(self.logger,"command failed") | ||
2193 | 115 | |||
2194 | 116 | |||
2195 | 117 | |||
2196 | 118 | |||
2197 | 119 | |||
2198 | 120 | |||
2199 | 0 | 121 | ||
2200 | === added file 'cobbler/action_buildiso.py' | |||
2201 | --- cobbler/action_buildiso.py 1970-01-01 00:00:00 +0000 | |||
2202 | +++ cobbler/action_buildiso.py 2011-03-11 21:10:49 +0000 | |||
2203 | @@ -0,0 +1,447 @@ | |||
2204 | 1 | """ | ||
2205 | 2 | Builds non-live bootable CD's that have PXE-equivalent behavior | ||
2206 | 3 | for all cobbler profiles currently in memory. | ||
2207 | 4 | |||
2208 | 5 | Copyright 2006-2009, Red Hat, Inc | ||
2209 | 6 | Michael DeHaan <mdehaan@redhat.com> | ||
2210 | 7 | |||
2211 | 8 | This program is free software; you can redistribute it and/or modify | ||
2212 | 9 | it under the terms of the GNU General Public License as published by | ||
2213 | 10 | the Free Software Foundation; either version 2 of the License, or | ||
2214 | 11 | (at your option) any later version. | ||
2215 | 12 | |||
2216 | 13 | This program is distributed in the hope that it will be useful, | ||
2217 | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2218 | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2219 | 16 | GNU General Public License for more details. | ||
2220 | 17 | |||
2221 | 18 | You should have received a copy of the GNU General Public License | ||
2222 | 19 | along with this program; if not, write to the Free Software | ||
2223 | 20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
2224 | 21 | 02110-1301 USA | ||
2225 | 22 | """ | ||
2226 | 23 | |||
2227 | 24 | import os | ||
2228 | 25 | import os.path | ||
2229 | 26 | import shutil | ||
2230 | 27 | import sys | ||
2231 | 28 | import traceback | ||
2232 | 29 | import shutil | ||
2233 | 30 | import re | ||
2234 | 31 | |||
2235 | 32 | import utils | ||
2236 | 33 | from cexceptions import * | ||
2237 | 34 | from utils import _ | ||
2238 | 35 | import clogger | ||
2239 | 36 | |||
2240 | 37 | # FIXME: lots of overlap with pxegen.py, should consolidate | ||
2241 | 38 | # FIXME: disable timeouts and remove local boot for this? | ||
2242 | 39 | HEADER = """ | ||
2243 | 40 | |||
2244 | 41 | DEFAULT menu | ||
2245 | 42 | PROMPT 0 | ||
2246 | 43 | MENU TITLE Cobbler | http://cobbler.et.redhat.com | ||
2247 | 44 | TIMEOUT 200 | ||
2248 | 45 | TOTALTIMEOUT 6000 | ||
2249 | 46 | ONTIMEOUT local | ||
2250 | 47 | |||
2251 | 48 | LABEL local | ||
2252 | 49 | MENU LABEL (local) | ||
2253 | 50 | MENU DEFAULT | ||
2254 | 51 | KERNEL chain.c32 | ||
2255 | 52 | APPEND hd0 0 | ||
2256 | 53 | |||
2257 | 54 | """ | ||
2258 | 55 | |||
2259 | 56 | class BuildIso: | ||
2260 | 57 | """ | ||
2261 | 58 | Handles conversion of internal state to the tftpboot tree layout | ||
2262 | 59 | """ | ||
2263 | 60 | |||
2264 | 61 | def __init__(self,config,verbose=False,logger=None): | ||
2265 | 62 | """ | ||
2266 | 63 | Constructor | ||
2267 | 64 | """ | ||
2268 | 65 | self.verbose = verbose | ||
2269 | 66 | self.config = config | ||
2270 | 67 | self.api = config.api | ||
2271 | 68 | self.distros = config.distros() | ||
2272 | 69 | self.profiles = config.profiles() | ||
2273 | 70 | self.systems = config.systems() | ||
2274 | 71 | self.distros = config.distros() | ||
2275 | 72 | self.distmap = {} | ||
2276 | 73 | self.distctr = 0 | ||
2277 | 74 | self.source = "" | ||
2278 | 75 | if logger is None: | ||
2279 | 76 | logger = clogger.Logger() | ||
2280 | 77 | self.logger = logger | ||
2281 | 78 | |||
2282 | 79 | |||
2283 | 80 | def make_shorter(self,distname): | ||
2284 | 81 | if self.distmap.has_key(distname): | ||
2285 | 82 | return self.distmap[distname] | ||
2286 | 83 | else: | ||
2287 | 84 | self.distctr = self.distctr + 1 | ||
2288 | 85 | self.distmap[distname] = str(self.distctr) | ||
2289 | 86 | return str(self.distctr) | ||
2290 | 87 | |||
2291 | 88 | |||
2292 | 89 | def generate_netboot_iso(self,imagesdir,isolinuxdir,profiles=None,systems=None,exclude_dns=None): | ||
2293 | 90 | self.logger.info("copying kernels and initrds for profiles") | ||
2294 | 91 | # copy all images in included profiles to images dir | ||
2295 | 92 | for profile in self.api.profiles(): | ||
2296 | 93 | use_this = True | ||
2297 | 94 | if profiles is not None: | ||
2298 | 95 | which_profiles = profiles.split(",") | ||
2299 | 96 | if not profile.name in which_profiles: | ||
2300 | 97 | use_this = False | ||
2301 | 98 | |||
2302 | 99 | if use_this: | ||
2303 | 100 | dist = profile.get_conceptual_parent() | ||
2304 | 101 | if dist.name.lower().find("-xen") != -1: | ||
2305 | 102 | self.logger.info("skipping Xen distro: %s" % dist.name) | ||
2306 | 103 | continue | ||
2307 | 104 | distname = self.make_shorter(dist.name) | ||
2308 | 105 | # buildisodir/isolinux/$distro/vmlinuz, initrd.img | ||
2309 | 106 | # FIXME: this will likely crash on non-Linux breeds | ||
2310 | 107 | f1 = os.path.join(isolinuxdir, "%s.krn" % distname) | ||
2311 | 108 | f2 = os.path.join(isolinuxdir, "%s.img" % distname) | ||
2312 | 109 | if not os.path.exists(dist.kernel): | ||
2313 | 110 | utils.die(self.logger,"path does not exist: %s" % dist.kernel) | ||
2314 | 111 | if not os.path.exists(dist.initrd): | ||
2315 | 112 | utils.die(self.logger,"path does not exist: %s" % dist.initrd) | ||
2316 | 113 | shutil.copyfile(dist.kernel, f1) | ||
2317 | 114 | shutil.copyfile(dist.initrd, f2) | ||
2318 | 115 | |||
2319 | 116 | if systems is not None: | ||
2320 | 117 | self.logger.info("copying kernels and initrds for systems") | ||
2321 | 118 | # copy all images in included profiles to images dir | ||
2322 | 119 | for system in self.api.systems(): | ||
2323 | 120 | if system.name in systems: | ||
2324 | 121 | profile = system.get_conceptual_parent() | ||
2325 | 122 | dist = profile.get_conceptual_parent() | ||
2326 | 123 | if dist.name.find("-xen") != -1: | ||
2327 | 124 | continue | ||
2328 | 125 | distname = self.make_shorter(dist.name) | ||
2329 | 126 | # buildisodir/isolinux/$distro/vmlinuz, initrd.img | ||
2330 | 127 | # FIXME: this will likely crash on non-Linux breeds | ||
2331 | 128 | shutil.copyfile(dist.kernel, os.path.join(isolinuxdir, "%s.krn" % distname)) | ||
2332 | 129 | shutil.copyfile(dist.initrd, os.path.join(isolinuxdir, "%s.img" % distname)) | ||
2333 | 130 | |||
2334 | 131 | self.logger.info("generating a isolinux.cfg") | ||
2335 | 132 | isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") | ||
2336 | 133 | cfg = open(isolinuxcfg, "w+") | ||
2337 | 134 | cfg.write(HEADER) # fixme, use template | ||
2338 | 135 | |||
2339 | 136 | self.logger.info("generating profile list") | ||
2340 | 137 | #sort the profiles | ||
2341 | 138 | profile_list = [profile for profile in self.profiles] | ||
2342 | 139 | def sort_name(a,b): | ||
2343 | 140 | return cmp(a.name,b.name) | ||
2344 | 141 | profile_list.sort(sort_name) | ||
2345 | 142 | |||
2346 | 143 | for profile in profile_list: | ||
2347 | 144 | use_this = True | ||
2348 | 145 | if profiles is not None: | ||
2349 | 146 | which_profiles = profiles.split(",") | ||
2350 | 147 | if not profile.name in which_profiles: | ||
2351 | 148 | use_this = False | ||
2352 | 149 | |||
2353 | 150 | if use_this: | ||
2354 | 151 | dist = profile.get_conceptual_parent() | ||
2355 | 152 | if dist.name.find("-xen") != -1: | ||
2356 | 153 | continue | ||
2357 | 154 | data = utils.blender(self.api, True, profile) | ||
2358 | 155 | distname = self.make_shorter(dist.name) | ||
2359 | 156 | |||
2360 | 157 | cfg.write("\n") | ||
2361 | 158 | cfg.write("LABEL %s\n" % profile.name) | ||
2362 | 159 | cfg.write(" MENU LABEL %s\n" % profile.name) | ||
2363 | 160 | cfg.write(" kernel %s.krn\n" % distname) | ||
2364 | 161 | |||
2365 | 162 | if data["kickstart"].startswith("/"): | ||
2366 | 163 | data["kickstart"] = "http://%s:%s/cblr/svc/op/ks/profile/%s" % ( | ||
2367 | 164 | data["server"], | ||
2368 | 165 | self.api.settings().http_port, | ||
2369 | 166 | profile.name | ||
2370 | 167 | ) | ||
2371 | 168 | |||
2372 | 169 | append_line = " append initrd=%s.img" % distname | ||
2373 | 170 | append_line = append_line + " ks=%s " % data["kickstart"] | ||
2374 | 171 | append_line = append_line + " %s\n" % data["kernel_options"] | ||
2375 | 172 | |||
2376 | 173 | length=len(append_line) | ||
2377 | 174 | if length>254: | ||
2378 | 175 | self.logger.warning("append line length is greater than 254 chars: (%s chars)" % length) | ||
2379 | 176 | |||
2380 | 177 | cfg.write(append_line) | ||
2381 | 178 | |||
2382 | 179 | if systems is not None: | ||
2383 | 180 | self.logger.info("generating system list") | ||
2384 | 181 | |||
2385 | 182 | cfg.write("\nMENU SEPARATOR\n") | ||
2386 | 183 | |||
2387 | 184 | #sort the systems | ||
2388 | 185 | system_list = [system for system in self.systems] | ||
2389 | 186 | def sort_name(a,b): | ||
2390 | 187 | return cmp(a.name,b.name) | ||
2391 | 188 | system_list.sort(sort_name) | ||
2392 | 189 | |||
2393 | 190 | for system in system_list: | ||
2394 | 191 | use_this = False | ||
2395 | 192 | if systems is not None: | ||
2396 | 193 | which_systems = systems.split(",") | ||
2397 | 194 | if system.name in which_systems: | ||
2398 | 195 | use_this = True | ||
2399 | 196 | |||
2400 | 197 | if use_this: | ||
2401 | 198 | profile = system.get_conceptual_parent() | ||
2402 | 199 | dist = profile.get_conceptual_parent() | ||
2403 | 200 | if dist.name.find("-xen") != -1: | ||
2404 | 201 | continue | ||
2405 | 202 | data = utils.blender(self.api, True, system) | ||
2406 | 203 | distname = self.make_shorter(dist.name) | ||
2407 | 204 | |||
2408 | 205 | cfg.write("\n") | ||
2409 | 206 | cfg.write("LABEL %s\n" % system.name) | ||
2410 | 207 | cfg.write(" MENU LABEL %s\n" % system.name) | ||
2411 | 208 | cfg.write(" kernel %s.krn\n" % distname) | ||
2412 | 209 | |||
2413 | 210 | if data["kickstart"].startswith("/"): | ||
2414 | 211 | data["kickstart"] = "http://%s:%s/cblr/svc/op/ks/system/%s" % ( | ||
2415 | 212 | data["server"], | ||
2416 | 213 | self.api.settings().http_port, | ||
2417 | 214 | system.name | ||
2418 | 215 | ) | ||
2419 | 216 | |||
2420 | 217 | append_line = " append initrd=%s.img" % distname | ||
2421 | 218 | append_line = append_line + " ks=%s" % data["kickstart"] | ||
2422 | 219 | append_line = append_line + " %s" % data["kernel_options"] | ||
2423 | 220 | |||
2424 | 221 | # add network info to avoid DHCP only if it is available | ||
2425 | 222 | |||
2426 | 223 | if data.has_key("bonding_master_eth0") and data["bonding_master_eth0"] != "": | ||
2427 | 224 | primary_interface = data["bonding_master_eth0"] | ||
2428 | 225 | else: | ||
2429 | 226 | primary_interface = "eth0" | ||
2430 | 227 | |||
2431 | 228 | # check if ksdevice entry exists and use that for network info | ||
2432 | 229 | |||
2433 | 230 | blended = utils.blender(self.api, False, system) # don't collapse | ||
2434 | 231 | |||
2435 | 232 | if blended["kernel_options"].has_key("ksdevice") and blended["kernel_options"]["ksdevice"] != "": | ||
2436 | 233 | ksdevice = blended["kernel_options"]["ksdevice"] | ||
2437 | 234 | self.logger.info(" - ksdevice %s set for system %s" % (ksdevice,system.name)) | ||
2438 | 235 | |||
2439 | 236 | if data.has_key("ip_address_" + ksdevice ) and data["ip_address_" + ksdevice] != "": | ||
2440 | 237 | primary_interface = ksdevice | ||
2441 | 238 | else: | ||
2442 | 239 | |||
2443 | 240 | for (obj_iname, obj_interface) in data['interfaces'].iteritems(): | ||
2444 | 241 | mac = obj_interface["mac_address"].upper() | ||
2445 | 242 | ksdevice_mac = ksdevice.upper() | ||
2446 | 243 | |||
2447 | 244 | if mac == ksdevice_mac: | ||
2448 | 245 | primary_interface = obj_iname | ||
2449 | 246 | |||
2450 | 247 | |||
2451 | 248 | if data.has_key("ip_address_" + primary_interface) and data["ip_address_" + primary_interface] != "": | ||
2452 | 249 | append_line = append_line + " ip=%s" % data["ip_address_" + primary_interface] | ||
2453 | 250 | |||
2454 | 251 | if data.has_key("subnet_" + primary_interface) and data["subnet_" + primary_interface] != "": | ||
2455 | 252 | append_line = append_line + " netmask=%s" % data["subnet_" + primary_interface] | ||
2456 | 253 | |||
2457 | 254 | if data.has_key("gateway") and data["gateway"] != "": | ||
2458 | 255 | append_line = append_line + " gateway=%s" % data["gateway"] | ||
2459 | 256 | |||
2460 | 257 | if not exclude_dns and data.has_key("name_servers") and data["name_servers"]: | ||
2461 | 258 | append_line = append_line + " dns=%s\n" % ",".join(data["name_servers"]) | ||
2462 | 259 | |||
2463 | 260 | length=len(append_line) | ||
2464 | 261 | if length > 254: | ||
2465 | 262 | self.logger.warning("append line length is greater than 254 chars: (%s chars)" % length) | ||
2466 | 263 | |||
2467 | 264 | cfg.write(append_line) | ||
2468 | 265 | |||
2469 | 266 | self.logger.info("done writing config") | ||
2470 | 267 | cfg.write("\n") | ||
2471 | 268 | cfg.write("MENU END\n") | ||
2472 | 269 | cfg.close() | ||
2473 | 270 | |||
2474 | 271 | |||
2475 | 272 | def generate_standalone_iso(self,imagesdir,isolinuxdir,distname,filesource): | ||
2476 | 273 | |||
2477 | 274 | # Get the distro object for the requested distro | ||
2478 | 275 | # and then get all of its descendants (profiles/sub-profiles/systems) | ||
2479 | 276 | distro = self.api.find_distro(distname) | ||
2480 | 277 | if distro is None: | ||
2481 | 278 | utils.die(self.logger,"distro %s was not found, aborting" % distname) | ||
2482 | 279 | descendants = distro.get_descendants() | ||
2483 | 280 | |||
2484 | 281 | if filesource is None: | ||
2485 | 282 | # Try to determine the source from the distro kernel path | ||
2486 | 283 | self.logger.debug("trying to locate source for distro") | ||
2487 | 284 | found_source = False | ||
2488 | 285 | (source_head, source_tail) = os.path.split(distro.kernel) | ||
2489 | 286 | while source_tail != '': | ||
2490 | 287 | if source_head == os.path.join(self.api.settings().webdir, "ks_mirror"): | ||
2491 | 288 | filesource = os.path.join(source_head, source_tail) | ||
2492 | 289 | found_source = True | ||
2493 | 290 | self.logger.debug("found source in %s" % filesource) | ||
2494 | 291 | break | ||
2495 | 292 | (source_head, source_tail) = os.path.split(source_head) | ||
2496 | 293 | # Can't find the source, raise an error | ||
2497 | 294 | if not found_source: | ||
2498 | 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") | ||
2499 | 296 | |||
2500 | 297 | self.logger.info("copying kernels and initrds for standalone distro") | ||
2501 | 298 | # buildisodir/isolinux/$distro/vmlinuz, initrd.img | ||
2502 | 299 | # FIXME: this will likely crash on non-Linux breeds | ||
2503 | 300 | f1 = os.path.join(isolinuxdir, "vmlinuz") | ||
2504 | 301 | f2 = os.path.join(isolinuxdir, "initrd.img") | ||
2505 | 302 | if not os.path.exists(distro.kernel): | ||
2506 | 303 | utils.die(self.logger,"path does not exist: %s" % distro.kernel) | ||
2507 | 304 | if not os.path.exists(distro.initrd): | ||
2508 | 305 | utils.die(self.logger,"path does not exist: %s" % distro.initrd) | ||
2509 | 306 | shutil.copyfile(distro.kernel, f1) | ||
2510 | 307 | shutil.copyfile(distro.initrd, f2) | ||
2511 | 308 | |||
2512 | 309 | cmd = "rsync -rlptgu --exclude=boot.cat --exclude=TRANS.TBL --exclude=isolinux/ %s/ %s/../" % (filesource, isolinuxdir) | ||
2513 | 310 | self.logger.info("- copying distro %s files (%s)" % (distname,cmd)) | ||
2514 | 311 | rc = utils.subprocess_call(self.logger, cmd, shell=True) | ||
2515 | 312 | if rc: | ||
2516 | 313 | utils.die(self.logger,"rsync of files failed") | ||
2517 | 314 | |||
2518 | 315 | self.logger.info("generating a isolinux.cfg") | ||
2519 | 316 | isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") | ||
2520 | 317 | cfg = open(isolinuxcfg, "w+") | ||
2521 | 318 | cfg.write(HEADER) # fixme, use template | ||
2522 | 319 | |||
2523 | 320 | for descendant in descendants: | ||
2524 | 321 | data = utils.blender(self.api, True, descendant) | ||
2525 | 322 | |||
2526 | 323 | cfg.write("\n") | ||
2527 | 324 | cfg.write("LABEL %s\n" % descendant.name) | ||
2528 | 325 | cfg.write(" MENU LABEL %s\n" % descendant.name) | ||
2529 | 326 | cfg.write(" kernel vmlinuz\n") | ||
2530 | 327 | |||
2531 | 328 | data["kickstart"] = "cdrom:/isolinux/ks-%s.cfg" % descendant.name | ||
2532 | 329 | |||
2533 | 330 | append_line = " append initrd=initrd.img" | ||
2534 | 331 | append_line = append_line + " ks=%s " % data["kickstart"] | ||
2535 | 332 | append_line = append_line + " %s\n" % data["kernel_options"] | ||
2536 | 333 | |||
2537 | 334 | cfg.write(append_line) | ||
2538 | 335 | |||
2539 | 336 | if descendant.COLLECTION_TYPE == 'profile': | ||
2540 | 337 | kickstart_data = self.api.kickgen.generate_kickstart_for_profile(descendant.name) | ||
2541 | 338 | elif descendant.COLLECTION_TYPE == 'system': | ||
2542 | 339 | kickstart_data = self.api.kickgen.generate_kickstart_for_system(descendant.name) | ||
2543 | 340 | |||
2544 | 341 | cdregex = re.compile("url .*\n", re.IGNORECASE) | ||
2545 | 342 | kickstart_data = cdregex.sub("cdrom\n", kickstart_data) | ||
2546 | 343 | |||
2547 | 344 | ks_name = os.path.join(isolinuxdir, "ks-%s.cfg" % descendant.name) | ||
2548 | 345 | ks_file = open(ks_name, "w+") | ||
2549 | 346 | ks_file.write(kickstart_data) | ||
2550 | 347 | ks_file.close() | ||
2551 | 348 | |||
2552 | 349 | self.logger.info("done writing config") | ||
2553 | 350 | cfg.write("\n") | ||
2554 | 351 | cfg.write("MENU END\n") | ||
2555 | 352 | cfg.close() | ||
2556 | 353 | |||
2557 | 354 | return | ||
2558 | 355 | |||
2559 | 356 | |||
2560 | 357 | def run(self,iso=None,buildisodir=None,profiles=None,systems=None,distro=None,standalone=None,source=None,exclude_dns=None): | ||
2561 | 358 | |||
2562 | 359 | self.settings = self.config.settings() | ||
2563 | 360 | |||
2564 | 361 | # the distro option is for stand-alone builds only | ||
2565 | 362 | if not standalone and distro is not None: | ||
2566 | 363 | utils.die(self.logger,"The --distro option should only be used when creating a standalone ISO") | ||
2567 | 364 | # if building standalone, we only want --distro, | ||
2568 | 365 | # profiles/systems are disallowed | ||
2569 | 366 | if standalone: | ||
2570 | 367 | if profiles is not None or systems is not None: | ||
2571 | 368 | utils.die(self.logger,"When building a standalone ISO, use --distro only instead of --profiles/--systems") | ||
2572 | 369 | elif distro is None: | ||
2573 | 370 | utils.die(self.logger,"When building a standalone ISO, you must specify a --distro") | ||
2574 | 371 | if source != None and not os.path.exists(source): | ||
2575 | 372 | utils.die(self.logger,"The source specified (%s) does not exist" % source) | ||
2576 | 373 | |||
2577 | 374 | # if iso is none, create it in . as "kickstart.iso" | ||
2578 | 375 | if iso is None: | ||
2579 | 376 | iso = "kickstart.iso" | ||
2580 | 377 | |||
2581 | 378 | if buildisodir is None: | ||
2582 | 379 | buildisodir = self.settings.buildisodir | ||
2583 | 380 | else: | ||
2584 | 381 | if not os.path.isdir(buildisodir): | ||
2585 | 382 | utils.die(self.logger,"The --tempdir specified is not a directory") | ||
2586 | 383 | |||
2587 | 384 | (buildisodir_head,buildisodir_tail) = os.path.split(os.path.normpath(buildisodir)) | ||
2588 | 385 | if buildisodir_tail != "buildiso": | ||
2589 | 386 | buildisodir = os.path.join(buildisodir, "buildiso") | ||
2590 | 387 | |||
2591 | 388 | self.logger.info("using/creating buildisodir: %s" % buildisodir) | ||
2592 | 389 | if not os.path.exists(buildisodir): | ||
2593 | 390 | os.makedirs(buildisodir) | ||
2594 | 391 | else: | ||
2595 | 392 | shutil.rmtree(buildisodir) | ||
2596 | 393 | os.makedirs(buildisodir) | ||
2597 | 394 | |||
2598 | 395 | # if base of buildisodir does not exist, fail | ||
2599 | 396 | # create all profiles unless filtered by "profiles" | ||
2600 | 397 | |||
2601 | 398 | imagesdir = os.path.join(buildisodir, "images") | ||
2602 | 399 | isolinuxdir = os.path.join(buildisodir, "isolinux") | ||
2603 | 400 | |||
2604 | 401 | self.logger.info("building tree for isolinux") | ||
2605 | 402 | if not os.path.exists(imagesdir): | ||
2606 | 403 | os.makedirs(imagesdir) | ||
2607 | 404 | if not os.path.exists(isolinuxdir): | ||
2608 | 405 | os.makedirs(isolinuxdir) | ||
2609 | 406 | |||
2610 | 407 | self.logger.info("copying miscellaneous files") | ||
2611 | 408 | |||
2612 | 409 | isolinuxbin = "/usr/share/syslinux/isolinux.bin" | ||
2613 | 410 | if not os.path.exists(isolinuxbin): | ||
2614 | 411 | isolinuxbin = "/usr/lib/syslinux/isolinux.bin" | ||
2615 | 412 | |||
2616 | 413 | menu = "/usr/share/syslinux/menu.c32" | ||
2617 | 414 | if not os.path.exists(menu): | ||
2618 | 415 | menu = "/var/lib/cobbler/loaders/menu.c32" | ||
2619 | 416 | |||
2620 | 417 | chain = "/usr/share/syslinux/chain.c32" | ||
2621 | 418 | if not os.path.exists(chain): | ||
2622 | 419 | chain = "/usr/lib/syslinux/chain.c32" | ||
2623 | 420 | |||
2624 | 421 | files = [ isolinuxbin, menu, chain ] | ||
2625 | 422 | for f in files: | ||
2626 | 423 | if not os.path.exists(f): | ||
2627 | 424 | utils.die(self.logger,"Required file not found: %s" % f) | ||
2628 | 425 | else: | ||
2629 | 426 | utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f)), self.api) | ||
2630 | 427 | |||
2631 | 428 | if standalone: | ||
2632 | 429 | self.generate_standalone_iso(imagesdir,isolinuxdir,distro,source) | ||
2633 | 430 | else: | ||
2634 | 431 | self.generate_netboot_iso(imagesdir,isolinuxdir,profiles,systems,exclude_dns) | ||
2635 | 432 | |||
2636 | 433 | # removed --quiet | ||
2637 | 434 | cmd = "mkisofs -o %s -r -b isolinux/isolinux.bin -c isolinux/boot.cat" % iso | ||
2638 | 435 | cmd = cmd + " -no-emul-boot -boot-load-size 4" | ||
2639 | 436 | cmd = cmd + " -boot-info-table -V Cobbler\ Install -R -J -T %s" % buildisodir | ||
2640 | 437 | |||
2641 | 438 | rc = utils.subprocess_call(self.logger, cmd, shell=True) | ||
2642 | 439 | if rc != 0: | ||
2643 | 440 | utils.die(self.logger,"mkisofs failed") | ||
2644 | 441 | |||
2645 | 442 | self.logger.info("ISO build complete") | ||
2646 | 443 | self.logger.info("You may wish to delete: %s" % buildisodir) | ||
2647 | 444 | self.logger.info("The output file is: %s" % iso) | ||
2648 | 445 | |||
2649 | 446 | return True | ||
2650 | 447 | |||
2651 | 0 | 448 | ||
2652 | === added file 'cobbler/action_check.py' | |||
2653 | --- cobbler/action_check.py 1970-01-01 00:00:00 +0000 | |||
2654 | +++ cobbler/action_check.py 2011-03-11 21:10:49 +0000 | |||
2655 | @@ -0,0 +1,482 @@ | |||
2656 | 1 | """ | ||
2657 | 2 | Validates whether the system is reasonably well configured for | ||
2658 | 3 | serving up content. This is the code behind 'cobbler check'. | ||
2659 | 4 | |||
2660 | 5 | Copyright 2006-2009, Red Hat, Inc | ||
2661 | 6 | Michael DeHaan <mdehaan@redhat.com> | ||
2662 | 7 | |||
2663 | 8 | This program is free software; you can redistribute it and/or modify | ||
2664 | 9 | it under the terms of the GNU General Public License as published by | ||
2665 | 10 | the Free Software Foundation; either version 2 of the License, or | ||
2666 | 11 | (at your option) any later version. | ||
2667 | 12 | |||
2668 | 13 | This program is distributed in the hope that it will be useful, | ||
2669 | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2670 | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2671 | 16 | GNU General Public License for more details. | ||
2672 | 17 | |||
2673 | 18 | You should have received a copy of the GNU General Public License | ||
2674 | 19 | along with this program; if not, write to the Free Software | ||
2675 | 20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
2676 | 21 | 02110-1301 USA | ||
2677 | 22 | """ | ||
2678 | 23 | |||
2679 | 24 | import os | ||
2680 | 25 | import re | ||
2681 | 26 | import action_sync | ||
2682 | 27 | import utils | ||
2683 | 28 | import glob | ||
2684 | 29 | from utils import _ | ||
2685 | 30 | import clogger | ||
2686 | 31 | |||
2687 | 32 | class BootCheck: | ||
2688 | 33 | |||
2689 | 34 | def __init__(self,config,logger=None): | ||
2690 | 35 | """ | ||
2691 | 36 | Constructor | ||
2692 | 37 | """ | ||
2693 | 38 | self.config = config | ||
2694 | 39 | self.settings = config.settings() | ||
2695 | 40 | if logger is None: | ||
2696 | 41 | logger = clogger.Logger() | ||
2697 | 42 | self.logger = logger | ||
2698 | 43 | |||
2699 | 44 | |||
2700 | 45 | def run(self): | ||
2701 | 46 | """ | ||
2702 | 47 | Returns None if there are no errors, otherwise returns a list | ||
2703 | 48 | of things to correct prior to running application 'for real'. | ||
2704 | 49 | (The CLI usage is "cobbler check" before "cobbler sync") | ||
2705 | 50 | """ | ||
2706 | 51 | status = [] | ||
2707 | 52 | self.checked_dist = utils.check_dist() | ||
2708 | 53 | self.check_name(status) | ||
2709 | 54 | self.check_selinux(status) | ||
2710 | 55 | if self.settings.manage_dhcp: | ||
2711 | 56 | mode = self.config.api.get_sync().dhcp.what() | ||
2712 | 57 | if mode == "isc": | ||
2713 | 58 | self.check_dhcpd_bin(status) | ||
2714 | 59 | self.check_dhcpd_conf(status) | ||
2715 | 60 | self.check_service(status,"dhcpd") | ||
2716 | 61 | elif mode == "dnsmasq": | ||
2717 | 62 | self.check_dnsmasq_bin(status) | ||
2718 | 63 | self.check_service(status,"dnsmasq") | ||
2719 | 64 | |||
2720 | 65 | if self.settings.manage_dns: | ||
2721 | 66 | mode = self.config.api.get_sync().dns.what() | ||
2722 | 67 | if mode == "bind": | ||
2723 | 68 | self.check_bind_bin(status) | ||
2724 | 69 | self.check_service(status,"named") | ||
2725 | 70 | elif mode == "dnsmasq" and not self.settings.manage_dhcp: | ||
2726 | 71 | self.check_dnsmasq_bin(status) | ||
2727 | 72 | self.check_service(status,"dnsmasq") | ||
2728 | 73 | |||
2729 | 74 | mode = self.config.api.get_sync().tftpd.what() | ||
2730 | 75 | if mode == "in_tftpd": | ||
2731 | 76 | self.check_tftpd_bin(status) | ||
2732 | 77 | self.check_tftpd_dir(status) | ||
2733 | 78 | self.check_tftpd_conf(status) | ||
2734 | 79 | elif mode == "tftpd_py": | ||
2735 | 80 | self.check_ctftpd_bin(status) | ||
2736 | 81 | self.check_ctftpd_dir(status) | ||
2737 | 82 | self.check_ctftpd_conf(status) | ||
2738 | 83 | |||
2739 | 84 | self.check_service(status, "cobblerd") | ||
2740 | 85 | |||
2741 | 86 | self.check_bootloaders(status) | ||
2742 | 87 | self.check_rsync_conf(status) | ||
2743 | 88 | self.check_httpd(status) | ||
2744 | 89 | self.check_iptables(status) | ||
2745 | 90 | self.check_yum(status) | ||
2746 | 91 | self.check_debmirror(status) | ||
2747 | 92 | self.check_for_ksvalidator(status) | ||
2748 | 93 | self.check_for_default_password(status) | ||
2749 | 94 | self.check_for_unreferenced_repos(status) | ||
2750 | 95 | self.check_for_unsynced_repos(status) | ||
2751 | 96 | self.check_for_cman(status) | ||
2752 | 97 | |||
2753 | 98 | return status | ||
2754 | 99 | |||
2755 | 100 | def check_for_ksvalidator(self, status): | ||
2756 | 101 | if self.checked_dist in ["debian", "ubuntu"]: | ||
2757 | 102 | return | ||
2758 | 103 | |||
2759 | 104 | if not os.path.exists("/usr/bin/ksvalidator"): | ||
2760 | 105 | status.append("ksvalidator was not found, install pykickstart") | ||
2761 | 106 | |||
2762 | 107 | return True | ||
2763 | 108 | |||
2764 | 109 | def check_for_cman(self, status): | ||
2765 | 110 | # not doing rpm -q here to be cross-distro friendly | ||
2766 | 111 | if not os.path.exists("/sbin/fence_ilo") and not os.path.exists("/usr/sbin/fence_ilo"): | ||
2767 | 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") | ||
2768 | 113 | return True | ||
2769 | 114 | |||
2770 | 115 | def check_service(self, status, which, notes=""): | ||
2771 | 116 | if notes != "": | ||
2772 | 117 | notes = " (NOTE: %s)" % notes | ||
2773 | 118 | rc = 0 | ||
2774 | 119 | if self.checked_dist == "redhat" or self.checked_dist == "suse": | ||
2775 | 120 | if os.path.exists("/etc/rc.d/init.d/%s" % which): | ||
2776 | 121 | rc = utils.subprocess_call(self.logger,"/sbin/service %s status > /dev/null 2>/dev/null" % which, shell=True) | ||
2777 | 122 | if rc != 0: | ||
2778 | 123 | status.append(_("service %s is not running%s") % (which,notes)) | ||
2779 | 124 | return False | ||
2780 | 125 | elif self.checked_dist in ["debian", "ubuntu"]: | ||
2781 | 126 | # we still use /etc/init.d | ||
2782 | 127 | if os.path.exists("/etc/init.d/%s" % which): | ||
2783 | 128 | rc = utils.subprocess_call(self.logger,"/etc/init.d/%s status /dev/null 2>/dev/null" % which, shell=True) | ||
2784 | 129 | if rc != 0: | ||
2785 | 130 | status.append(_("service %s is not running%s") % which,notes) | ||
2786 | 131 | return False | ||
2787 | 132 | elif self.checked_dist == "ubuntu": | ||
2788 | 133 | if os.path.exists("/etc/init/%s.conf" % which): | ||
2789 | 134 | rc = utils.subprocess_call(self.logger,"status %s > /dev/null 2>&1" % which, shell=True) | ||
2790 | 135 | if rc != 0: | ||
2791 | 136 | status.append(_("service %s is not running%s") % (which,notes)) | ||
2792 | 137 | else: | ||
2793 | 138 | status.append(_("Unknown distribution type, cannot check for running service %s" % which)) | ||
2794 | 139 | return False | ||
2795 | 140 | return True | ||
2796 | 141 | |||
2797 | 142 | def check_iptables(self, status): | ||
2798 | 143 | if os.path.exists("/etc/rc.d/init.d/iptables"): | ||
2799 | 144 | rc = utils.subprocess_call(self.logger,"/sbin/service iptables status >/dev/null 2>/dev/null", shell=True) | ||
2800 | 145 | if rc == 0: | ||
2801 | 146 | status.append(_("since iptables may be running, ensure 69, 80, and %(xmlrpc)s are unblocked") % { "xmlrpc" : self.settings.xmlrpc_port }) | ||
2802 | 147 | |||
2803 | 148 | def check_yum(self,status): | ||
2804 | 149 | if self.checked_dist in ["debian", "ubuntu"]: | ||
2805 | 150 | return | ||
2806 | 151 | |||
2807 | 152 | if not os.path.exists("/usr/bin/createrepo"): | ||
2808 | 153 | status.append(_("createrepo package is not installed, needed for cobbler import and cobbler reposync, install createrepo?")) | ||
2809 | 154 | if not os.path.exists("/usr/bin/reposync"): | ||
2810 | 155 | status.append(_("reposync is not installed, need for cobbler reposync, install/upgrade yum-utils?")) | ||
2811 | 156 | if not os.path.exists("/usr/bin/yumdownloader"): | ||
2812 | 157 | status.append(_("yumdownloader is not installed, needed for cobbler repo add with --rpm-list parameter, install/upgrade yum-utils?")) | ||
2813 | 158 | if self.settings.reposync_flags.find("-l"): | ||
2814 | 159 | if self.checked_dist == "redhat" or self.checked_dist == "suse": | ||
2815 | 160 | yum_utils_ver = utils.subprocess_get(self.logger,"/usr/bin/rpmquery --queryformat=%{VERSION} yum-utils", shell=True) | ||
2816 | 161 | if yum_utils_ver < "1.1.17": | ||
2817 | 162 | status.append(_("yum-utils need to be at least version 1.1.17 for reposync -l, current version is %s") % yum_utils_ver ) | ||
2818 | 163 | |||
2819 | 164 | def check_debmirror(self,status): | ||
2820 | 165 | if not os.path.exists("/usr/bin/debmirror"): | ||
2821 | 166 | status.append(_("debmirror package is not installed, it will be required to manage debian deployments and repositories")) | ||
2822 | 167 | if os.path.exists("/etc/debmirror.conf"): | ||
2823 | 168 | f = open("/etc/debmirror.conf") | ||
2824 | 169 | re_dists = re.compile(r'@dists=') | ||
2825 | 170 | re_arches = re.compile(r'@arches=') | ||
2826 | 171 | for line in f.readlines(): | ||
2827 | 172 | if re_dists.search(line) and not line.strip().startswith("#"): | ||
2828 | 173 | status.append(_("comment 'dists' on /etc/debmirror.conf for proper debian support")) | ||
2829 | 174 | if re_arches.search(line) and not line.strip().startswith("#"): | ||
2830 | 175 | status.append(_("comment 'arches' on /etc/debmirror.conf for proper debian support")) | ||
2831 | 176 | |||
2832 | 177 | |||
2833 | 178 | def check_name(self,status): | ||
2834 | 179 | """ | ||
2835 | 180 | If the server name in the config file is still set to localhost | ||
2836 | 181 | kickstarts run from koan will not have proper kernel line | ||
2837 | 182 | parameters. | ||
2838 | 183 | """ | ||
2839 | 184 | if self.settings.server == "127.0.0.1": | ||
2840 | 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.")) | ||
2841 | 186 | if self.settings.next_server == "127.0.0.1": | ||
2842 | 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.")) | ||
2843 | 188 | |||
2844 | 189 | def check_selinux(self,status): | ||
2845 | 190 | """ | ||
2846 | 191 | Suggests various SELinux rules changes to run Cobbler happily with | ||
2847 | 192 | SELinux in enforcing mode. FIXME: this method could use some | ||
2848 | 193 | refactoring in the future. | ||
2849 | 194 | """ | ||
2850 | 195 | if self.checked_dist in ["debian", "ubuntu"]: | ||
2851 | 196 | return | ||
2852 | 197 | |||
2853 | 198 | enabled = self.config.api.is_selinux_enabled() | ||
2854 | 199 | if enabled: | ||
2855 | 200 | data2 = utils.subprocess_get(self.logger,"/usr/sbin/getsebool -a",shell=True) | ||
2856 | 201 | for line in data2.split("\n"): | ||
2857 | 202 | if line.find("httpd_can_network_connect ") != -1: | ||
2858 | 203 | if line.find("off") != -1: | ||
2859 | 204 | status.append(_("Must enable a selinux boolean to enable vital web services components, run: setsebool -P httpd_can_network_connect true")) | ||
2860 | 205 | if line.find("rsync_disable_trans ") != -1: | ||
2861 | 206 | if line.find("on") != -1: | ||
2862 | 207 | status.append(_("Must enable the cobbler import and replicate commands, run: setsebool -P rsync_disable_trans=1")) | ||
2863 | 208 | |||
2864 | 209 | data3 = utils.subprocess_get(self.logger,"/usr/sbin/semanage fcontext -l | grep public_content_t",shell=True) | ||
2865 | 210 | |||
2866 | 211 | rule1 = False | ||
2867 | 212 | rule2 = False | ||
2868 | 213 | rule3 = False | ||
2869 | 214 | selinux_msg = "/usr/sbin/semanage fcontext -a -t public_content_t \"%s\"" | ||
2870 | 215 | for line in data3.split("\n"): | ||
2871 | 216 | if line.startswith("/tftpboot/.*"): | ||
2872 | 217 | rule1 = True | ||
2873 | 218 | if line.startswith("/var/lib/tftpboot/.*"): | ||
2874 | 219 | rule2 = True | ||
2875 | 220 | if line.startswith("/var/www/cobbler/images/.*"): | ||
2876 | 221 | rule3 = True | ||
2877 | 222 | |||
2878 | 223 | rules = [] | ||
2879 | 224 | if os.path.exists("/tftpboot") and not rule1: | ||
2880 | 225 | rules.append(selinux_msg % "/tftpboot/.*") | ||
2881 | 226 | else: | ||
2882 | 227 | if not rule2: | ||
2883 | 228 | rules.append(selinux_msg % "/var/lib/tftpboot/.*") | ||
2884 | 229 | if not rule3: | ||
2885 | 230 | rules.append(selinux_msg % "/var/www/cobbler/images/.*") | ||
2886 | 231 | if len(rules) > 0: | ||
2887 | 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)) | ||
2888 | 233 | |||
2889 | 234 | # now check to see that the Django sessions path is accessible | ||
2890 | 235 | # by Apache | ||
2891 | 236 | |||
2892 | 237 | data4 = utils.subprocess_get(self.logger,"/usr/sbin/semanage fcontext -l | grep httpd_sys_content_rw_t",shell=True) | ||
2893 | 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\"" | ||
2894 | 239 | rule4 = False | ||
2895 | 240 | for line in data4.split("\n"): | ||
2896 | 241 | if line.startswith("/var/lib/cobbler/webui_sessions/.*"): | ||
2897 | 242 | rule4 = True | ||
2898 | 243 | if not rule4: | ||
2899 | 244 | status.append(selinux_msg % "/var/lib/cobbler/webui_sessions/.*") | ||
2900 | 245 | |||
2901 | 246 | |||
2902 | 247 | def check_for_default_password(self,status): | ||
2903 | 248 | default_pass = self.settings.default_password_crypted | ||
2904 | 249 | if default_pass == "$1$mF86/UHC$WvcIcX2t6crBz2onWxyac.": | ||
2905 | 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")) | ||
2906 | 251 | |||
2907 | 252 | |||
2908 | 253 | def check_for_unreferenced_repos(self,status): | ||
2909 | 254 | repos = [] | ||
2910 | 255 | referenced = [] | ||
2911 | 256 | not_found = [] | ||
2912 | 257 | for r in self.config.api.repos(): | ||
2913 | 258 | repos.append(r.name) | ||
2914 | 259 | for p in self.config.api.profiles(): | ||
2915 | 260 | my_repos = p.repos | ||
2916 | 261 | if my_repos != "<<inherit>>": | ||
2917 | 262 | referenced.extend(my_repos) | ||
2918 | 263 | for r in referenced: | ||
2919 | 264 | if r not in repos and r != "<<inherit>>": | ||
2920 | 265 | not_found.append(r) | ||
2921 | 266 | if len(not_found) > 0: | ||
2922 | 267 | status.append(_("One or more repos referenced by profile objects is no longer defined in cobbler: %s") % ", ".join(not_found)) | ||
2923 | 268 | |||
2924 | 269 | def check_for_unsynced_repos(self,status): | ||
2925 | 270 | need_sync = [] | ||
2926 | 271 | for r in self.config.repos(): | ||
2927 | 272 | if r.mirror_locally == 1: | ||
2928 | 273 | lookfor = os.path.join(self.settings.webdir, "repo_mirror", r.name) | ||
2929 | 274 | if not os.path.exists(lookfor): | ||
2930 | 275 | need_sync.append(r.name) | ||
2931 | 276 | if len(need_sync) > 0: | ||
2932 | 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)) | ||
2933 | 278 | |||
2934 | 279 | |||
2935 | 280 | def check_httpd(self,status): | ||
2936 | 281 | """ | ||
2937 | 282 | Check if Apache is installed. | ||
2938 | 283 | """ | ||
2939 | 284 | if self.checked_dist in [ "suse", "redhat" ]: | ||
2940 | 285 | rc = utils.subprocess_get(self.logger,"httpd -v") | ||
2941 | 286 | else: | ||
2942 | 287 | rc = utils.subprocess_get(self.logger,"apache2 -v") | ||
2943 | 288 | if rc.find("Server") == -1: | ||
2944 | 289 | status.append("Apache (httpd) is not installed and/or in path") | ||
2945 | 290 | |||
2946 | 291 | |||
2947 | 292 | def check_dhcpd_bin(self,status): | ||
2948 | 293 | """ | ||
2949 | 294 | Check if dhcpd is installed | ||
2950 | 295 | """ | ||
2951 | 296 | if not os.path.exists("/usr/sbin/dhcpd"): | ||
2952 | 297 | status.append("dhcpd is not installed") | ||
2953 | 298 | |||
2954 | 299 | def check_dnsmasq_bin(self,status): | ||
2955 | 300 | """ | ||
2956 | 301 | Check if dnsmasq is installed | ||
2957 | 302 | """ | ||
2958 | 303 | rc = utils.subprocess_get(self.logger,"dnsmasq --help") | ||
2959 | 304 | if rc.find("Valid options") == -1: | ||
2960 | 305 | status.append("dnsmasq is not installed and/or in path") | ||
2961 | 306 | |||
2962 | 307 | def check_bind_bin(self,status): | ||
2963 | 308 | """ | ||
2964 | 309 | Check if bind is installed. | ||
2965 | 310 | """ | ||
2966 | 311 | rc = utils.subprocess_get(self.logger,"named -v") | ||
2967 | 312 | # it should return something like "BIND 9.6.1-P1-RedHat-9.6.1-6.P1.fc11" | ||
2968 | 313 | if rc.find("BIND") == -1: | ||
2969 | 314 | status.append("named is not installed and/or in path") | ||
2970 | 315 | |||
2971 | 316 | def check_bootloaders(self,status): | ||
2972 | 317 | """ | ||
2973 | 318 | Check if network bootloaders are installed | ||
2974 | 319 | """ | ||
2975 | 320 | # FIXME: move zpxe.rexx to loaders | ||
2976 | 321 | |||
2977 | 322 | bootloaders = { | ||
2978 | 323 | "elilo" : [ "/var/lib/cobbler/loaders/elilo*.efi" ], | ||
2979 | 324 | "menu.c32" : [ "/usr/share/syslinux/menu.c32", | ||
2980 | 325 | "/usr/lib/syslinux/menu.c32", | ||
2981 | 326 | "/var/lib/cobbler/loaders/menu.c32" ], | ||
2982 | 327 | "yaboot" : [ "/var/lib/cobbler/loaders/yaboot*" ], | ||
2983 | 328 | "pxelinux.0" : [ "/usr/share/syslinux/pxelinux.0", | ||
2984 | 329 | "/usr/lib/syslinux/pxelinux.0", | ||
2985 | 330 | "/var/lib/cobbler/loaders/pxelinux.0" ], | ||
2986 | 331 | "efi" : [ "/var/lib/cobbler/loaders/grub-x86.efi", | ||
2987 | 332 | "/var/lib/cobbler/loaders/grub-x86_64.efi" ], | ||
2988 | 333 | } | ||
2989 | 334 | |||
2990 | 335 | # look for bootloaders at the glob locations above | ||
2991 | 336 | found_bootloaders = [] | ||
2992 | 337 | items = bootloaders.keys() | ||
2993 | 338 | for loader_name in items: | ||
2994 | 339 | patterns = bootloaders[loader_name] | ||
2995 | 340 | for pattern in patterns: | ||
2996 | 341 | matches = glob.glob(pattern) | ||
2997 | 342 | if len(matches) > 0: | ||
2998 | 343 | found_bootloaders.append(loader_name) | ||
2999 | 344 | not_found = [] | ||
3000 | 345 | |||
3001 | 346 | # invert the list of what we've found so we can report on what we haven't found | ||
3002 | 347 | for loader_name in items: | ||
3003 | 348 | if loader_name not in found_bootloaders: | ||
3004 | 349 | not_found.append(loader_name) | ||
3005 | 350 | |||
3006 | 351 | if len(not_found) > 0: | ||
3007 | 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.") | ||
3008 | 353 | |||
3009 | 354 | def check_tftpd_bin(self,status): | ||
3010 | 355 | """ | ||
3011 | 356 | Check if tftpd is installed | ||
3012 | 357 | """ | ||
3013 | 358 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3014 | 359 | return | ||
3015 | 360 | |||
3016 | 361 | if not os.path.exists("/etc/xinetd.d/tftp"): | ||
3017 | 362 | status.append("missing /etc/xinetd.d/tftp, install tftp-server?") | ||
3018 | 363 | |||
3019 | 364 | def check_tftpd_dir(self,status): | ||
3020 | 365 | """ | ||
3021 | 366 | Check if cobbler.conf's tftpboot directory exists | ||
3022 | 367 | """ | ||
3023 | 368 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3024 | 369 | return | ||
3025 | 370 | |||
3026 | 371 | bootloc = utils.tftpboot_location() | ||
3027 | 372 | if not os.path.exists(bootloc): | ||
3028 | 373 | status.append(_("please create directory: %(dirname)s") % { "dirname" : bootloc }) | ||
3029 | 374 | |||
3030 | 375 | |||
3031 | 376 | def check_tftpd_conf(self,status): | ||
3032 | 377 | """ | ||
3033 | 378 | Check that configured tftpd boot directory matches with actual | ||
3034 | 379 | Check that tftpd is enabled to autostart | ||
3035 | 380 | """ | ||
3036 | 381 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3037 | 382 | return | ||
3038 | 383 | |||
3039 | 384 | if os.path.exists("/etc/xinetd.d/tftp"): | ||
3040 | 385 | f = open("/etc/xinetd.d/tftp") | ||
3041 | 386 | re_disable = re.compile(r'disable.*=.*yes') | ||
3042 | 387 | for line in f.readlines(): | ||
3043 | 388 | if re_disable.search(line) and not line.strip().startswith("#"): | ||
3044 | 389 | status.append(_("change 'disable' to 'no' in %(file)s") % { "file" : "/etc/xinetd.d/tftp" }) | ||
3045 | 390 | else: | ||
3046 | 391 | status.append("missing configuration file: /etc/xinetd.d/tftp") | ||
3047 | 392 | |||
3048 | 393 | def check_ctftpd_bin(self,status): | ||
3049 | 394 | """ | ||
3050 | 395 | Check if the Cobbler tftp server is installed | ||
3051 | 396 | """ | ||
3052 | 397 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3053 | 398 | return | ||
3054 | 399 | |||
3055 | 400 | if not os.path.exists("/etc/xinetd.d/ctftp"): | ||
3056 | 401 | status.append("missing /etc/xinetd.d/ctftp") | ||
3057 | 402 | |||
3058 | 403 | def check_ctftpd_dir(self,status): | ||
3059 | 404 | """ | ||
3060 | 405 | Check if cobbler.conf's tftpboot directory exists | ||
3061 | 406 | """ | ||
3062 | 407 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3063 | 408 | return | ||
3064 | 409 | |||
3065 | 410 | bootloc = utils.tftpboot_location() | ||
3066 | 411 | if not os.path.exists(bootloc): | ||
3067 | 412 | status.append(_("please create directory: %(dirname)s") % { "dirname" : bootloc }) | ||
3068 | 413 | |||
3069 | 414 | def check_ctftpd_conf(self,status): | ||
3070 | 415 | """ | ||
3071 | 416 | Check that configured tftpd boot directory matches with actual | ||
3072 | 417 | Check that tftpd is enabled to autostart | ||
3073 | 418 | """ | ||
3074 | 419 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3075 | 420 | return | ||
3076 | 421 | |||
3077 | 422 | if os.path.exists("/etc/xinetd.d/tftp"): | ||
3078 | 423 | f = open("/etc/xinetd.d/tftp") | ||
3079 | 424 | re_disable = re.compile(r'disable.*=.*no') | ||
3080 | 425 | for line in f.readlines(): | ||
3081 | 426 | if re_disable.search(line) and not line.strip().startswith("#"): | ||
3082 | 427 | status.append(_("change 'disable' to 'yes' in %(file)s") % { "file" : "/etc/xinetd.d/tftp" }) | ||
3083 | 428 | if os.path.exists("/etc/xinetd.d/ctftp"): | ||
3084 | 429 | f = open("/etc/xinetd.d/ctftp") | ||
3085 | 430 | re_disable = re.compile(r'disable.*=.*yes') | ||
3086 | 431 | for line in f.readlines(): | ||
3087 | 432 | if re_disable.search(line) and not line.strip().startswith("#"): | ||
3088 | 433 | status.append(_("change 'disable' to 'no' in %(file)s") % { "file" : "/etc/xinetd.d/ctftp" }) | ||
3089 | 434 | else: | ||
3090 | 435 | status.append("missing configuration file: /etc/xinetd.d/ctftp") | ||
3091 | 436 | |||
3092 | 437 | def check_rsync_conf(self,status): | ||
3093 | 438 | """ | ||
3094 | 439 | Check that rsync is enabled to autostart | ||
3095 | 440 | """ | ||
3096 | 441 | if self.checked_dist in ["debian", "ubuntu"]: | ||
3097 | 442 | return | ||
3098 | 443 | |||
3099 | 444 | if os.path.exists("/etc/xinetd.d/rsync"): | ||
3100 | 445 | f = open("/etc/xinetd.d/rsync") | ||
3101 | 446 | re_disable = re.compile(r'disable.*=.*yes') | ||
3102 | 447 | for line in f.readlines(): | ||
3103 | 448 | if re_disable.search(line) and not line.strip().startswith("#"): | ||
3104 | 449 | status.append(_("change 'disable' to 'no' in %(file)s") % { "file" : "/etc/xinetd.d/rsync" }) | ||
3105 | 450 | else: | ||
3106 | 451 | status.append(_("file %(file)s does not exist") % { "file" : "/etc/xinetd.d/rsync" }) | ||
3107 | 452 | |||
3108 | 453 | |||
3109 | 454 | def check_dhcpd_conf(self,status): | ||
3110 | 455 | """ | ||
3111 | 456 | NOTE: this code only applies if cobbler is *NOT* set to generate | ||
3112 | 457 | a dhcp.conf file | ||
3113 | 458 | |||
3114 | 459 | Check that dhcpd *appears* to be configured for pxe booting. | ||
3115 | 460 | We can't assure file correctness. Since a cobbler user might | ||
3116 | 461 | have dhcp on another server, it's okay if it's not there and/or | ||
3117 | 462 | not configured correctly according to automated scans. | ||
3118 | 463 | """ | ||
3119 | 464 | if not (self.settings.manage_dhcp == 0): | ||
3120 | 465 | return | ||
3121 | 466 | |||
3122 | 467 | if os.path.exists(self.settings.dhcpd_conf): | ||
3123 | 468 | match_next = False | ||
3124 | 469 | match_file = False | ||
3125 | 470 | f = open(self.settings.dhcpd_conf) | ||
3126 | 471 | for line in f.readlines(): | ||
3127 | 472 | if line.find("next-server") != -1: | ||
3128 | 473 | match_next = True | ||
3129 | 474 | if line.find("filename") != -1: | ||
3130 | 475 | match_file = True | ||
3131 | 476 | if not match_next: | ||
3132 | 477 | status.append(_("expecting next-server entry in %(file)s") % { "file" : self.settings.dhcpd_conf }) | ||
3133 | 478 | if not match_file: | ||
3134 | 479 | status.append(_("missing file: %(file)s") % { "file" : self.settings.dhcpd_conf }) | ||
3135 | 480 | else: | ||
3136 | 481 | status.append(_("missing file: %(file)s") % { "file" : self.settings.dhcpd_conf }) | ||
3137 | 482 | |||
3138 | 0 | 483 | ||
3139 | === added file 'cobbler/action_dlcontent.py' | |||
3140 | --- cobbler/action_dlcontent.py 1970-01-01 00:00:00 +0000 | |||
3141 | +++ cobbler/action_dlcontent.py 2011-03-11 21:10:49 +0000 | |||
3142 | @@ -0,0 +1,96 @@ | |||
3143 | 1 | """ | ||
3144 | 2 | Downloads bootloader content for all arches for when the user doesn't want to supply their own. | ||
3145 | 3 | |||
3146 | 4 | Copyright 2009, Red Hat, Inc | ||
3147 | 5 | Michael DeHaan <mdehaan@redhat.com> | ||
3148 | 6 | |||
3149 | 7 | This program is free software; you can redistribute it and/or modify | ||
3150 | 8 | it under the terms of the GNU General Public License as published by | ||
3151 | 9 | the Free Software Foundation; either version 2 of the License, or | ||
3152 | 10 | (at your option) any later version. | ||
3153 | 11 | |||
3154 | 12 | This program is distributed in the hope that it will be useful, | ||
3155 | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3156 | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3157 | 15 | GNU General Public License for more details. | ||
3158 | 16 | |||
3159 | 17 | You should have received a copy of the GNU General Public License | ||
3160 | 18 | along with this program; if not, write to the Free Software | ||
3161 | 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
3162 | 20 | 02110-1301 USA | ||
3163 | 21 | """ | ||
3164 | 22 | |||
3165 | 23 | import os | ||
3166 | 24 | import urlgrabber | ||
3167 | 25 | import clogger | ||
3168 | 26 | |||
3169 | 27 | class ContentDownloader: | ||
3170 | 28 | |||
3171 | 29 | def __init__(self,config,logger=None): | ||
3172 | 30 | """ | ||
3173 | 31 | Constructor | ||
3174 | 32 | """ | ||
3175 | 33 | self.config = config | ||
3176 | 34 | self.settings = config.settings() | ||
3177 | 35 | if logger is None: | ||
3178 | 36 | logger = clogger.Logger() | ||
3179 | 37 | self.logger = logger | ||
3180 | 38 | |||
3181 | 39 | |||
3182 | 40 | def run(self,force=False): | ||
3183 | 41 | """ | ||
3184 | 42 | Download bootloader content for all of the latest bootloaders, since the user | ||
3185 | 43 | has chosen to not supply their own. You may ask "why not get this from yum", though | ||
3186 | 44 | Fedora has no IA64 repo, for instance, and we also want this to be able to work on Debian and | ||
3187 | 45 | further do not want folks to have to install a cross compiler. For those that don't like this approach | ||
3188 | 46 | they can still source their cross-arch bootloader content manually. | ||
3189 | 47 | """ | ||
3190 | 48 | |||
3191 | 49 | content_server = "http://dgoodwin.fedorapeople.org/loaders" | ||
3192 | 50 | dest = "/var/lib/cobbler/loaders" | ||
3193 | 51 | |||
3194 | 52 | files = ( | ||
3195 | 53 | ( "%s/README" % content_server, "%s/README" % dest ), | ||
3196 | 54 | ( "%s/COPYING.elilo" % content_server, "%s/COPYING.elilo" % dest ), | ||
3197 | 55 | ( "%s/COPYING.yaboot" % content_server, "%s/COPYING.yaboot" % dest), | ||
3198 | 56 | ( "%s/COPYING.syslinux" % content_server, "%s/COPYING.syslinux" % dest), | ||
3199 | 57 | ( "%s/elilo-3.8-ia64.efi" % content_server, "%s/elilo-ia64.efi" % dest ), | ||
3200 | 58 | ( "%s/yaboot-1.3.14-12" % content_server, "%s/yaboot" % dest), | ||
3201 | 59 | ( "%s/pxelinux.0-3.61" % content_server, "%s/pxelinux.0" % dest), | ||
3202 | 60 | ( "%s/menu.c32-3.61" % content_server, "%s/menu.c32" % dest), | ||
3203 | 61 | ( "%s/grub-0.97-x86.efi" % content_server, "%s/grub-x86.efi" % dest), | ||
3204 | 62 | ( "%s/grub-0.97-x86_64.efi" % content_server, "%s/grub-x86_64.efi" % dest), | ||
3205 | 63 | ) | ||
3206 | 64 | |||
3207 | 65 | proxies = {} | ||
3208 | 66 | for var in os.environ.keys(): | ||
3209 | 67 | if (var.lower() == "http_proxy"): | ||
3210 | 68 | proxies['http'] = os.environ[var] | ||
3211 | 69 | |||
3212 | 70 | if (var.lower() == "ftp_proxy"): | ||
3213 | 71 | proxies['ftp'] = os.environ[var] | ||
3214 | 72 | |||
3215 | 73 | if (len(proxies) > 0): | ||
3216 | 74 | for f in files: | ||
3217 | 75 | src = f[0] | ||
3218 | 76 | dst = f[1] | ||
3219 | 77 | if os.path.exists(dst) and not force: | ||
3220 | 78 | self.logger.info("path %s already exists, not overwriting existing content, use --force if you wish to update" % dst) | ||
3221 | 79 | continue | ||
3222 | 80 | os.chdir(dest) | ||
3223 | 81 | self.logger.info("downloading %s to %s" % (src,dst)) | ||
3224 | 82 | urlgrabber.grabber.urlgrab(src, proxies=proxies) | ||
3225 | 83 | |||
3226 | 84 | else: | ||
3227 | 85 | self.logger.info("downloading content required to netboot all arches") | ||
3228 | 86 | for f in files: | ||
3229 | 87 | src = f[0] | ||
3230 | 88 | dst = f[1] | ||
3231 | 89 | if os.path.exists(dst) and not force: | ||
3232 | 90 | self.logger.info("path %s already exists, not overwriting existing content, use --force if you wish to update" % dst) | ||
3233 | 91 | continue | ||
3234 | 92 | self.logger.info("downloading %s to %s" % (src,dst)) | ||
3235 | 93 | urlgrabber.urlgrab(src,dst) | ||
3236 | 94 | |||
3237 | 95 | return True | ||
3238 | 96 | |||
3239 | 0 | 97 | ||
3240 | === added file 'cobbler/action_hardlink.py' | |||
3241 | --- cobbler/action_hardlink.py 1970-01-01 00:00:00 +0000 | |||
3242 | +++ cobbler/action_hardlink.py 2011-03-11 21:10:49 +0000 | |||
3243 | @@ -0,0 +1,60 @@ | |||
3244 | 1 | """ | ||
3245 | 2 | Hard links cobbler content together to save space. | ||
3246 | 3 | |||
3247 | 4 | Copyright 2009, Red Hat, Inc | ||
3248 | 5 | Michael DeHaan <mdehaan@redhat.com> | ||
3249 | 6 | |||
3250 | 7 | This program is free software; you can redistribute it and/or modify | ||
3251 | 8 | it under the terms of the GNU General Public License as published by | ||
3252 | 9 | the Free Software Foundation; either version 2 of the License, or | ||
3253 | 10 | (at your option) any later version. | ||
3254 | 11 | |||
3255 | 12 | This program is distributed in the hope that it will be useful, | ||
3256 | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3257 | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3258 | 15 | GNU General Public License for more details. | ||
3259 | 16 | |||
3260 | 17 | You should have received a copy of the GNU General Public License | ||
3261 | 18 | along with this program; if not, write to the Free Software | ||
3262 | 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
3263 | 20 | 02110-1301 USA | ||
3264 | 21 | """ | ||
3265 | 22 | |||
3266 | 23 | import os | ||
3267 | 24 | import utils | ||
3268 | 25 | from cexceptions import * | ||
3269 | 26 | import clogger | ||
3270 | 27 | |||
3271 | 28 | class HardLinker: | ||
3272 | 29 | |||
3273 | 30 | def __init__(self,config,logger=None): | ||
3274 | 31 | """ | ||
3275 | 32 | Constructor | ||
3276 | 33 | """ | ||
3277 | 34 | #self.config = config | ||
3278 | 35 | #self.api = config.api | ||
3279 | 36 | #self.settings = config.settings() | ||
3280 | 37 | if logger is None: | ||
3281 | 38 | logger = clogger.Logger() | ||
3282 | 39 | self.logger = logger | ||
3283 | 40 | |||
3284 | 41 | |||
3285 | 42 | def run(self): | ||
3286 | 43 | """ | ||
3287 | 44 | Simply hardlinks directories that are cobbler managed. | ||
3288 | 45 | This is a /very/ simple command but may grow more complex | ||
3289 | 46 | and intelligent over time. | ||
3290 | 47 | """ | ||
3291 | 48 | |||
3292 | 49 | # FIXME: if these directories become configurable some | ||
3293 | 50 | # changes will be required here. | ||
3294 | 51 | |||
3295 | 52 | if not os.path.exists("/usr/sbin/hardlink"): | ||
3296 | 53 | utils.die(self.logger,"please install 'hardlink' (/usr/sbin/hardlink) to use this feature") | ||
3297 | 54 | |||
3298 | 55 | self.logger.info("now hardlinking to save space, this may take some time.") | ||
3299 | 56 | |||
3300 | 57 | rc = utils.subprocess_call(self.logger,"/usr/sbin/hardlink -c -v /var/www/cobbler/ks_mirror /var/www/cobbler/repo_mirror",shell=True) | ||
3301 | 58 | |||
3302 | 59 | return rc | ||
3303 | 60 | |||
3304 | 0 | 61 | ||
3305 | === added file 'cobbler/action_import.py' | |||
3306 | --- cobbler/action_import.py 1970-01-01 00:00:00 +0000 | |||
3307 | +++ cobbler/action_import.py 2011-03-11 21:10:49 +0000 | |||
3308 | @@ -0,0 +1,1332 @@ | |||
3309 | 1 | """ | ||
3310 | 2 | Enables the "cobbler import" command to seed cobbler | ||
3311 | 3 | information with available distribution from rsync mirrors | ||
3312 | 4 | and mounted DVDs. | ||
3313 | 5 | |||
3314 | 6 | Copyright 2006-2009, Red Hat, Inc | ||
3315 | 7 | Michael DeHaan <mdehaan@redhat.com> | ||
3316 | 8 | |||
3317 | 9 | This program is free software; you can redistribute it and/or modify | ||
3318 | 10 | it under the terms of the GNU General Public License as published by | ||
3319 | 11 | the Free Software Foundation; either version 2 of the License, or | ||
3320 | 12 | (at your option) any later version. | ||
3321 | 13 | |||
3322 | 14 | This program is distributed in the hope that it will be useful, | ||
3323 | 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3324 | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3325 | 17 | GNU General Public License for more details. | ||
3326 | 18 | |||
3327 | 19 | You should have received a copy of the GNU General Public License | ||
3328 | 20 | along with this program; if not, write to the Free Software | ||
3329 | 21 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
3330 | 22 | 02110-1301 USA | ||
3331 | 23 | """ | ||
3332 | 24 | |||
3333 | 25 | from cexceptions import * | ||
3334 | 26 | import os | ||
3335 | 27 | import os.path | ||
3336 | 28 | import re | ||
3337 | 29 | import traceback | ||
3338 | 30 | import glob | ||
3339 | 31 | import api | ||
3340 | 32 | import utils | ||
3341 | 33 | import shutil | ||
3342 | 34 | from utils import _ | ||
3343 | 35 | import item_repo | ||
3344 | 36 | import clogger | ||
3345 | 37 | |||
3346 | 38 | # FIXME: add --quiet depending on if not --verbose? | ||
3347 | 39 | RSYNC_CMD = "rsync -a %s '%s' %s/ks_mirror/%s --exclude-from=/etc/cobbler/rsync.exclude --progress" | ||
3348 | 40 | |||
3349 | 41 | class Importer: | ||
3350 | 42 | |||
3351 | 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): | ||
3352 | 44 | """ | ||
3353 | 45 | Performs an import of a install tree (or trees) from the given | ||
3354 | 46 | mirror address. The prefix of the distro is to be specified | ||
3355 | 47 | by mirror name. For instance, if FC-6 is given, FC-6-xen-i386 | ||
3356 | 48 | would be a potential distro that could be created. For content | ||
3357 | 49 | available on external servers via a known nfs:// or ftp:// or | ||
3358 | 50 | http:// path, we can import without doing rsync mirorring to | ||
3359 | 51 | cobbler's http directory. This is explained in more detail | ||
3360 | 52 | in the manpage. Leave network_root to None if want mirroring. | ||
3361 | 53 | """ | ||
3362 | 54 | self.api = api | ||
3363 | 55 | self.config = config | ||
3364 | 56 | self.mirror = mirror | ||
3365 | 57 | self.mirror_name = mirror_name | ||
3366 | 58 | self.network_root = network_root | ||
3367 | 59 | self.distros = config.distros() | ||
3368 | 60 | self.profiles = config.profiles() | ||
3369 | 61 | self.systems = config.systems() | ||
3370 | 62 | self.settings = config.settings() | ||
3371 | 63 | self.kickstart_file = kickstart_file | ||
3372 | 64 | self.rsync_flags = rsync_flags | ||
3373 | 65 | self.arch = arch | ||
3374 | 66 | self.breed = breed | ||
3375 | 67 | self.os_version = os_version | ||
3376 | 68 | if logger is None: | ||
3377 | 69 | logger = clogger.Logger() | ||
3378 | 70 | self.logger = logger | ||
3379 | 71 | |||
3380 | 72 | |||
3381 | 73 | # ======================================================================== | ||
3382 | 74 | |||
3383 | 75 | def run(self): | ||
3384 | 76 | |||
3385 | 77 | """ | ||
3386 | 78 | This contains the guts of the import command. | ||
3387 | 79 | """ | ||
3388 | 80 | |||
3389 | 81 | # some fixups for the XMLRPC interface, which does not use "None" | ||
3390 | 82 | if self.arch == "": self.arch = None | ||
3391 | 83 | if self.mirror == "": self.mirror = None | ||
3392 | 84 | if self.mirror_name == "": self.mirror_name = None | ||
3393 | 85 | if self.breed == "": self.breed = None | ||
3394 | 86 | if self.kickstart_file == "": self.kickstart_file = None | ||
3395 | 87 | if self.os_version == "": self.os_version = None | ||
3396 | 88 | if self.rsync_flags == "": self.rsync_flags = None | ||
3397 | 89 | if self.network_root == "": self.network_root = None | ||
3398 | 90 | |||
3399 | 91 | # both --import and --name are required arguments | ||
3400 | 92 | |||
3401 | 93 | if self.mirror is None: | ||
3402 | 94 | utils.die(self.logger,"import failed. no --path specified") | ||
3403 | 95 | if self.mirror_name is None: | ||
3404 | 96 | utils.die(self.logger,"import failed. no --name specified") | ||
3405 | 97 | |||
3406 | 98 | # if --arch is supplied, validate it to ensure it's valid | ||
3407 | 99 | |||
3408 | 100 | if self.arch is not None and self.arch != "": | ||
3409 | 101 | self.arch = self.arch.lower() | ||
3410 | 102 | if self.arch == "x86": | ||
3411 | 103 | # be consistent | ||
3412 | 104 | self.arch = "i386" | ||
3413 | 105 | if self.arch not in [ "i386", "ia64", "ppc", "ppc64", "s390", "s390x", "x86_64", ]: | ||
3414 | 106 | utils.die(self.logger,"arch must be i386, ia64, ppc, ppc64, s390, s390x or x86_64") | ||
3415 | 107 | |||
3416 | 108 | # if we're going to do any copying, set where to put things | ||
3417 | 109 | # and then make sure nothing is already there. | ||
3418 | 110 | |||
3419 | 111 | mpath = os.path.join(self.settings.webdir, "ks_mirror", self.mirror_name) | ||
3420 | 112 | if os.path.exists(mpath) and self.arch is None: | ||
3421 | 113 | # FIXME : Raise exception even when network_root is given ? | ||
3422 | 114 | utils.die(self.logger,"Something already exists at this import location (%s). You must specify --arch to avoid potentially overwriting existing files." % mpath) | ||
3423 | 115 | |||
3424 | 116 | # import takes a --kickstart for forcing selection that can't be used in all circumstances | ||
3425 | 117 | |||
3426 | 118 | if self.kickstart_file and not self.breed: | ||
3427 | 119 | utils.die(self.logger,"Kickstart file can only be specified when a specific breed is selected") | ||
3428 | 120 | |||
3429 | 121 | if self.os_version and not self.breed: | ||
3430 | 122 | utils.die(self.logger,"OS version can only be specified when a specific breed is selected") | ||
3431 | 123 | |||
3432 | 124 | #if self.breed and self.breed.lower() not in [ "redhat", "debian", "ubuntu", "windows" ]: | ||
3433 | 125 | #if self.breed and self.breed.lower() not in [ "redhat" ]: | ||
3434 | 126 | if self.breed and self.breed.lower() not in [ "redhat", "vmware" ]: | ||
3435 | 127 | utils.die(self.logger,"Supplied import breed is not supported") | ||
3436 | 128 | |||
3437 | 129 | # if --arch is supplied, make sure the user is not importing a path with a different | ||
3438 | 130 | # arch, which would just be silly. | ||
3439 | 131 | |||
3440 | 132 | if self.arch: | ||
3441 | 133 | # append the arch path to the name if the arch is not already | ||
3442 | 134 | # found in the name. | ||
3443 | 135 | for x in [ "i386", "ia64", "ppc", "ppc64", "s390", "s390x", "x86_64", "x86", ]: | ||
3444 | 136 | if self.mirror_name.lower().find(x) != -1: | ||
3445 | 137 | if self.arch != x : | ||
3446 | 138 | utils.die(self.logger,"Architecture found on pathname (%s) does not fit the one given in command line (%s)"%(x,self.arch)) | ||
3447 | 139 | break | ||
3448 | 140 | else: | ||
3449 | 141 | # FIXME : This is very likely removed later at get_proposed_name, and the guessed arch appended again | ||
3450 | 142 | self.mirror_name = self.mirror_name + "-" + self.arch | ||
3451 | 143 | |||
3452 | 144 | # make the output path and mirror content but only if not specifying that a network | ||
3453 | 145 | # accessible support location already exists (this is --available-as on the command line) | ||
3454 | 146 | |||
3455 | 147 | if self.network_root is None: | ||
3456 | 148 | |||
3457 | 149 | # we need to mirror (copy) the files | ||
3458 | 150 | |||
3459 | 151 | self.path = os.path.normpath( "%s/ks_mirror/%s" % (self.settings.webdir, self.mirror_name) ) | ||
3460 | 152 | self.mkdir(self.path) | ||
3461 | 153 | |||
3462 | 154 | # prevent rsync from creating the directory name twice | ||
3463 | 155 | # if we are copying via rsync | ||
3464 | 156 | |||
3465 | 157 | if not self.mirror.endswith("/"): | ||
3466 | 158 | self.mirror = "%s/" % self.mirror | ||
3467 | 159 | |||
3468 | 160 | if self.mirror.startswith("http://") or self.mirror.startswith("ftp://") or self.mirror.startswith("nfs://"): | ||
3469 | 161 | |||
3470 | 162 | # http mirrors are kind of primative. rsync is better. | ||
3471 | 163 | # that's why this isn't documented in the manpage and we don't support them. | ||
3472 | 164 | # TODO: how about adding recursive FTP as an option? | ||
3473 | 165 | |||
3474 | 166 | utils.die(self.logger,"unsupported protocol") | ||
3475 | 167 | |||
3476 | 168 | else: | ||
3477 | 169 | |||
3478 | 170 | # good, we're going to use rsync.. | ||
3479 | 171 | # we don't use SSH for public mirrors and local files. | ||
3480 | 172 | # presence of user@host syntax means use SSH | ||
3481 | 173 | |||
3482 | 174 | spacer = "" | ||
3483 | 175 | if not self.mirror.startswith("rsync://") and not self.mirror.startswith("/"): | ||
3484 | 176 | spacer = ' -e "ssh" ' | ||
3485 | 177 | rsync_cmd = RSYNC_CMD | ||
3486 | 178 | if self.rsync_flags: | ||
3487 | 179 | rsync_cmd = rsync_cmd + " " + self.rsync_flags | ||
3488 | 180 | |||
3489 | 181 | # kick off the rsync now | ||
3490 | 182 | |||
3491 | 183 | self.run_this(rsync_cmd, (spacer, self.mirror, self.settings.webdir, self.mirror_name)) | ||
3492 | 184 | |||
3493 | 185 | else: | ||
3494 | 186 | |||
3495 | 187 | # rather than mirroring, we're going to assume the path is available | ||
3496 | 188 | # over http, ftp, and nfs, perhaps on an external filer. scanning still requires | ||
3497 | 189 | # --mirror is a filesystem path, but --available-as marks the network path | ||
3498 | 190 | |||
3499 | 191 | if not os.path.exists(self.mirror): | ||
3500 | 192 | utils.die(self.logger, "path does not exist: %s" % self.mirror) | ||
3501 | 193 | |||
3502 | 194 | # find the filesystem part of the path, after the server bits, as each distro | ||
3503 | 195 | # URL needs to be calculated relative to this. | ||
3504 | 196 | |||
3505 | 197 | if not self.network_root.endswith("/"): | ||
3506 | 198 | self.network_root = self.network_root + "/" | ||
3507 | 199 | self.path = os.path.normpath( self.mirror ) | ||
3508 | 200 | valid_roots = [ "nfs://", "ftp://", "http://" ] | ||
3509 | 201 | for valid_root in valid_roots: | ||
3510 | 202 | if self.network_root.startswith(valid_root): | ||
3511 | 203 | break | ||
3512 | 204 | else: | ||
3513 | 205 | utils.die(self.logger, "Network root given to --available-as must be nfs://, ftp://, or http://") | ||
3514 | 206 | if self.network_root.startswith("nfs://"): | ||
3515 | 207 | try: | ||
3516 | 208 | (a,b,rest) = self.network_root.split(":",3) | ||
3517 | 209 | except: | ||
3518 | 210 | utils.die(self.logger, "Network root given to --available-as is missing a colon, please see the manpage example.") | ||
3519 | 211 | |||
3520 | 212 | # now walk the filesystem looking for distributions that match certain patterns | ||
3521 | 213 | |||
3522 | 214 | self.logger.info("adding distros") | ||
3523 | 215 | distros_added = [] | ||
3524 | 216 | # FIXME : search below self.path for isolinux configurations or known directories from TRY_LIST | ||
3525 | 217 | os.path.walk(self.path, self.distro_adder, distros_added) | ||
3526 | 218 | |||
3527 | 219 | # find out if we can auto-create any repository records from the install tree | ||
3528 | 220 | |||
3529 | 221 | if self.network_root is None: | ||
3530 | 222 | self.logger.info("associating repos") | ||
3531 | 223 | # FIXME: this automagic is not possible (yet) without mirroring | ||
3532 | 224 | self.repo_finder(distros_added) | ||
3533 | 225 | |||
3534 | 226 | # find the most appropriate answer files for each profile object | ||
3535 | 227 | |||
3536 | 228 | self.logger.info("associating kickstarts") | ||
3537 | 229 | self.kickstart_finder(distros_added) | ||
3538 | 230 | |||
3539 | 231 | # ensure bootloaders are present | ||
3540 | 232 | self.api.pxegen.copy_bootloaders() | ||
3541 | 233 | |||
3542 | 234 | return True | ||
3543 | 235 | |||
3544 | 236 | # ---------------------------------------------------------------------- | ||
3545 | 237 | |||
3546 | 238 | def mkdir(self, dir): | ||
3547 | 239 | |||
3548 | 240 | """ | ||
3549 | 241 | A more tolerant mkdir. | ||
3550 | 242 | FIXME: use the one in utils.py (?) | ||
3551 | 243 | """ | ||
3552 | 244 | |||
3553 | 245 | try: | ||
3554 | 246 | os.makedirs(dir) | ||
3555 | 247 | except OSError , ex: | ||
3556 | 248 | if ex.strerror == "Permission denied": | ||
3557 | 249 | utils.die(self.logger, "Permission denied at %s" % dir) | ||
3558 | 250 | except: | ||
3559 | 251 | pass | ||
3560 | 252 | |||
3561 | 253 | # ---------------------------------------------------------------------- | ||
3562 | 254 | |||
3563 | 255 | def run_this(self, cmd, args): | ||
3564 | 256 | |||
3565 | 257 | """ | ||
3566 | 258 | A simple wrapper around subprocess calls. | ||
3567 | 259 | """ | ||
3568 | 260 | |||
3569 | 261 | my_cmd = cmd % args | ||
3570 | 262 | rc = utils.subprocess_call(self.logger,my_cmd,shell=True) | ||
3571 | 263 | if rc != 0: | ||
3572 | 264 | utils.die(self.logger,"Command failed") | ||
3573 | 265 | |||
3574 | 266 | # ======================================================================= | ||
3575 | 267 | |||
3576 | 268 | def kickstart_finder(self,distros_added): | ||
3577 | 269 | |||
3578 | 270 | """ | ||
3579 | 271 | For all of the profiles in the config w/o a kickstart, use the | ||
3580 | 272 | given kickstart file, or look at the kernel path, from that, | ||
3581 | 273 | see if we can guess the distro, and if we can, assign a kickstart | ||
3582 | 274 | if one is available for it. | ||
3583 | 275 | """ | ||
3584 | 276 | for profile in self.profiles: | ||
3585 | 277 | distro = self.distros.find(name=profile.get_conceptual_parent().name) | ||
3586 | 278 | if distro is None or not (distro in distros_added): | ||
3587 | 279 | continue | ||
3588 | 280 | |||
3589 | 281 | kdir = os.path.dirname(distro.kernel) | ||
3590 | 282 | importer = import_factory(kdir,self.path,self.breed,self.logger) | ||
3591 | 283 | if self.kickstart_file == None: | ||
3592 | 284 | for rpm in importer.get_release_files(): | ||
3593 | 285 | # FIXME : This redhat specific check should go into the importer.find_release_files method | ||
3594 | 286 | if rpm.find("notes") != -1: | ||
3595 | 287 | continue | ||
3596 | 288 | results = importer.scan_pkg_filename(rpm) | ||
3597 | 289 | # FIXME : If os is not found on tree but set with CLI, no kickstart is searched | ||
3598 | 290 | if results is None: | ||
3599 | 291 | self.logger.warning("No version found on imported tree") | ||
3600 | 292 | continue | ||
3601 | 293 | (flavor, major, minor) = results | ||
3602 | 294 | version , ks = importer.set_variance(flavor, major, minor, distro.arch) | ||
3603 | 295 | if self.os_version: | ||
3604 | 296 | if self.os_version != version: | ||
3605 | 297 | utils.die(self.logger,"CLI version differs from tree : %s vs. %s" % (self.os_version,version)) | ||
3606 | 298 | ds = importer.get_datestamp() | ||
3607 | 299 | distro.set_comment("%s.%s" % (version, int(minor))) | ||
3608 | 300 | distro.set_os_version(version) | ||
3609 | 301 | if ds is not None: | ||
3610 | 302 | distro.set_tree_build_time(ds) | ||
3611 | 303 | profile.set_kickstart(ks) | ||
3612 | 304 | self.profiles.add(profile,save=True) | ||
3613 | 305 | |||
3614 | 306 | self.configure_tree_location(distro,importer) | ||
3615 | 307 | self.distros.add(distro,save=True) # re-save | ||
3616 | 308 | self.api.serialize() | ||
3617 | 309 | |||
3618 | 310 | # ========================================================================== | ||
3619 | 311 | |||
3620 | 312 | |||
3621 | 313 | def configure_tree_location(self, distro, importer): | ||
3622 | 314 | |||
3623 | 315 | """ | ||
3624 | 316 | Once a distribution is identified, find the part of the distribution | ||
3625 | 317 | that has the URL in it that we want to use for kickstarting the | ||
3626 | 318 | distribution, and create a ksmeta variable $tree that contains this. | ||
3627 | 319 | """ | ||
3628 | 320 | |||
3629 | 321 | base = importer.get_rootdir() | ||
3630 | 322 | |||
3631 | 323 | if self.network_root is None: | ||
3632 | 324 | if distro.breed == "debian" or distro.breed == "ubuntu": | ||
3633 | 325 | dists_path = os.path.join( self.path , "dists" ) | ||
3634 | 326 | if os.path.isdir( dists_path ): | ||
3635 | 327 | tree = "http://@@http_server@@/cblr/ks_mirror/%s" % (self.mirror_name) | ||
3636 | 328 | else: | ||
3637 | 329 | tree = "http://@@http_server@@/cblr/repo_mirror/%s" % (distro.name) | ||
3638 | 330 | else: | ||
3639 | 331 | dest_link = os.path.join(self.settings.webdir, "links", distro.name) | ||
3640 | 332 | # create the links directory only if we are mirroring because with | ||
3641 | 333 | # SELinux Apache can't symlink to NFS (without some doing) | ||
3642 | 334 | if not os.path.exists(dest_link): | ||
3643 | 335 | try: | ||
3644 | 336 | os.symlink(base, dest_link) | ||
3645 | 337 | except: | ||
3646 | 338 | # this shouldn't happen but I've seen it ... debug ... | ||
3647 | 339 | self.logger.warning("symlink creation failed: %(base)s, %(dest)s") % { "base" : base, "dest" : dest_link } | ||
3648 | 340 | # how we set the tree depends on whether an explicit network_root was specified | ||
3649 | 341 | tree = "http://@@http_server@@/cblr/links/%s" % (distro.name) | ||
3650 | 342 | importer.set_install_tree( distro, tree) | ||
3651 | 343 | else: | ||
3652 | 344 | # where we assign the kickstart source is relative to our current directory | ||
3653 | 345 | # and the input start directory in the crawl. We find the path segments | ||
3654 | 346 | # between and tack them on the network source path to find the explicit | ||
3655 | 347 | # network path to the distro that Anaconda can digest. | ||
3656 | 348 | tail = self.path_tail(self.path, base) | ||
3657 | 349 | tree = self.network_root[:-1] + tail | ||
3658 | 350 | importer.set_install_tree( distro, tree) | ||
3659 | 351 | |||
3660 | 352 | # ============================================================================ | ||
3661 | 353 | |||
3662 | 354 | def path_tail(self, apath, bpath): | ||
3663 | 355 | """ | ||
3664 | 356 | Given two paths (B is longer than A), find the part in B not in A | ||
3665 | 357 | """ | ||
3666 | 358 | position = bpath.find(apath) | ||
3667 | 359 | if position != 0: | ||
3668 | 360 | utils.die(self.logger, "- warning: possible symlink traversal?: %s") | ||
3669 | 361 | rposition = position + len(self.mirror) | ||
3670 | 362 | result = bpath[rposition:] | ||
3671 | 363 | if not result.startswith("/"): | ||
3672 | 364 | result = "/" + result | ||
3673 | 365 | return result | ||
3674 | 366 | |||
3675 | 367 | # ====================================================================== | ||
3676 | 368 | |||
3677 | 369 | def repo_finder(self,distros_added): | ||
3678 | 370 | |||
3679 | 371 | """ | ||
3680 | 372 | This routine looks through all distributions and tries to find | ||
3681 | 373 | any applicable repositories in those distributions for post-install | ||
3682 | 374 | usage. | ||
3683 | 375 | """ | ||
3684 | 376 | |||
3685 | 377 | for distro in distros_added: | ||
3686 | 378 | self.logger.info("traversing distro %s" % distro.name) | ||
3687 | 379 | # FIXME : Shouldn't decide this the value of self.network_root ? | ||
3688 | 380 | if distro.kernel.find("ks_mirror") != -1: | ||
3689 | 381 | basepath = os.path.dirname(distro.kernel) | ||
3690 | 382 | importer = import_factory(basepath,self.path,self.breed,self.logger) | ||
3691 | 383 | top = importer.get_rootdir() | ||
3692 | 384 | self.logger.info("descent into %s" % top) | ||
3693 | 385 | if distro.breed in [ "debian" , "ubuntu" ]: | ||
3694 | 386 | dists_path = os.path.join( self.path , "dists" ) | ||
3695 | 387 | if not os.path.isdir( dists_path ): | ||
3696 | 388 | importer.process_repos( self , distro ) | ||
3697 | 389 | else: | ||
3698 | 390 | # FIXME : The location of repo definition is known from breed | ||
3699 | 391 | os.path.walk(top, self.repo_scanner, distro) | ||
3700 | 392 | else: | ||
3701 | 393 | self.logger.info("this distro isn't mirrored") | ||
3702 | 394 | |||
3703 | 395 | # ======================================================================== | ||
3704 | 396 | |||
3705 | 397 | |||
3706 | 398 | def repo_scanner(self,distro,dirname,fnames): | ||
3707 | 399 | |||
3708 | 400 | """ | ||
3709 | 401 | This is an os.path.walk routine that looks for potential yum repositories | ||
3710 | 402 | to be added to the configuration for post-install usage. | ||
3711 | 403 | """ | ||
3712 | 404 | |||
3713 | 405 | matches = {} | ||
3714 | 406 | for x in fnames: | ||
3715 | 407 | if x == "base" or x == "repodata": | ||
3716 | 408 | self.logger.info("processing repo at : %s" % dirname) | ||
3717 | 409 | # only run the repo scanner on directories that contain a comps.xml | ||
3718 | 410 | gloob1 = glob.glob("%s/%s/*comps*.xml" % (dirname,x)) | ||
3719 | 411 | if len(gloob1) >= 1: | ||
3720 | 412 | if matches.has_key(dirname): | ||
3721 | 413 | self.logger.info("looks like we've already scanned here: %s" % dirname) | ||
3722 | 414 | continue | ||
3723 | 415 | self.logger.info("need to process repo/comps: %s" % dirname) | ||
3724 | 416 | self.process_comps_file(dirname, distro) | ||
3725 | 417 | matches[dirname] = 1 | ||
3726 | 418 | else: | ||
3727 | 419 | self.logger.info("directory %s is missing xml comps file, skipping" % dirname) | ||
3728 | 420 | continue | ||
3729 | 421 | |||
3730 | 422 | # ======================================================================================= | ||
3731 | 423 | |||
3732 | 424 | |||
3733 | 425 | |||
3734 | 426 | def process_comps_file(self, comps_path, distro): | ||
3735 | 427 | """ | ||
3736 | 428 | When importing Fedora/EL certain parts of the install tree can also be used | ||
3737 | 429 | as yum repos containing packages that might not yet be available via updates | ||
3738 | 430 | in yum. This code identifies those areas. | ||
3739 | 431 | """ | ||
3740 | 432 | |||
3741 | 433 | processed_repos = {} | ||
3742 | 434 | |||
3743 | 435 | masterdir = "repodata" | ||
3744 | 436 | if not os.path.exists(os.path.join(comps_path, "repodata")): | ||
3745 | 437 | # older distros... | ||
3746 | 438 | masterdir = "base" | ||
3747 | 439 | |||
3748 | 440 | # figure out what our comps file is ... | ||
3749 | 441 | self.logger.info("looking for %(p1)s/%(p2)s/*comps*.xml" % { "p1" : comps_path, "p2" : masterdir }) | ||
3750 | 442 | files = glob.glob("%s/%s/*comps*.xml" % (comps_path, masterdir)) | ||
3751 | 443 | if len(files) == 0: | ||
3752 | 444 | self.logger.info("no comps found here: %s" % os.path.join(comps_path, masterdir)) | ||
3753 | 445 | return # no comps xml file found | ||
3754 | 446 | |||
3755 | 447 | # pull the filename from the longer part | ||
3756 | 448 | comps_file = files[0].split("/")[-1] | ||
3757 | 449 | |||
3758 | 450 | try: | ||
3759 | 451 | |||
3760 | 452 | # store the yum configs on the filesystem so we can use them later. | ||
3761 | 453 | # and configure them in the kickstart post, etc | ||
3762 | 454 | |||
3763 | 455 | counter = len(distro.source_repos) | ||
3764 | 456 | |||
3765 | 457 | # find path segment for yum_url (changing filesystem path to http:// trailing fragment) | ||
3766 | 458 | seg = comps_path.rfind("ks_mirror") | ||
3767 | 459 | urlseg = comps_path[seg+10:] | ||
3768 | 460 | |||
3769 | 461 | # write a yum config file that shows how to use the repo. | ||
3770 | 462 | if counter == 0: | ||
3771 | 463 | dotrepo = "%s.repo" % distro.name | ||
3772 | 464 | else: | ||
3773 | 465 | dotrepo = "%s-%s.repo" % (distro.name, counter) | ||
3774 | 466 | |||
3775 | 467 | fname = os.path.join(self.settings.webdir, "ks_mirror", "config", "%s-%s.repo" % (distro.name, counter)) | ||
3776 | 468 | |||
3777 | 469 | repo_url = "http://@@http_server@@/cobbler/ks_mirror/config/%s-%s.repo" % (distro.name, counter) | ||
3778 | 470 | |||
3779 | 471 | repo_url2 = "http://@@http_server@@/cobbler/ks_mirror/%s" % (urlseg) | ||
3780 | 472 | |||
3781 | 473 | distro.source_repos.append([repo_url,repo_url2]) | ||
3782 | 474 | |||
3783 | 475 | # NOTE: the following file is now a Cheetah template, so it can be remapped | ||
3784 | 476 | # during sync, that's why we have the @@http_server@@ left as templating magic. | ||
3785 | 477 | # repo_url2 is actually no longer used. (?) | ||
3786 | 478 | |||
3787 | 479 | config_file = open(fname, "w+") | ||
3788 | 480 | config_file.write("[core-%s]\n" % counter) | ||
3789 | 481 | config_file.write("name=core-%s\n" % counter) | ||
3790 | 482 | config_file.write("baseurl=http://@@http_server@@/cobbler/ks_mirror/%s\n" % (urlseg)) | ||
3791 | 483 | config_file.write("enabled=1\n") | ||
3792 | 484 | config_file.write("gpgcheck=0\n") | ||
3793 | 485 | config_file.write("priority=$yum_distro_priority\n") | ||
3794 | 486 | config_file.close() | ||
3795 | 487 | |||
3796 | 488 | # don't run creatrepo twice -- this can happen easily for Xen and PXE, when | ||
3797 | 489 | # they'll share same repo files. | ||
3798 | 490 | |||
3799 | 491 | if not processed_repos.has_key(comps_path): | ||
3800 | 492 | utils.remove_yum_olddata(comps_path) | ||
3801 | 493 | #cmd = "createrepo --basedir / --groupfile %s %s" % (os.path.join(comps_path, masterdir, comps_file), comps_path) | ||
3802 | 494 | cmd = "createrepo %s --groupfile %s %s" % (self.settings.createrepo_flags,os.path.join(comps_path, masterdir, comps_file), comps_path) | ||
3803 | 495 | utils.subprocess_call(self.logger, cmd, shell=True) | ||
3804 | 496 | processed_repos[comps_path] = 1 | ||
3805 | 497 | # for older distros, if we have a "base" dir parallel with "repodata", we need to copy comps.xml up one... | ||
3806 | 498 | p1 = os.path.join(comps_path, "repodata", "comps.xml") | ||
3807 | 499 | p2 = os.path.join(comps_path, "base", "comps.xml") | ||
3808 | 500 | if os.path.exists(p1) and os.path.exists(p2): | ||
3809 | 501 | shutil.copyfile(p1,p2) | ||
3810 | 502 | |||
3811 | 503 | except: | ||
3812 | 504 | self.logger.error("error launching createrepo (not installed?), ignoring") | ||
3813 | 505 | utils.log_exc(self.logger) | ||
3814 | 506 | |||
3815 | 507 | |||
3816 | 508 | # ======================================================================== | ||
3817 | 509 | |||
3818 | 510 | def distro_adder(self,distros_added,dirname,fnames): | ||
3819 | 511 | |||
3820 | 512 | """ | ||
3821 | 513 | This is an os.path.walk routine that finds distributions in the directory | ||
3822 | 514 | to be scanned and then creates them. | ||
3823 | 515 | """ | ||
3824 | 516 | |||
3825 | 517 | # FIXME: If there are more than one kernel or initrd image on the same directory, | ||
3826 | 518 | # results are unpredictable | ||
3827 | 519 | |||
3828 | 520 | initrd = None | ||
3829 | 521 | kernel = None | ||
3830 | 522 | |||
3831 | 523 | # make sure we don't mismatch PAE and non-PAE types | ||
3832 | 524 | pae_initrd = None | ||
3833 | 525 | pae_kernel = None | ||
3834 | 526 | |||
3835 | 527 | for x in fnames: | ||
3836 | 528 | adtls = [] | ||
3837 | 529 | |||
3838 | 530 | fullname = os.path.join(dirname,x) | ||
3839 | 531 | if os.path.islink(fullname) and os.path.isdir(fullname): | ||
3840 | 532 | if fullname.startswith(self.path): | ||
3841 | 533 | # Prevent infinite loop with Sci Linux 5 | ||
3842 | 534 | self.logger.warning("avoiding symlink loop") | ||
3843 | 535 | continue | ||
3844 | 536 | self.logger.info("following symlink: %s" % fullname) | ||
3845 | 537 | os.path.walk(fullname, self.distro_adder, distros_added) | ||
3846 | 538 | |||
3847 | 539 | if ( x.startswith("initrd") or x.startswith("ramdisk.image.gz") or x.startswith("vmkboot.gz") ) and x != "initrd.size" and x != "initrd.addrsize": | ||
3848 | 540 | if x.find("PAE") == -1: | ||
3849 | 541 | initrd = os.path.join(dirname,x) | ||
3850 | 542 | else: | ||
3851 | 543 | pae_initrd = os.path.join(dirname, x) | ||
3852 | 544 | |||
3853 | 545 | if ( x.startswith("vmlinu") or x.startswith("kernel.img") or x.startswith("linux") or x.startswith("mboot.c32") ) and x.find("initrd") == -1: | ||
3854 | 546 | if x.find("PAE") == -1: | ||
3855 | 547 | kernel = os.path.join(dirname,x) | ||
3856 | 548 | else: | ||
3857 | 549 | pae_kernel = os.path.join(dirname, x) | ||
3858 | 550 | |||
3859 | 551 | # if we've collected a matching kernel and initrd pair, turn the in and add them to the list | ||
3860 | 552 | if initrd is not None and kernel is not None and dirname.find("isolinux") == -1: | ||
3861 | 553 | adtls.append(self.add_entry(dirname,kernel,initrd)) | ||
3862 | 554 | kernel = None | ||
3863 | 555 | initrd = None | ||
3864 | 556 | elif pae_initrd is not None and pae_kernel is not None and dirname.find("isolinux") == -1: | ||
3865 | 557 | adtls.append(self.add_entry(dirname,pae_kernel,pae_initrd)) | ||
3866 | 558 | pae_kernel = None | ||
3867 | 559 | pae_initrd = None | ||
3868 | 560 | elif initrd is not None and kernel is not None and dirname.find("VMware") == -1: | ||
3869 | 561 | adtls.append(self.add_entry(dirname,kernel,initrd)) | ||
3870 | 562 | kernel = None | ||
3871 | 563 | initrd = None | ||
3872 | 564 | for adtl in adtls: | ||
3873 | 565 | distros_added.extend(adtl) | ||
3874 | 566 | |||
3875 | 567 | |||
3876 | 568 | |||
3877 | 569 | |||
3878 | 570 | # ======================================================================== | ||
3879 | 571 | |||
3880 | 572 | def add_entry(self,dirname,kernel,initrd): | ||
3881 | 573 | |||
3882 | 574 | """ | ||
3883 | 575 | When we find a directory with a valid kernel/initrd in it, create the distribution objects | ||
3884 | 576 | as appropriate and save them. This includes creating xen and rescue distros/profiles | ||
3885 | 577 | if possible. | ||
3886 | 578 | """ | ||
3887 | 579 | |||
3888 | 580 | proposed_name = self.get_proposed_name(dirname,kernel) | ||
3889 | 581 | proposed_arch = self.get_proposed_arch(dirname) | ||
3890 | 582 | |||
3891 | 583 | if self.arch and proposed_arch and self.arch != proposed_arch: | ||
3892 | 584 | utils.die(self.logger,"Arch from pathname (%s) does not match with supplied one %s"%(proposed_arch,self.arch)) | ||
3893 | 585 | |||
3894 | 586 | importer = import_factory(dirname,self.path,self.breed,self.logger) | ||
3895 | 587 | |||
3896 | 588 | archs = importer.learn_arch_from_tree() | ||
3897 | 589 | if not archs: | ||
3898 | 590 | if self.arch: | ||
3899 | 591 | archs.append( self.arch ) | ||
3900 | 592 | else: | ||
3901 | 593 | if self.arch and self.arch not in archs: | ||
3902 | 594 | utils.die(self.logger, "Given arch (%s) not found on imported tree %s"%(self.arch,importer.get_pkgdir())) | ||
3903 | 595 | if proposed_arch: | ||
3904 | 596 | if archs and proposed_arch not in archs: | ||
3905 | 597 | self.logger.warning("arch from pathname (%s) not found on imported tree %s" % (proposed_arch,importer.get_pkgdir())) | ||
3906 | 598 | return | ||
3907 | 599 | |||
3908 | 600 | archs = [ proposed_arch ] | ||
3909 | 601 | |||
3910 | 602 | if importer.breed == "ubuntu" and dirname.find("ubuntu-installer") == -1: | ||
3911 | 603 | self.logger.info("skipping entry, there are no netboot images") | ||
3912 | 604 | return | ||
3913 | 605 | |||
3914 | 606 | |||
3915 | 607 | if len(archs)>1: | ||
3916 | 608 | if importer.breed in [ "redhat" ]: | ||
3917 | 609 | self.logger.warning("directory %s holds multiple arches : %s" % (dirname, archs)) | ||
3918 | 610 | return | ||
3919 | 611 | self.logger.warning("- Warning : Multiple archs found : %s" % (archs)) | ||
3920 | 612 | |||
3921 | 613 | distros_added = [] | ||
3922 | 614 | |||
3923 | 615 | for pxe_arch in archs: | ||
3924 | 616 | |||
3925 | 617 | name = proposed_name + "-" + pxe_arch | ||
3926 | 618 | existing_distro = self.distros.find(name=name) | ||
3927 | 619 | |||
3928 | 620 | if existing_distro is not None: | ||
3929 | 621 | self.logger.warning("skipping import, as distro name already exists: %s" % name) | ||
3930 | 622 | continue | ||
3931 | 623 | |||
3932 | 624 | else: | ||
3933 | 625 | self.logger.info("creating new distro: %s" % name) | ||
3934 | 626 | distro = self.config.new_distro() | ||
3935 | 627 | |||
3936 | 628 | if name.find("-autoboot") != -1: | ||
3937 | 629 | # this is an artifact of some EL-3 imports | ||
3938 | 630 | continue | ||
3939 | 631 | |||
3940 | 632 | distro.set_name(name) | ||
3941 | 633 | distro.set_kernel(kernel) | ||
3942 | 634 | distro.set_initrd(initrd) | ||
3943 | 635 | distro.set_arch(pxe_arch) | ||
3944 | 636 | distro.set_breed(importer.breed) | ||
3945 | 637 | # If a version was supplied on command line, we set it now | ||
3946 | 638 | if self.os_version: | ||
3947 | 639 | distro.set_os_version(self.os_version) | ||
3948 | 640 | |||
3949 | 641 | self.distros.add(distro,save=True) | ||
3950 | 642 | distros_added.append(distro) | ||
3951 | 643 | |||
3952 | 644 | existing_profile = self.profiles.find(name=name) | ||
3953 | 645 | |||
3954 | 646 | # see if the profile name is already used, if so, skip it and | ||
3955 | 647 | # do not modify the existing profile | ||
3956 | 648 | |||
3957 | 649 | if existing_profile is None: | ||
3958 | 650 | self.logger.info("creating new profile: %s" % name) | ||
3959 | 651 | #FIXME: The created profile holds a default kickstart, and should be breed specific | ||
3960 | 652 | profile = self.config.new_profile() | ||
3961 | 653 | else: | ||
3962 | 654 | self.logger.info("skipping existing profile, name already exists: %s" % name) | ||
3963 | 655 | continue | ||
3964 | 656 | |||
3965 | 657 | # save our minimal profile which just points to the distribution and a good | ||
3966 | 658 | # default answer file | ||
3967 | 659 | |||
3968 | 660 | profile.set_name(name) | ||
3969 | 661 | profile.set_distro(name) | ||
3970 | 662 | if self.kickstart_file: | ||
3971 | 663 | profile.set_kickstart(self.kickstart_file) | ||
3972 | 664 | else: | ||
3973 | 665 | profile.set_kickstart(importer.ks) | ||
3974 | 666 | |||
3975 | 667 | # depending on the name of the profile we can define a good virt-type | ||
3976 | 668 | # for usage with koan | ||
3977 | 669 | |||
3978 | 670 | if name.find("-xen") != -1: | ||
3979 | 671 | profile.set_virt_type("xenpv") | ||
3980 | 672 | elif name.find("vmware") != -1: | ||
3981 | 673 | profile.set_virt_type("vmware") | ||
3982 | 674 | else: | ||
3983 | 675 | profile.set_virt_type("qemu") | ||
3984 | 676 | |||
3985 | 677 | # save our new profile to the collection | ||
3986 | 678 | |||
3987 | 679 | self.profiles.add(profile,save=True) | ||
3988 | 680 | |||
3989 | 681 | # Create a rescue image as well, if this is not a xen distro | ||
3990 | 682 | # but only for red hat profiles | ||
3991 | 683 | |||
3992 | 684 | # this code disabled as it seems to be adding "-rescue" to | ||
3993 | 685 | # distros that are /not/ rescue related, which is wrong. | ||
3994 | 686 | # left as a FIXME for those who find this feature interesting. | ||
3995 | 687 | |||
3996 | 688 | #if name.find("-xen") == -1 and importer.breed == "redhat": | ||
3997 | 689 | # rescue_name = 'rescue-' + name | ||
3998 | 690 | # existing_profile = self.profiles.find(name=rescue_name) | ||
3999 | 691 | # | ||
4000 | 692 | # if existing_profile is None: | ||
4001 | 693 | # self.logger.info("creating new profile: %s" % rescue_name) | ||
4002 | 694 | # profile = self.config.new_profile() | ||
4003 | 695 | # else: | ||
4004 | 696 | # continue | ||
4005 | 697 | # | ||
4006 | 698 | # profile.set_name(rescue_name) | ||
4007 | 699 | # profile.set_distro(name) | ||
4008 | 700 | # profile.set_virt_type("qemu") | ||
4009 | 701 | # profile.kernel_options['rescue'] = None | ||
4010 | 702 | # profile.kickstart = '/var/lib/cobbler/kickstarts/pxerescue.ks' | ||
4011 | 703 | # | ||
4012 | 704 | # self.profiles.add(profile,save=True) | ||
4013 | 705 | |||
4014 | 706 | # self.api.serialize() # not required, is implicit | ||
4015 | 707 | |||
4016 | 708 | return distros_added | ||
4017 | 709 | |||
4018 | 710 | # ======================================================================== | ||
4019 | 711 | |||
4020 | 712 | def get_proposed_name(self,dirname,kernel=None): | ||
4021 | 713 | |||
4022 | 714 | """ | ||
4023 | 715 | Given a directory name where we have a kernel/initrd pair, try to autoname | ||
4024 | 716 | the distribution (and profile) object based on the contents of that path | ||
4025 | 717 | """ | ||
4026 | 718 | |||
4027 | 719 | if self.network_root is not None: | ||
4028 | 720 | name = self.mirror_name + "-".join(self.path_tail(os.path.dirname(self.path),dirname).split("/")) | ||
4029 | 721 | else: | ||
4030 | 722 | # remove the part that says /var/www/cobbler/ks_mirror/name | ||
4031 | 723 | name = "-".join(dirname.split("/")[5:]) | ||
4032 | 724 | |||
4033 | 725 | if kernel is not None and kernel.find("PAE") != -1: | ||
4034 | 726 | name = name + "-PAE" | ||
4035 | 727 | |||
4036 | 728 | # These are all Ubuntu's doing, the netboot images are buried pretty | ||
4037 | 729 | # deep. ;-) -JC | ||
4038 | 730 | name = name.replace("-netboot","") | ||
4039 | 731 | name = name.replace("-ubuntu-installer","") | ||
4040 | 732 | name = name.replace("-amd64","") | ||
4041 | 733 | name = name.replace("-i386","") | ||
4042 | 734 | |||
4043 | 735 | # we know that some kernel paths should not be in the name | ||
4044 | 736 | |||
4045 | 737 | name = name.replace("-images","") | ||
4046 | 738 | name = name.replace("-pxeboot","") | ||
4047 | 739 | name = name.replace("-install","") | ||
4048 | 740 | name = name.replace("-isolinux","") | ||
4049 | 741 | |||
4050 | 742 | # some paths above the media root may have extra path segments we want | ||
4051 | 743 | # to clean up | ||
4052 | 744 | |||
4053 | 745 | name = name.replace("-os","") | ||
4054 | 746 | name = name.replace("-tree","") | ||
4055 | 747 | name = name.replace("var-www-cobbler-", "") | ||
4056 | 748 | name = name.replace("ks_mirror-","") | ||
4057 | 749 | name = name.replace("--","-") | ||
4058 | 750 | |||
4059 | 751 | # remove any architecture name related string, as real arch will be appended later | ||
4060 | 752 | |||
4061 | 753 | name = name.replace("chrp","ppc64") | ||
4062 | 754 | |||
4063 | 755 | for separator in [ '-' , '_' , '.' ] : | ||
4064 | 756 | for arch in [ "i386" , "x86_64" , "ia64" , "ppc64", "ppc32", "ppc", "x86" , "s390x", "s390" , "386" , "amd" ]: | ||
4065 | 757 | name = name.replace("%s%s" % ( separator , arch ),"") | ||
4066 | 758 | |||
4067 | 759 | return name | ||
4068 | 760 | |||
4069 | 761 | # ======================================================================== | ||
4070 | 762 | |||
4071 | 763 | def get_proposed_arch(self,dirname): | ||
4072 | 764 | """ | ||
4073 | 765 | Given an directory name, can we infer an architecture from a path segment? | ||
4074 | 766 | """ | ||
4075 | 767 | if dirname.find("x86_64") != -1 or dirname.find("amd") != -1: | ||
4076 | 768 | return "x86_64" | ||
4077 | 769 | if dirname.find("ia64") != -1: | ||
4078 | 770 | return "ia64" | ||
4079 | 771 | if dirname.find("i386") != -1 or dirname.find("386") != -1 or dirname.find("x86") != -1: | ||
4080 | 772 | return "i386" | ||
4081 | 773 | if dirname.find("s390x") != -1: | ||
4082 | 774 | return "s390x" | ||
4083 | 775 | if dirname.find("s390") != -1: | ||
4084 | 776 | return "s390" | ||
4085 | 777 | if dirname.find("ppc64") != -1 or dirname.find("chrp") != -1: | ||
4086 | 778 | return "ppc64" | ||
4087 | 779 | if dirname.find("ppc32") != -1: | ||
4088 | 780 | return "ppc" | ||
4089 | 781 | if dirname.find("ppc") != -1: | ||
4090 | 782 | return "ppc" | ||
4091 | 783 | return None | ||
4092 | 784 | |||
4093 | 785 | # ============================================== | ||
4094 | 786 | |||
4095 | 787 | |||
4096 | 788 | def guess_breed(kerneldir,path,cli_breed,logger): | ||
4097 | 789 | |||
4098 | 790 | """ | ||
4099 | 791 | This tries to guess the distro. Traverses from kernel dir to imported root checking | ||
4100 | 792 | for distro signatures, which are the locations in media where the search for release | ||
4101 | 793 | packages should start. When a debian/ubuntu pool is found, the upper directory should | ||
4102 | 794 | be checked to get the real breed. If we are on a real media, the upper directory will | ||
4103 | 795 | be at the same level, as a local '.' symlink | ||
4104 | 796 | The lowercase names are required for fat32/vfat filesystems | ||
4105 | 797 | """ | ||
4106 | 798 | signatures = [ | ||
4107 | 799 | [ 'pool' , "debian" ], | ||
4108 | 800 | [ 'VMware/RPMS' , "vmware" ], | ||
4109 | 801 | [ 'imagedd.bz2' , "vmware" ], | ||
4110 | 802 | [ 'RedHat/RPMS' , "redhat" ], | ||
4111 | 803 | [ 'RedHat/rpms' , "redhat" ], | ||
4112 | 804 | [ 'RedHat/Base' , "redhat" ], | ||
4113 | 805 | [ 'Fedora/RPMS' , "redhat" ], | ||
4114 | 806 | [ 'Fedora/rpms' , "redhat" ], | ||
4115 | 807 | [ 'CentOS/RPMS' , "redhat" ], | ||
4116 | 808 | [ 'CentOS/rpms' , "redhat" ], | ||
4117 | 809 | [ 'CentOS' , "redhat" ], | ||
4118 | 810 | [ 'Packages' , "redhat" ], | ||
4119 | 811 | [ 'Fedora' , "redhat" ], | ||
4120 | 812 | [ 'Server' , "redhat" ], | ||
4121 | 813 | [ 'Client' , "redhat" ], | ||
4122 | 814 | [ 'SL' , "redhat" ], | ||
4123 | 815 | [ 'isolinux.bin', None ], | ||
4124 | 816 | ] | ||
4125 | 817 | guess = None | ||
4126 | 818 | |||
4127 | 819 | while kerneldir != os.path.dirname(path) : | ||
4128 | 820 | logger.info("scanning %s for distro signature" % kerneldir) | ||
4129 | 821 | for (x, breedguess) in signatures: | ||
4130 | 822 | d = os.path.join( kerneldir , x ) | ||
4131 | 823 | if os.path.exists( d ): | ||
4132 | 824 | guess = breedguess | ||
4133 | 825 | break | ||
4134 | 826 | if guess: | ||
4135 | 827 | break | ||
4136 | 828 | |||
4137 | 829 | kerneldir = os.path.dirname(kerneldir) | ||
4138 | 830 | else: | ||
4139 | 831 | if cli_breed: | ||
4140 | 832 | logger.info("Warning: No distro signature for kernel at %s, using value from command line" % kerneldir) | ||
4141 | 833 | return (cli_breed , kerneldir , None) | ||
4142 | 834 | utils.die(logger, "No distro signature for kernel at %s" % kerneldir ) | ||
4143 | 835 | |||
4144 | 836 | if guess == "debian" : | ||
4145 | 837 | for suite in [ "debian" , "ubuntu" ] : | ||
4146 | 838 | # NOTE : Although we break the loop after the first match, | ||
4147 | 839 | # multiple debian derived distros can actually live at the same pool -- JP | ||
4148 | 840 | d = os.path.join( kerneldir , suite ) | ||
4149 | 841 | if os.path.islink(d) and os.path.isdir(d): | ||
4150 | 842 | if os.path.realpath(d) == os.path.realpath(kerneldir): | ||
4151 | 843 | return (suite, kerneldir ,x) | ||
4152 | 844 | if os.path.basename( kerneldir ) == suite : | ||
4153 | 845 | return (suite , kerneldir , x) | ||
4154 | 846 | |||
4155 | 847 | return (guess, kerneldir , x) | ||
4156 | 848 | |||
4157 | 849 | # ============================================================ | ||
4158 | 850 | |||
4159 | 851 | |||
4160 | 852 | def import_factory(kerneldir,path,cli_breed,logger): | ||
4161 | 853 | """ | ||
4162 | 854 | Given a directory containing a kernel, return an instance of an Importer | ||
4163 | 855 | that can be used to complete the import. | ||
4164 | 856 | """ | ||
4165 | 857 | |||
4166 | 858 | breed , rootdir, pkgdir = guess_breed(kerneldir,path,cli_breed,logger) | ||
4167 | 859 | # NOTE : The guess_breed code should be included in the factory, in order to make | ||
4168 | 860 | # the real root directory available, so allowing kernels at different levels within | ||
4169 | 861 | # the same tree (removing the isolinux rejection from distro_adder) -- JP | ||
4170 | 862 | |||
4171 | 863 | if isinstance(rootdir, list): | ||
4172 | 864 | if rootdir[1]: | ||
4173 | 865 | logger.info("found content (breed=%s) at %s" % (breed,os.path.join( rootdir[0] , rootdir[1]))) | ||
4174 | 866 | else: | ||
4175 | 867 | logger.info("found content (breed=%s) at %s" % (breed,rootdir[0])) | ||
4176 | 868 | else: | ||
4177 | 869 | logger.info("found content (breed=%s) at %s" % (breed,rootdir)) | ||
4178 | 870 | |||
4179 | 871 | if cli_breed: | ||
4180 | 872 | if cli_breed != breed: | ||
4181 | 873 | utils.die(logger, "Requested breed (%s); breed found is %s" % ( cli_breed , breed ) ) | ||
4182 | 874 | breed = cli_breed | ||
4183 | 875 | |||
4184 | 876 | if breed == "redhat": | ||
4185 | 877 | return RedHatImporter(logger,rootdir,pkgdir) | ||
4186 | 878 | if breed == "vmware": | ||
4187 | 879 | return VMwareImporter(logger,rootdir,pkgdir) | ||
4188 | 880 | # disabled for 2.0 | ||
4189 | 881 | #elif breed == "debian": | ||
4190 | 882 | # return DebianImporter(logger,rootdir,pkgdir) | ||
4191 | 883 | #elif breed == "ubuntu": | ||
4192 | 884 | # return UbuntuImporter(logger,rootdir,pkgdir) | ||
4193 | 885 | elif breed: | ||
4194 | 886 | utils.die(logger, "Unsupported OS breed %s" % breed) | ||
4195 | 887 | |||
4196 | 888 | |||
4197 | 889 | class BaseImporter: | ||
4198 | 890 | """ | ||
4199 | 891 | Base class for distribution specific importer code. | ||
4200 | 892 | """ | ||
4201 | 893 | |||
4202 | 894 | # FIXME : Rename learn_arch_from_tree into guess_arch and simplify. | ||
4203 | 895 | # FIXME : Drop package extension check and make a single search for all names. | ||
4204 | 896 | # FIXME: Next methods to be moved here: kickstart_finder TRY_LIST loop | ||
4205 | 897 | |||
4206 | 898 | # =================================================================== | ||
4207 | 899 | |||
4208 | 900 | def arch_walker(self,foo,dirname,fnames): | ||
4209 | 901 | """ | ||
4210 | 902 | See docs on learn_arch_from_tree. | ||
4211 | 903 | |||
4212 | 904 | The TRY_LIST is used to speed up search, and should be dropped for default importer | ||
4213 | 905 | Searched kernel names are kernel-header, linux-headers-, kernel-largesmp, kernel-hugemem | ||
4214 | 906 | |||
4215 | 907 | This method is useful to get the archs, but also to package type and a raw guess of the breed | ||
4216 | 908 | """ | ||
4217 | 909 | |||
4218 | 910 | # try to find a kernel header RPM and then look at it's arch. | ||
4219 | 911 | for x in fnames: | ||
4220 | 912 | if self.match_kernelarch_file(x): | ||
4221 | 913 | for arch in [ "i386" , "x86_64" , "ia64" , "ppc64", "ppc", "s390", "s390x" ]: | ||
4222 | 914 | if x.find(arch) != -1: | ||
4223 | 915 | foo[arch] = 1 | ||
4224 | 916 | for arch in [ "i686" , "amd64" ]: | ||
4225 | 917 | if x.find(arch) != -1: | ||
4226 | 918 | foo[arch] = 1 | ||
4227 | 919 | |||
4228 | 920 | # =================================================================== | ||
4229 | 921 | |||
4230 | 922 | def get_rootdir(self): | ||
4231 | 923 | return self.rootdir | ||
4232 | 924 | |||
4233 | 925 | # =================================================================== | ||
4234 | 926 | |||
4235 | 927 | def get_pkgdir(self): | ||
4236 | 928 | if not self.pkgdir: | ||
4237 | 929 | return None | ||
4238 | 930 | return os.path.join(self.get_rootdir(),self.pkgdir) | ||
4239 | 931 | |||
4240 | 932 | # =================================================================== | ||
4241 | 933 | |||
4242 | 934 | def set_install_tree(self, distro, url): | ||
4243 | 935 | distro.ks_meta["tree"] = url | ||
4244 | 936 | |||
4245 | 937 | # =================================================================== | ||
4246 | 938 | |||
4247 | 939 | def learn_arch_from_tree(self): | ||
4248 | 940 | """ | ||
4249 | 941 | If a distribution is imported from DVD, there is a good chance the path doesn't | ||
4250 | 942 | contain the arch and we should add it back in so that it's part of the | ||
4251 | 943 | meaningful name ... so this code helps figure out the arch name. This is important | ||
4252 | 944 | for producing predictable distro names (and profile names) from differing import sources | ||
4253 | 945 | """ | ||
4254 | 946 | result = {} | ||
4255 | 947 | # FIXME : this is called only once, should not be a walk | ||
4256 | 948 | if self.get_pkgdir(): | ||
4257 | 949 | os.path.walk(self.get_pkgdir(), self.arch_walker, result) | ||
4258 | 950 | if result.pop("amd64",False): | ||
4259 | 951 | result["x86_64"] = 1 | ||
4260 | 952 | if result.pop("i686",False): | ||
4261 | 953 | result["i386"] = 1 | ||
4262 | 954 | return result.keys() | ||
4263 | 955 | |||
4264 | 956 | def get_datestamp(self): | ||
4265 | 957 | """ | ||
4266 | 958 | Allows each breed to return its datetime stamp | ||
4267 | 959 | """ | ||
4268 | 960 | return None | ||
4269 | 961 | # =================================================================== | ||
4270 | 962 | |||
4271 | 963 | def __init__(self,logger,rootdir,pkgdir): | ||
4272 | 964 | raise exceptions.NotImplementedError | ||
4273 | 965 | |||
4274 | 966 | # =================================================================== | ||
4275 | 967 | |||
4276 | 968 | def process_repos(self, main_importer, distro): | ||
4277 | 969 | raise exceptions.NotImplementedError | ||
4278 | 970 | |||
4279 | 971 | # =================================================================== | ||
4280 | 972 | # =================================================================== | ||
4281 | 973 | |||
4282 | 974 | class RedHatImporter ( BaseImporter ) : | ||
4283 | 975 | |||
4284 | 976 | def __init__(self,logger,rootdir,pkgdir): | ||
4285 | 977 | self.breed = "redhat" | ||
4286 | 978 | self.ks = "/var/lib/cobbler/kickstarts/default.ks" | ||
4287 | 979 | self.rootdir = rootdir | ||
4288 | 980 | self.pkgdir = pkgdir | ||
4289 | 981 | self.logger = logger | ||
4290 | 982 | |||
4291 | 983 | # ================================================================ | ||
4292 | 984 | |||
4293 | 985 | def get_release_files(self): | ||
4294 | 986 | data = glob.glob(os.path.join(self.get_pkgdir(), "*release-*")) | ||
4295 | 987 | data2 = [] | ||
4296 | 988 | for x in data: | ||
4297 | 989 | b = os.path.basename(x) | ||
4298 | 990 | if b.find("fedora") != -1 or \ | ||
4299 | 991 | b.find("redhat") != -1 or \ | ||
4300 | 992 | b.find("centos") != -1: | ||
4301 | 993 | data2.append(x) | ||
4302 | 994 | return data2 | ||
4303 | 995 | |||
4304 | 996 | # ================================================================ | ||
4305 | 997 | |||
4306 | 998 | def match_kernelarch_file(self, filename): | ||
4307 | 999 | """ | ||
4308 | 1000 | Is the given filename a kernel filename? | ||
4309 | 1001 | """ | ||
4310 | 1002 | |||
4311 | 1003 | if not filename.endswith("rpm") and not filename.endswith("deb"): | ||
4312 | 1004 | return False | ||
4313 | 1005 | for match in ["kernel-header", "kernel-source", "kernel-smp", "kernel-largesmp", "kernel-hugemem", "linux-headers-", "kernel-devel", "kernel-"]: | ||
4314 | 1006 | if filename.find(match) != -1: | ||
4315 | 1007 | return True | ||
4316 | 1008 | return False | ||
4317 | 1009 | |||
4318 | 1010 | # ================================================================ | ||
4319 | 1011 | |||
4320 | 1012 | def scan_pkg_filename(self, rpm): | ||
4321 | 1013 | """ | ||
4322 | 1014 | Determine what the distro is based on the release package filename. | ||
4323 | 1015 | """ | ||
4324 | 1016 | |||
4325 | 1017 | rpm = os.path.basename(rpm) | ||
4326 | 1018 | |||
4327 | 1019 | # if it looks like a RHEL RPM we'll cheat. | ||
4328 | 1020 | # it may be slightly wrong, but it will be close enough | ||
4329 | 1021 | # for RHEL5 we can get it exactly. | ||
4330 | 1022 | |||
4331 | 1023 | for x in [ "4AS", "4ES", "4WS", "4common", "4Desktop" ]: | ||
4332 | 1024 | if rpm.find(x) != -1: | ||
4333 | 1025 | return ("redhat", 4, 0) | ||
4334 | 1026 | for x in [ "3AS", "3ES", "3WS", "3Desktop" ]: | ||
4335 | 1027 | if rpm.find(x) != -1: | ||
4336 | 1028 | return ("redhat", 3, 0) | ||
4337 | 1029 | for x in [ "2AS", "2ES", "2WS", "2Desktop" ]: | ||
4338 | 1030 | if rpm.find(x) != -1: | ||
4339 | 1031 | return ("redhat", 2, 0) | ||
4340 | 1032 | |||
4341 | 1033 | # now get the flavor: | ||
4342 | 1034 | flavor = "redhat" | ||
4343 | 1035 | if rpm.lower().find("fedora") != -1: | ||
4344 | 1036 | flavor = "fedora" | ||
4345 | 1037 | if rpm.lower().find("centos") != -1: | ||
4346 | 1038 | flavor = "centos" | ||
4347 | 1039 | |||
4348 | 1040 | # get all the tokens and try to guess a version | ||
4349 | 1041 | accum = [] | ||
4350 | 1042 | tokens = rpm.split(".") | ||
4351 | 1043 | for t in tokens: | ||
4352 | 1044 | tokens2 = t.split("-") | ||
4353 | 1045 | for t2 in tokens2: | ||
4354 | 1046 | try: | ||
4355 | 1047 | float(t2) | ||
4356 | 1048 | accum.append(t2) | ||
4357 | 1049 | except: | ||
4358 | 1050 | pass | ||
4359 | 1051 | |||
4360 | 1052 | major = float(accum[0]) | ||
4361 | 1053 | minor = float(accum[1]) | ||
4362 | 1054 | return (flavor, major, minor) | ||
4363 | 1055 | |||
4364 | 1056 | def get_datestamp(self): | ||
4365 | 1057 | """ | ||
4366 | 1058 | Based on a RedHat tree find the creation timestamp | ||
4367 | 1059 | """ | ||
4368 | 1060 | base = self.get_rootdir() | ||
4369 | 1061 | if os.path.exists("%s/.discinfo" % base): | ||
4370 | 1062 | discinfo = open("%s/.discinfo" % base, "r") | ||
4371 | 1063 | datestamp = discinfo.read().split("\n")[0] | ||
4372 | 1064 | discinfo.close() | ||
4373 | 1065 | else: | ||
4374 | 1066 | return 0 | ||
4375 | 1067 | return float(datestamp) | ||
4376 | 1068 | |||
4377 | 1069 | def set_variance(self, flavor, major, minor, arch): | ||
4378 | 1070 | |||
4379 | 1071 | """ | ||
4380 | 1072 | find the profile kickstart and set the distro breed/os-version based on what | ||
4381 | 1073 | we can find out from the rpm filenames and then return the kickstart | ||
4382 | 1074 | path to use. | ||
4383 | 1075 | """ | ||
4384 | 1076 | |||
4385 | 1077 | if flavor == "fedora": | ||
4386 | 1078 | |||
4387 | 1079 | # this may actually fail because the libvirt/virtinst database | ||
4388 | 1080 | # is not always up to date. We keep a simplified copy of this | ||
4389 | 1081 | # in codes.py. If it fails we set it to something generic | ||
4390 | 1082 | # and don't worry about it. | ||
4391 | 1083 | |||
4392 | 1084 | try: | ||
4393 | 1085 | os_version = "fedora%s" % int(major) | ||
4394 | 1086 | except: | ||
4395 | 1087 | os_version = "other" | ||
4396 | 1088 | |||
4397 | 1089 | if flavor == "redhat" or flavor == "centos": | ||
4398 | 1090 | |||
4399 | 1091 | if major <= 2: | ||
4400 | 1092 | # rhel2.1 is the only rhel2 | ||
4401 | 1093 | os_version = "rhel2.1" | ||
4402 | 1094 | else: | ||
4403 | 1095 | try: | ||
4404 | 1096 | # must use libvirt version | ||
4405 | 1097 | os_version = "rhel%s" % (int(major)) | ||
4406 | 1098 | except: | ||
4407 | 1099 | os_version = "other" | ||
4408 | 1100 | |||
4409 | 1101 | kickbase = "/var/lib/cobbler/kickstarts" | ||
4410 | 1102 | # Look for ARCH/OS_VERSION.MINOR kickstart first | ||
4411 | 1103 | # ARCH/OS_VERSION next | ||
4412 | 1104 | # OS_VERSION next | ||
4413 | 1105 | # OS_VERSION.MINOR next | ||
4414 | 1106 | # ARCH/default.ks next | ||
4415 | 1107 | # FLAVOR.ks next | ||
4416 | 1108 | kickstarts = [ | ||
4417 | 1109 | "%s/%s/%s.%i.ks" % (kickbase,arch,os_version,int(minor)), | ||
4418 | 1110 | "%s/%s/%s.ks" % (kickbase,arch,os_version), | ||
4419 | 1111 | "%s/%s.%i.ks" % (kickbase,os_version,int(minor)), | ||
4420 | 1112 | "%s/%s.ks" % (kickbase,os_version), | ||
4421 | 1113 | "%s/%s/default.ks" % (kickbase,arch), | ||
4422 | 1114 | "%s/%s.ks" % (kickbase,flavor), | ||
4423 | 1115 | ] | ||
4424 | 1116 | for kickstart in kickstarts: | ||
4425 | 1117 | if os.path.exists(kickstart): | ||
4426 | 1118 | return os_version, kickstart | ||
4427 | 1119 | |||
4428 | 1120 | major = int(major) | ||
4429 | 1121 | |||
4430 | 1122 | if flavor == "fedora": | ||
4431 | 1123 | if major >= 8: | ||
4432 | 1124 | return os_version , "/var/lib/cobbler/kickstarts/sample_end.ks" | ||
4433 | 1125 | if major >= 6: | ||
4434 | 1126 | return os_version , "/var/lib/cobbler/kickstarts/sample.ks" | ||
4435 | 1127 | |||
4436 | 1128 | if flavor == "redhat" or flavor == "centos": | ||
4437 | 1129 | if major >= 5: | ||
4438 | 1130 | return os_version , "/var/lib/cobbler/kickstarts/sample.ks" | ||
4439 | 1131 | |||
4440 | 1132 | return os_version , "/var/lib/cobbler/kickstarts/legacy.ks" | ||
4441 | 1133 | |||
4442 | 1134 | self.logger.warning("could not use distro specifics, using rhel 4 compatible kickstart") | ||
4443 | 1135 | return None , "/var/lib/cobbler/kickstarts/legacy.ks" | ||
4444 | 1136 | |||
4445 | 1137 | |||
4446 | 1138 | class VMwareImporter (BaseImporter): | ||
4447 | 1139 | """ | ||
4448 | 1140 | VMware specific importer code. | ||
4449 | 1141 | """ | ||
4450 | 1142 | |||
4451 | 1143 | def __init__(self,logger,rootdir,pkgdir): | ||
4452 | 1144 | self.breed = "vmware" | ||
4453 | 1145 | self.ks = "/var/lib/cobbler/kickstarts/default.ks" | ||
4454 | 1146 | self.rootdir = rootdir | ||
4455 | 1147 | self.pkgdir = pkgdir | ||
4456 | 1148 | self.logger = logger | ||
4457 | 1149 | |||
4458 | 1150 | def learn_arch_from_tree(self): | ||
4459 | 1151 | """ | ||
4460 | 1152 | Attempt to figure out the arch from packages in the install tree. | ||
4461 | 1153 | ESX 4 and up is 64bit. | ||
4462 | 1154 | """ | ||
4463 | 1155 | result = ["x86_64"] | ||
4464 | 1156 | return result | ||
4465 | 1157 | |||
4466 | 1158 | def get_release_files(self): | ||
4467 | 1159 | """ | ||
4468 | 1160 | Find distro release packages. | ||
4469 | 1161 | """ | ||
4470 | 1162 | data = glob.glob(os.path.join(self.get_pkgdir(), "*release-*")) | ||
4471 | 1163 | data2 = [] | ||
4472 | 1164 | for x in data: | ||
4473 | 1165 | b = os.path.basename(x) | ||
4474 | 1166 | if b.find("vmware") != -1: | ||
4475 | 1167 | data2.append(x) | ||
4476 | 1168 | if len(data2) == 0: | ||
4477 | 1169 | # ESXi maybe? | ||
4478 | 1170 | return glob.glob(os.path.join(self.get_rootdir(), "imagedd.bz2*")) | ||
4479 | 1171 | return data2 | ||
4480 | 1172 | |||
4481 | 1173 | def scan_pkg_filename(self, rpm): | ||
4482 | 1174 | """ | ||
4483 | 1175 | Determine what the distro is based on the release package filename. | ||
4484 | 1176 | """ | ||
4485 | 1177 | rpm = os.path.basename(rpm) | ||
4486 | 1178 | |||
4487 | 1179 | if rpm.lower().find("-esx-") != -1: | ||
4488 | 1180 | flavor = "esx" | ||
4489 | 1181 | elif rpm.lower() == "imagedd.bz2": | ||
4490 | 1182 | flavor = "esxi" | ||
4491 | 1183 | |||
4492 | 1184 | match = re.search(r'^([\-a-zA-Z0-9]+)-([\.0-9]+)-([\.0-9]+)\.', rpm) | ||
4493 | 1185 | if match: | ||
4494 | 1186 | (name, version, release) = [match.group(1), match.group(2), match.group(3)] | ||
4495 | 1187 | major = version.split('.')[0] | ||
4496 | 1188 | minor = release.split('.')[0] | ||
4497 | 1189 | else: | ||
4498 | 1190 | # FIXME: better major/minor detection for esxi | ||
4499 | 1191 | # or if the match falls through for some reason | ||
4500 | 1192 | major = 4 | ||
4501 | 1193 | minor = 0 | ||
4502 | 1194 | |||
4503 | 1195 | return (flavor, major, minor) | ||
4504 | 1196 | |||
4505 | 1197 | def set_variance(self, flavor, major, minor, arch): | ||
4506 | 1198 | """ | ||
4507 | 1199 | Set distro specific versioning. | ||
4508 | 1200 | """ | ||
4509 | 1201 | os_version = "%s%s" % (flavor, major) | ||
4510 | 1202 | return os_version , "/var/lib/cobbler/kickstarts/default.ks" | ||
4511 | 1203 | |||
4512 | 1204 | |||
4513 | 1205 | def get_datestamp(self): | ||
4514 | 1206 | """ | ||
4515 | 1207 | Based on a VMWare tree find the creation timestamp | ||
4516 | 1208 | """ | ||
4517 | 1209 | pass | ||
4518 | 1210 | |||
4519 | 1211 | #class DebianImporter ( BaseImporter ) : | ||
4520 | 1212 | # | ||
4521 | 1213 | # def __init__(self,logger,rootdir,pkgdir): | ||
4522 | 1214 | # self.breed = "debian" | ||
4523 | 1215 | # self.ks = "/var/lib/cobbler/kickstarts/sample.seed" | ||
4524 | 1216 | # self.rootdir = rootdir | ||
4525 | 1217 | # self.pkgdir = pkgdir | ||
4526 | 1218 | # self.logger = logger | ||
4527 | 1219 | # | ||
4528 | 1220 | # def get_release_files(self): | ||
4529 | 1221 | # if not self.get_pkgdir(): | ||
4530 | 1222 | # return [] | ||
4531 | 1223 | # # search for base-files or base-installer ? | ||
4532 | 1224 | # return glob.glob(os.path.join(self.get_pkgdir(), "main/b/base-files" , "base-files_*")) | ||
4533 | 1225 | # | ||
4534 | 1226 | # def match_kernelarch_file(self, filename): | ||
4535 | 1227 | # if not filename.endswith("deb"): | ||
4536 | 1228 | # return False | ||
4537 | 1229 | # if filename.startswith("linux-headers-"): | ||
4538 | 1230 | # return True | ||
4539 | 1231 | # return False | ||
4540 | 1232 | # | ||
4541 | 1233 | # def scan_pkg_filename(self, deb): | ||
4542 | 1234 | # | ||
4543 | 1235 | # deb = os.path.basename(deb) | ||
4544 | 1236 | # self.logger.info("processing deb : %s" % deb) | ||
4545 | 1237 | # | ||
4546 | 1238 | # # get all the tokens and try to guess a version | ||
4547 | 1239 | # accum = [] | ||
4548 | 1240 | # tokens = deb.split("_") | ||
4549 | 1241 | # tokens2 = tokens[1].split(".") | ||
4550 | 1242 | # for t2 in tokens2: | ||
4551 | 1243 | # try: | ||
4552 | 1244 | # val = int(t2) | ||
4553 | 1245 | # accum.append(val) | ||
4554 | 1246 | # except: | ||
4555 | 1247 | # pass | ||
4556 | 1248 | # # Safeguard for non-guessable versions | ||
4557 | 1249 | # if not accum: | ||
4558 | 1250 | # return None | ||
4559 | 1251 | # accum.append(0) | ||
4560 | 1252 | # | ||
4561 | 1253 | # return (None, accum[0], accum[1]) | ||
4562 | 1254 | # | ||
4563 | 1255 | # def set_variance(self, flavor, major, minor, arch): | ||
4564 | 1256 | # | ||
4565 | 1257 | # dist_names = { '4.0' : "etch" , '5.0' : "lenny" } | ||
4566 | 1258 | # dist_vers = "%s.%s" % ( major , minor ) | ||
4567 | 1259 | # os_version = dist_names[dist_vers] | ||
4568 | 1260 | # | ||
4569 | 1261 | # return os_version , "/var/lib/cobbler/kickstarts/sample.seed" | ||
4570 | 1262 | # | ||
4571 | 1263 | # def set_install_tree(self, distro, url): | ||
4572 | 1264 | # idx = url.find("://") | ||
4573 | 1265 | # url = url[idx+3:] | ||
4574 | 1266 | # | ||
4575 | 1267 | # idx = url.find("/") | ||
4576 | 1268 | # distro.ks_meta["hostname"] = url[:idx] | ||
4577 | 1269 | # distro.ks_meta["directory"] = url[idx:] | ||
4578 | 1270 | # if not distro.os_version : | ||
4579 | 1271 | # utils.die(self.logger, "OS version is required for debian distros") | ||
4580 | 1272 | # distro.ks_meta["suite"] = distro.os_version | ||
4581 | 1273 | # | ||
4582 | 1274 | # def process_repos(self, main_importer, distro): | ||
4583 | 1275 | # | ||
4584 | 1276 | # # Create a disabled repository for the new distro, and the security updates | ||
4585 | 1277 | # # | ||
4586 | 1278 | # # NOTE : We cannot use ks_meta nor os_version because they get fixed at a later stage | ||
4587 | 1279 | # | ||
4588 | 1280 | # repo = item_repo.Repo(main_importer.config) | ||
4589 | 1281 | # repo.set_breed( "apt" ) | ||
4590 | 1282 | # repo.set_arch( distro.arch ) | ||
4591 | 1283 | # repo.set_keep_updated( False ) | ||
4592 | 1284 | # repo.yumopts["--ignore-release-gpg"] = None | ||
4593 | 1285 | # repo.yumopts["--verbose"] = None | ||
4594 | 1286 | # repo.set_name( distro.name ) | ||
4595 | 1287 | # repo.set_os_version( distro.os_version ) | ||
4596 | 1288 | # # NOTE : The location of the mirror should come from timezone | ||
4597 | 1289 | # repo.set_mirror( "http://ftp.%s.debian.org/debian/dists/%s" % ( 'us' , '@@suite@@' ) ) | ||
4598 | 1290 | # | ||
4599 | 1291 | # security_repo = item_repo.Repo(main_importer.config) | ||
4600 | 1292 | # security_repo.set_breed( "apt" ) | ||
4601 | 1293 | # security_repo.set_arch( distro.arch ) | ||
4602 | 1294 | # security_repo.set_keep_updated( False ) | ||
4603 | 1295 | # security_repo.yumopts["--ignore-release-gpg"] = None | ||
4604 | 1296 | # security_repo.yumopts["--verbose"] = None | ||
4605 | 1297 | # security_repo.set_name( distro.name + "-security" ) | ||
4606 | 1298 | # security_repo.set_os_version( distro.os_version ) | ||
4607 | 1299 | # # There are no official mirrors for security updates | ||
4608 | 1300 | # security_repo.set_mirror( "http://security.debian.org/debian-security/dists/%s/updates" % '@@suite@@' ) | ||
4609 | 1301 | # | ||
4610 | 1302 | # self.logger.info("Added repos for %s" % distro.name) | ||
4611 | 1303 | # repos = main_importer.config.repos() | ||
4612 | 1304 | # repos.add(repo,save=True) | ||
4613 | 1305 | # repos.add(security_repo,save=True) | ||
4614 | 1306 | |||
4615 | 1307 | |||
4616 | 1308 | #class UbuntuImporter ( DebianImporter ) : | ||
4617 | 1309 | # | ||
4618 | 1310 | # def __init__(self,rootdir,pkgdir): | ||
4619 | 1311 | # DebianImporter.__init__(self,rootdir,pkgdir) | ||
4620 | 1312 | # self.breed = "ubuntu" | ||
4621 | 1313 | # | ||
4622 | 1314 | # def get_release_files(self): | ||
4623 | 1315 | # if not self.get_pkgdir(): | ||
4624 | 1316 | # return [] | ||
4625 | 1317 | # return glob.glob(os.path.join(self.get_pkgdir(), "main/u/ubuntu-docs" , "ubuntu-docs_*")) | ||
4626 | 1318 | # | ||
4627 | 1319 | # def set_variance(self, flavor, major, minor, arch): | ||
4628 | 1320 | # | ||
4629 | 1321 | # # Release names taken from wikipedia | ||
4630 | 1322 | # dist_names = { '6.4':"dapper", '8.4':"hardy", '8.10':"intrepid", '9.4':"jaunty" } | ||
4631 | 1323 | # dist_vers = "%s.%s" % ( major , minor ) | ||
4632 | 1324 | # if not dist_names.has_key( dist_vers ): | ||
4633 | 1325 | # dist_names['4ubuntu2.0'] = "IntrepidIbex" | ||
4634 | 1326 | # os_version = dist_names[dist_vers] | ||
4635 | 1327 | # | ||
4636 | 1328 | # return os_version , "/var/lib/cobbler/kickstarts/sample.seed" | ||
4637 | 1329 | # | ||
4638 | 1330 | # def process_repos(self, main_importer, distro): | ||
4639 | 1331 | # | ||
4640 | 1332 | # pass | ||
4641 | 0 | 1333 | ||
4642 | === added file 'cobbler/action_litesync.py' | |||
4643 | --- cobbler/action_litesync.py 1970-01-01 00:00:00 +0000 | |||
4644 | +++ cobbler/action_litesync.py 2011-03-11 21:10:49 +0000 | |||
4645 | @@ -0,0 +1,167 @@ | |||
4646 | 1 | """ | ||
4647 | 2 | Running small pieces of cobbler sync when certain actions are taken, | ||
4648 | 3 | such that we don't need a time consuming sync when adding new | ||
4649 | 4 | systems if nothing has changed for systems that have already | ||
4650 | 5 | been created. | ||
4651 | 6 | |||
4652 | 7 | Copyright 2006-2009, Red Hat, Inc | ||
4653 | 8 | Michael DeHaan <mdehaan@redhat.com> | ||
4654 | 9 | |||
4655 | 10 | This program is free software; you can redistribute it and/or modify | ||
4656 | 11 | it under the terms of the GNU General Public License as published by | ||
4657 | 12 | the Free Software Foundation; either version 2 of the License, or | ||
4658 | 13 | (at your option) any later version. | ||
4659 | 14 | |||
4660 | 15 | This program is distributed in the hope that it will be useful, | ||
4661 | 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4662 | 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4663 | 18 | GNU General Public License for more details. | ||
4664 | 19 | |||
4665 | 20 | You should have received a copy of the GNU General Public License | ||
4666 | 21 | along with this program; if not, write to the Free Software | ||
4667 | 22 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
4668 | 23 | 02110-1301 USA | ||
4669 | 24 | """ | ||
4670 | 25 | |||
4671 | 26 | import os | ||
4672 | 27 | import os.path | ||
4673 | 28 | |||
4674 | 29 | import utils | ||
4675 | 30 | import traceback | ||
4676 | 31 | import clogger | ||
4677 | 32 | import module_loader | ||
4678 | 33 | |||
4679 | 34 | class BootLiteSync: | ||
4680 | 35 | """ | ||
4681 | 36 | Handles conversion of internal state to the tftpboot tree layout | ||
4682 | 37 | """ | ||
4683 | 38 | |||
4684 | 39 | def __init__(self,config,verbose=False,logger=None): | ||
4685 | 40 | """ | ||
4686 | 41 | Constructor | ||
4687 | 42 | """ | ||
4688 | 43 | self.verbose = verbose | ||
4689 | 44 | self.config = config | ||
4690 | 45 | self.distros = config.distros() | ||
4691 | 46 | self.profiles = config.profiles() | ||
4692 | 47 | self.systems = config.systems() | ||
4693 | 48 | self.images = config.images() | ||
4694 | 49 | self.settings = config.settings() | ||
4695 | 50 | self.repos = config.repos() | ||
4696 | 51 | if logger is None: | ||
4697 | 52 | logger = clogger.Logger() | ||
4698 | 53 | self.logger = logger | ||
4699 | 54 | self.tftpd = module_loader.get_module_from_file( | ||
4700 | 55 | "tftpd","module","in_tftpd" | ||
4701 | 56 | ).get_manager(config,logger) | ||
4702 | 57 | self.sync = config.api.get_sync(verbose,logger=self.logger) | ||
4703 | 58 | self.sync.make_tftpboot() | ||
4704 | 59 | |||
4705 | 60 | def add_single_distro(self, name): | ||
4706 | 61 | # get the distro record | ||
4707 | 62 | distro = self.distros.find(name=name) | ||
4708 | 63 | if distro is None: | ||
4709 | 64 | return | ||
4710 | 65 | # copy image files to images/$name in webdir & tftpboot: | ||
4711 | 66 | self.sync.pxegen.copy_single_distro_files(distro, | ||
4712 | 67 | self.settings.webdir,True) | ||
4713 | 68 | self.tftpd.add_single_distro(distro) | ||
4714 | 69 | |||
4715 | 70 | # generate any templates listed in the distro | ||
4716 | 71 | self.sync.pxegen.write_templates(distro) | ||
4717 | 72 | # cascade sync | ||
4718 | 73 | kids = distro.get_children() | ||
4719 | 74 | for k in kids: | ||
4720 | 75 | self.add_single_profile(k.name, rebuild_menu=False) | ||
4721 | 76 | self.sync.pxegen.make_pxe_menu() | ||
4722 | 77 | |||
4723 | 78 | |||
4724 | 79 | def add_single_image(self, name): | ||
4725 | 80 | image = self.images.find(name=name) | ||
4726 | 81 | self.sync.pxegen.copy_single_image_files(image) | ||
4727 | 82 | kids = image.get_children() | ||
4728 | 83 | for k in kids: | ||
4729 | 84 | self.add_single_system(k.name) | ||
4730 | 85 | self.sync.pxegen.make_pxe_menu() | ||
4731 | 86 | |||
4732 | 87 | def remove_single_distro(self, name): | ||
4733 | 88 | bootloc = utils.tftpboot_location() | ||
4734 | 89 | # delete contents of images/$name directory in webdir | ||
4735 | 90 | utils.rmtree(os.path.join(self.settings.webdir, "images", name)) | ||
4736 | 91 | # delete contents of images/$name in tftpboot | ||
4737 | 92 | utils.rmtree(os.path.join(bootloc, "images", name)) | ||
4738 | 93 | # delete potential symlink to tree in webdir/links | ||
4739 | 94 | utils.rmfile(os.path.join(self.settings.webdir, "links", name)) | ||
4740 | 95 | |||
4741 | 96 | def remove_single_image(self, name): | ||
4742 | 97 | bootloc = utils.tftpboot_location() | ||
4743 | 98 | utils.rmfile(os.path.join(bootloc, "images2", name)) | ||
4744 | 99 | |||
4745 | 100 | def add_single_profile(self, name, rebuild_menu=True): | ||
4746 | 101 | # get the profile object: | ||
4747 | 102 | profile = self.profiles.find(name=name) | ||
4748 | 103 | if profile is None: | ||
4749 | 104 | # most likely a subprofile's kid has been | ||
4750 | 105 | # removed already, though the object tree has | ||
4751 | 106 | # not been reloaded ... and this is just noise. | ||
4752 | 107 | return | ||
4753 | 108 | # rebuild the yum configuration files for any attached repos | ||
4754 | 109 | # generate any templates listed in the distro | ||
4755 | 110 | self.sync.pxegen.write_templates(profile) | ||
4756 | 111 | # cascade sync | ||
4757 | 112 | kids = profile.get_children() | ||
4758 | 113 | for k in kids: | ||
4759 | 114 | if k.COLLECTION_TYPE == "profile": | ||
4760 | 115 | self.add_single_profile(k.name, rebuild_menu=False) | ||
4761 | 116 | else: | ||
4762 | 117 | self.add_single_system(k.name) | ||
4763 | 118 | if rebuild_menu: | ||
4764 | 119 | self.sync.pxegen.make_pxe_menu() | ||
4765 | 120 | return True | ||
4766 | 121 | |||
4767 | 122 | def remove_single_profile(self, name, rebuild_menu=True): | ||
4768 | 123 | # delete profiles/$name file in webdir | ||
4769 | 124 | utils.rmfile(os.path.join(self.settings.webdir, "profiles", name)) | ||
4770 | 125 | # delete contents on kickstarts/$name directory in webdir | ||
4771 | 126 | utils.rmtree(os.path.join(self.settings.webdir, "kickstarts", name)) | ||
4772 | 127 | if rebuild_menu: | ||
4773 | 128 | self.sync.pxegen.make_pxe_menu() | ||
4774 | 129 | |||
4775 | 130 | def update_system_netboot_status(self,name): | ||
4776 | 131 | self.tftpd.update_netboot(name) | ||
4777 | 132 | |||
4778 | 133 | def add_single_system(self, name): | ||
4779 | 134 | # get the system object: | ||
4780 | 135 | system = self.systems.find(name=name) | ||
4781 | 136 | if system is None: | ||
4782 | 137 | return | ||
4783 | 138 | # rebuild system_list file in webdir | ||
4784 | 139 | if self.settings.manage_dhcp: | ||
4785 | 140 | self.sync.dhcp.regen_ethers() | ||
4786 | 141 | if self.settings.manage_dns: | ||
4787 | 142 | self.sync.dns.regen_hosts() | ||
4788 | 143 | # write the PXE files for the system | ||
4789 | 144 | self.tftpd.add_single_system(system) | ||
4790 | 145 | |||
4791 | 146 | def remove_single_system(self, name): | ||
4792 | 147 | bootloc = utils.tftpboot_location() | ||
4793 | 148 | system_record = self.systems.find(name=name) | ||
4794 | 149 | # delete contents of kickstarts_sys/$name in webdir | ||
4795 | 150 | system_record = self.systems.find(name=name) | ||
4796 | 151 | |||
4797 | 152 | itanic = False | ||
4798 | 153 | profile = self.profiles.find(name=system_record.profile) | ||
4799 | 154 | if profile is not None: | ||
4800 | 155 | distro = self.distros.find(name=profile.get_conceptual_parent().name) | ||
4801 | 156 | if distro is not None and distro in [ "ia64", "IA64"]: | ||
4802 | 157 | itanic = True | ||
4803 | 158 | |||
4804 | 159 | for (name,interface) in system_record.interfaces.iteritems(): | ||
4805 | 160 | filename = utils.get_config_filename(system_record,interface=name) | ||
4806 | 161 | |||
4807 | 162 | if not itanic: | ||
4808 | 163 | utils.rmfile(os.path.join(bootloc, "pxelinux.cfg", filename)) | ||
4809 | 164 | utils.rmfile(os.path.join(bootloc, "grub", filename.upper())) | ||
4810 | 165 | else: | ||
4811 | 166 | utils.rmfile(os.path.join(bootloc, filename)) | ||
4812 | 167 | |||
4813 | 0 | 168 | ||
4814 | === added file 'cobbler/action_log.py' | |||
4815 | --- cobbler/action_log.py 1970-01-01 00:00:00 +0000 | |||
4816 | +++ cobbler/action_log.py 2011-03-11 21:10:49 +0000 | |||
4817 | @@ -0,0 +1,71 @@ | |||
4818 | 1 | """ | ||
4819 | 2 | |||
4820 | 3 | Copyright 2009, Red Hat, Inc | ||
4821 | 4 | Bill Peck <bpeck@redhat.com> | ||
4822 | 5 | |||
4823 | 6 | This program is free software; you can redistribute it and/or modify | ||
4824 | 7 | it under the terms of the GNU General Public License as published by | ||
4825 | 8 | the Free Software Foundation; either version 2 of the License, or | ||
4826 | 9 | (at your option) any later version. | ||
4827 | 10 | |||
4828 | 11 | This program is distributed in the hope that it will be useful, | ||
4829 | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4830 | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4831 | 14 | GNU General Public License for more details. | ||
4832 | 15 | |||
4833 | 16 | You should have received a copy of the GNU General Public License | ||
4834 | 17 | along with this program; if not, write to the Free Software | ||
4835 | 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
4836 | 19 | 02110-1301 USA | ||
4837 | 20 | """ | ||
4838 | 21 | |||
4839 | 22 | |||
4840 | 23 | import os | ||
4841 | 24 | import os.path | ||
4842 | 25 | import sys | ||
4843 | 26 | import traceback | ||
4844 | 27 | import clogger | ||
4845 | 28 | |||
4846 | 29 | import utils | ||
4847 | 30 | from cexceptions import * | ||
4848 | 31 | import glob | ||
4849 | 32 | |||
4850 | 33 | class LogTool: | ||
4851 | 34 | """ | ||
4852 | 35 | Helpers for dealing with System logs, consoles, anamon, etc.. | ||
4853 | 36 | """ | ||
4854 | 37 | |||
4855 | 38 | def __init__(self,config,system,api,logger=None): | ||
4856 | 39 | """ | ||
4857 | 40 | Log library constructor requires a cobbler system object. | ||
4858 | 41 | """ | ||
4859 | 42 | self.system = system | ||
4860 | 43 | self.config = config | ||
4861 | 44 | self.settings = config.settings() | ||
4862 | 45 | self.api = api | ||
4863 | 46 | if logger is None: | ||
4864 | 47 | logger = clogger.Logger() | ||
4865 | 48 | self.logger = logger | ||
4866 | 49 | |||
4867 | 50 | |||
4868 | 51 | def clear(self): | ||
4869 | 52 | """ | ||
4870 | 53 | Clears the system logs | ||
4871 | 54 | """ | ||
4872 | 55 | |||
4873 | 56 | #FIXME /var/consoles should come from config.settings() | ||
4874 | 57 | logs = ['/var/consoles/%s' % self.system.name] | ||
4875 | 58 | anamon_dir = '/var/log/cobbler/anamon/%s' % self.system.name | ||
4876 | 59 | if os.path.isdir(anamon_dir): | ||
4877 | 60 | logs.extend(filter(os.path.isfile, glob.glob('%s/*' % anamon_dir))) | ||
4878 | 61 | for log in logs: | ||
4879 | 62 | try: | ||
4880 | 63 | f = open(log, 'w') | ||
4881 | 64 | f.truncate() | ||
4882 | 65 | f.close() | ||
4883 | 66 | except IOError, e: | ||
4884 | 67 | self.logger.info("Failed to Truncate '%s':%s " % (log, e)) | ||
4885 | 68 | except OSError, e: | ||
4886 | 69 | self.logger.info("Failed to Truncate '%s':%s " % (log, e)) | ||
4887 | 70 | return 0 | ||
4888 | 71 | |||
4889 | 0 | 72 | ||
4890 | === added file 'cobbler/action_power.py' | |||
4891 | --- cobbler/action_power.py 1970-01-01 00:00:00 +0000 | |||
4892 | +++ cobbler/action_power.py 2011-03-11 21:10:49 +0000 | |||
4893 | @@ -0,0 +1,150 @@ | |||
4894 | 1 | """ | ||
4895 | 2 | Power management library. For cobbler objects with power management configured | ||
4896 | 3 | encapsulate the logic to run power management commands so that the admin does not | ||
4897 | 4 | have to use seperate tools and remember how each of the power management tools are | ||
4898 | 5 | set up. This makes power cycling a system for reinstallation much easier. | ||
4899 | 6 | |||
4900 | 7 | See https://fedorahosted.org/cobbler/wiki/PowerManagement | ||
4901 | 8 | |||
4902 | 9 | Copyright 2008-2009, Red Hat, Inc | ||
4903 | 10 | Michael DeHaan <mdehaan@redhat.com> | ||
4904 | 11 | |||
4905 | 12 | This program is free software; you can redistribute it and/or modify | ||
4906 | 13 | it under the terms of the GNU General Public License as published by | ||
4907 | 14 | the Free Software Foundation; either version 2 of the License, or | ||
4908 | 15 | (at your option) any later version. | ||
4909 | 16 | |||
4910 | 17 | This program is distributed in the hope that it will be useful, | ||
4911 | 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4912 | 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
4913 | 20 | GNU General Public License for more details. | ||
4914 | 21 | |||
4915 | 22 | You should have received a copy of the GNU General Public License | ||
4916 | 23 | along with this program; if not, write to the Free Software | ||
4917 | 24 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
4918 | 25 | 02110-1301 USA | ||
4919 | 26 | """ | ||
4920 | 27 | |||
4921 | 28 | |||
4922 | 29 | import os | ||
4923 | 30 | import os.path | ||
4924 | 31 | import traceback | ||
4925 | 32 | import time | ||
4926 | 33 | import re | ||
4927 | 34 | |||
4928 | 35 | import utils | ||
4929 | 36 | import func_utils | ||
4930 | 37 | from cexceptions import * | ||
4931 | 38 | import templar | ||
4932 | 39 | import clogger | ||
4933 | 40 | |||
4934 | 41 | class PowerTool: | ||
4935 | 42 | """ | ||
4936 | 43 | Handles conversion of internal state to the tftpboot tree layout | ||
4937 | 44 | """ | ||
4938 | 45 | |||
4939 | 46 | def __init__(self,config,system,api,force_user=None,force_pass=None,logger=None): | ||
4940 | 47 | """ | ||
4941 | 48 | Power library constructor requires a cobbler system object. | ||
4942 | 49 | """ | ||
4943 | 50 | self.system = system | ||
4944 | 51 | self.config = config | ||
4945 | 52 | self.settings = config.settings() | ||
4946 | 53 | self.api = api | ||
4947 | 54 | self.logger = self.api.logger | ||
4948 | 55 | self.force_user = force_user | ||
4949 | 56 | self.force_pass = force_pass | ||
4950 | 57 | if logger is None: | ||
4951 | 58 | logger = clogger.Logger() | ||
4952 | 59 | self.logger = logger | ||
4953 | 60 | |||
4954 | 61 | def power(self, desired_state): | ||
4955 | 62 | """ | ||
4956 | 63 | state is either "on" or "off". Rebooting is implemented at the api.py | ||
4957 | 64 | level. | ||
4958 | 65 | |||
4959 | 66 | The user and password need not be supplied. If not supplied they | ||
4960 | 67 | will be taken from the environment, COBBLER_POWER_USER and COBBLER_POWER_PASS. | ||
4961 | 68 | If provided, these will override any other data and be used instead. Users | ||
4962 | 69 | interested in maximum security should take that route. | ||
4963 | 70 | """ | ||
4964 | 71 | |||
4965 | 72 | template = self.get_command_template() | ||
4966 | 73 | template_file = open(template, "r") | ||
4967 | 74 | |||
4968 | 75 | meta = utils.blender(self.api, False, self.system) | ||
4969 | 76 | meta["power_mode"] = desired_state | ||
4970 | 77 | |||
4971 | 78 | # allow command line overrides of the username/password | ||
4972 | 79 | if self.force_user is not None: | ||
4973 | 80 | meta["power_user"] = self.force_user | ||
4974 | 81 | if self.force_pass is not None: | ||
4975 | 82 | meta["power_pass"] = self.force_pass | ||
4976 | 83 | |||
4977 | 84 | tmp = templar.Templar(self.api._config) | ||
4978 | 85 | cmd = tmp.render(template_file, meta, None, self.system) | ||
4979 | 86 | template_file.close() | ||
4980 | 87 | |||
4981 | 88 | cmd = cmd.strip() | ||
4982 | 89 | |||
4983 | 90 | self.logger.info("cobbler power configuration is:") | ||
4984 | 91 | |||
4985 | 92 | self.logger.info(" type : %s" % self.system.power_type) | ||
4986 | 93 | self.logger.info(" address: %s" % self.system.power_address) | ||
4987 | 94 | self.logger.info(" user : %s" % self.system.power_user) | ||
4988 | 95 | self.logger.info(" id : %s" % self.system.power_id) | ||
4989 | 96 | |||
4990 | 97 | # if no username/password data, check the environment | ||
4991 | 98 | |||
4992 | 99 | if meta.get("power_user","") == "": | ||
4993 | 100 | meta["power_user"] = os.environ.get("COBBLER_POWER_USER","") | ||
4994 | 101 | if meta.get("power_pass","") == "": | ||
4995 | 102 | meta["power_pass"] = os.environ.get("COBBLER_POWER_PASS","") | ||
4996 | 103 | |||
4997 | 104 | self.logger.info("- %s" % cmd) | ||
4998 | 105 | |||
4999 | 106 | # use shell so we can have mutliple power commands chained together | ||
5000 | 107 | cmd = ['/bin/sh','-c', cmd] |
The diff has been truncated for viewing.