mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-30 01:26:38 +00:00
Initial xCAT 2.0 import
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
abc365a315
commit
c99d72a179
42
QUICKSTART
Normal file
42
QUICKSTART
Normal file
@ -0,0 +1,42 @@
|
||||
This is at this point essentially a demo of xCAT 2.0 concepts.
|
||||
|
||||
Currently, all it can do is the set of out-of-band management of IPMI systems.
|
||||
|
||||
To see how it works:
|
||||
./rpminstallperlxcat
|
||||
./rpminstallserver
|
||||
(at this point it will list failed dependencies probably, have fun filling those,
|
||||
SLES10 includes the SSL one, and SLES10 sdk has perl-XML-Simple,
|
||||
the details of making these deps easy is a TODO for 1.3 release)
|
||||
./rpminstallclient
|
||||
|
||||
|
||||
Now that it is installed, setup of the security for 1.2 like operation:
|
||||
/usr/share/xcat/scripts/setup-xcat-ca.sh
|
||||
(put whatever common name you want)
|
||||
/usr/share/xcat/scripts/setup-server-cert.sh
|
||||
(name something for your server, say y twice)
|
||||
/usr/share/xcat/scripts/setup-local-client.sh
|
||||
(use the name root for now)
|
||||
|
||||
chtab key=xcatdport site.value=3002 (using 3002 so you can use it on an xcat 1.2 server without worry)
|
||||
|
||||
(now assuming setup for a node called node1 with a bmc called node1-bmc)
|
||||
chtab node=node1 nodelist.groups=ipmi
|
||||
chtab node=ipmi nodehm.mgt=ipmi ipmi.bmc='/\z/-bmc/'
|
||||
|
||||
(start xcatd)
|
||||
xcatd & (the warnings are not actually useful to correct now, so don't worry)
|
||||
|
||||
export XCATHOST=localhost:3002
|
||||
testclient power node1 stat
|
||||
|
||||
(should work, number of commands will work, obviously the name indicates I haven't bother with the shorter
|
||||
rpower/rinv/rvitals names yet, but it will come, also obviously since the client can do everything,
|
||||
it will be busybox like most likely)
|
||||
|
||||
To add another node2 with same name scheme as node1:
|
||||
chtab node=node2 nodelist.groups=ipmi
|
||||
(can immediately start rpowering)
|
||||
|
||||
|
27
doc/configuration.pod
Normal file
27
doc/configuration.pod
Normal file
@ -0,0 +1,27 @@
|
||||
=pod
|
||||
|
||||
=head1 xCAT configuration core architecture
|
||||
|
||||
xCAT configuration spans a number of tables, some with records associated with particular nodes (such as nodelist and nodehm) and others that do not have a direct relationship with any given node.
|
||||
|
||||
The tables not associated with a given node are straightforward, the data is stored and retrieved as-is from the database without interpretation, and without any configuration layer inheritance (though some calling code may have an internal concept of inheritance with such fields, the core configuration will have no facilities to explicitly aid this.
|
||||
|
||||
The tables with records typically retrieved by node name have some extra features to enable a more template-based style to be used:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Any tagname can be used in lieu of a node name under the node field, and that record will then be taken to be applicable to any node with that tag. If a field is requested for a specific node, and either a record doesn't exist specifically for that nodename or a record exists, but has no definition for the requested field, that nodes tags are then used to search for general level records. If multiple records could apply from two different tags, the precedence is TBD. This is nearly identical to most xCAT 1.x tab file conventions. This is useful in tables such as noderes, where typical configurations have exactly the same field values for large sets of nodes.
|
||||
|
||||
=item *
|
||||
|
||||
xCAT 2 extends the above to be made useful where a field will vary for every node with a given tag, but in ways that would be trivial to describe. If a field is of the format /I<pattern>/I<replacement>/, it is taken to be a perl regular expression, to be performed on the nodename. For example, the bmc field of the ipmi table might be /\z/-bmc/ for a record with node=ipmi to specify that the BMC hostname is derived by appending -bmc to the end of the nodename of every node tagged ipmi. This is useful in tables such as ipmi.
|
||||
|
||||
=item *
|
||||
|
||||
As an extension to the above, a regular expression extended with arithmetic operators is available, by using the format |I<pattern>|I<replacement>|. This behaves similarly to the above, but () enclosed parts in I<replacement> are taken to signify arithmetic operations and substituted in. All operations are integer arithmetic, so 5/4 would come out as 1. The typical perl positional variables are available in such expressions. For example, the mpa field of the mp table for node=blade might be |\D+(\d+)|bc((${1}-1)/14+1)|. Specifically in this case, if you had a node named blade572 tagged blade, the 572 would be set to ${1} by the left hand parentheses, and on the right hand, that would become bc((572-1/14+1)), and finally evaluated and returned as bc41. To complete the example, the id field of mp would be |\D+(\d+)|((${1}-1)%14+1)|, which upon evaluation indicates slot 12. This is useful for tables that call out infrastructure devices/port numbers, such as switch, nodehm (for terminal servers), and mp (for IBM Bladecenter configurations).
|
||||
|
||||
=back
|
||||
|
||||
An administrator may chose to ignore any and all of the functions. For example, an administrator may chose to only make use of the first mentioned feature, and preserve an xCAT 1.x layout for their tables.
|
29
makeclientrpm
Executable file
29
makeclientrpm
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/ksh
|
||||
|
||||
OSNAME=$(uname)
|
||||
|
||||
if [ "$OSNAME" = "AIX" ]
|
||||
then
|
||||
|
||||
tar -cvf xCAT-client-2.0.tar xCAT-client-2.0
|
||||
gzip xCAT-client-2.0.tar
|
||||
cp xCAT-client-2.0.tar.gz /opt/freeware/src/packages/SOURCES
|
||||
cd ./xCAT-client-2.0
|
||||
rm /opt/freeware/src/packages/RPMS/ppc/xCAT-client-2.0*rpm
|
||||
rpm -ba xCAT-client.spec
|
||||
#rpm -Uvh /opt/freeware/src/packages/RPMS/ppc/xCAT-client-2.0*rpm
|
||||
|
||||
else
|
||||
|
||||
if [ -f /etc/redhat-release ]
|
||||
then
|
||||
pkg="redhat"
|
||||
else
|
||||
pkg="packages"
|
||||
fi
|
||||
|
||||
tar czvf xCAT-client-2.0.tar.gz xCAT-client-2.0;
|
||||
rm /usr/src/$pkg/RPMS/noarch/xCAT-client-2.0*rpm
|
||||
rpmbuild -ta xCAT-client-2.0.tar.gz ;
|
||||
#rpm -Uvh /usr/src/$pkg/RPMS/noarch/xCAT-client-2.0*rpm
|
||||
fi
|
28
makeperlxcatrpm
Executable file
28
makeperlxcatrpm
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/ksh
|
||||
|
||||
OSNAME=$(uname)
|
||||
|
||||
if [ "$OSNAME" = "AIX" ]
|
||||
then
|
||||
|
||||
tar -cvf perl-xCAT-2.0.tar perl-xCAT-2.0
|
||||
gzip perl-xCAT-2.0.tar
|
||||
cp perl-xCAT-2.0.tar.gz /opt/freeware/src/packages/SOURCES
|
||||
cd ./perl-xCAT-2.0
|
||||
rm /opt/freeware/src/packages/RPMS/ppc/perl-xCAT-2.0*rpm
|
||||
rpm -ba perl-xCAT.spec
|
||||
#rpm -Uvh /opt/freeware/src/packages/RPMS/ppc/perl-xCAT-2.0*rpm
|
||||
|
||||
else
|
||||
if [ -f /etc/redhat-release ]
|
||||
then
|
||||
pkg="redhat"
|
||||
else
|
||||
pkg="packages"
|
||||
fi
|
||||
|
||||
tar --exclude .svn -czvf perl-xCAT-2.0.tar.gz perl-xCAT-2.0/;
|
||||
rm /usr/src/$pkg/RPMS/noarch/perl-xCAT-2.0*rpm
|
||||
rpmbuild -ta perl-xCAT-2.0.tar.gz ;
|
||||
#rpm -Uvh /usr/src/$pkg/RPMS/noarch/perl-xCAT-2.0*rpm
|
||||
fi
|
28
makeserverrpm
Executable file
28
makeserverrpm
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/ksh
|
||||
|
||||
OSNAME=$(uname)
|
||||
|
||||
if [ "$OSNAME" = "AIX" ]
|
||||
then
|
||||
tar -cvf xCAT-server-2.0.tar xCAT-server-2.0
|
||||
gzip xCAT-server-2.0.tar
|
||||
cp xCAT-server-2.0.tar.gz /opt/freeware/src/packages/SOURCES
|
||||
cd ./xCAT-server-2.0
|
||||
rm /opt/freeware/src/packages/RPMS/ppc/xCAT-server-2.0*rpm
|
||||
rpm -ba xCAT-server.spec
|
||||
#rpm -Uvh /opt/freeware/src/packages/RPMS/ppc/xCAT-server-2.0*rpm
|
||||
|
||||
else
|
||||
|
||||
if [ -f /etc/redhat-release ]
|
||||
then
|
||||
pkg="redhat"
|
||||
else
|
||||
pkg="packages"
|
||||
fi
|
||||
|
||||
tar czvf xCAT-server-2.0.tar.gz xCAT-server-2.0;
|
||||
rm /usr/src/$pkg/RPMS/noarch/xCAT-server-2.0*rpm
|
||||
rpmbuild -ta xCAT-server-2.0.tar.gz ;
|
||||
#rpm -Uvh /usr/src/$pkg/RPMS/noarch/xCAT-server-2.0*rpm
|
||||
fi
|
326
perl-xCAT-2.0/LICENSE.html
Normal file
326
perl-xCAT-2.0/LICENSE.html
Normal file
@ -0,0 +1,326 @@
|
||||
<html xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||||
<meta name=ProgId content=Word.Document>
|
||||
<meta name=Generator content="Microsoft Word 9">
|
||||
<meta name=Originator content="Microsoft Word 9">
|
||||
<title>Eclipse Public License - Version 1.0</title>
|
||||
<!--[if gte mso 9]><xml>
|
||||
<o:DocumentProperties>
|
||||
<o:Revision>2</o:Revision>
|
||||
<o:TotalTime>3</o:TotalTime>
|
||||
<o:Created>2004-03-05T23:03:00Z</o:Created>
|
||||
<o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
|
||||
<o:Pages>4</o:Pages>
|
||||
<o:Words>1626</o:Words>
|
||||
<o:Characters>9270</o:Characters>
|
||||
<o:Lines>77</o:Lines>
|
||||
<o:Paragraphs>18</o:Paragraphs>
|
||||
<o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
|
||||
<o:Version>9.4402</o:Version>
|
||||
</o:DocumentProperties>
|
||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||
<w:WordDocument>
|
||||
<w:TrackRevisions/>
|
||||
</w:WordDocument>
|
||||
</xml><![endif]-->
|
||||
<style>
|
||||
<!--
|
||||
/* Font Definitions */
|
||||
@font-face
|
||||
{font-family:Tahoma;
|
||||
panose-1:2 11 6 4 3 5 4 4 2 4;
|
||||
mso-font-charset:0;
|
||||
mso-generic-font-family:swiss;
|
||||
mso-font-pitch:variable;
|
||||
mso-font-signature:553679495 -2147483648 8 0 66047 0;}
|
||||
/* Style Definitions */
|
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||||
{mso-style-parent:"";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p
|
||||
{margin-right:0in;
|
||||
mso-margin-top-alt:auto;
|
||||
mso-margin-bottom-alt:auto;
|
||||
margin-left:0in;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p.BalloonText, li.BalloonText, div.BalloonText
|
||||
{mso-style-name:"Balloon Text";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:8.0pt;
|
||||
font-family:Tahoma;
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
@page Section1
|
||||
{size:8.5in 11.0in;
|
||||
margin:1.0in 1.25in 1.0in 1.25in;
|
||||
mso-header-margin:.5in;
|
||||
mso-footer-margin:.5in;
|
||||
mso-paper-source:0;}
|
||||
div.Section1
|
||||
{page:Section1;}
|
||||
-->
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body lang=EN-US style='tab-interval:.5in'>
|
||||
|
||||
<div class=Section1>
|
||||
|
||||
<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
|
||||
</p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
|
||||
THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
|
||||
REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
|
||||
OF THIS AGREEMENT.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
in the case of the initial Contributor, the initial code and documentation
|
||||
distributed under this Agreement, and<br clear=left>
|
||||
b) in the case of each subsequent Contributor:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
changes to the Program, and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
additions to the Program;</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
|
||||
such changes and/or additions to the Program originate from and are distributed
|
||||
by that particular Contributor. A Contribution 'originates' from a Contributor
|
||||
if it was added to the Program by such Contributor itself or anyone acting on
|
||||
such Contributor's behalf. Contributions do not include additions to the
|
||||
Program which: (i) are separate modules of software distributed in conjunction
|
||||
with the Program under their own license agreement, and (ii) are not derivative
|
||||
works of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contributor" means any person or
|
||||
entity that distributes the Program.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
|
||||
claims licensable by a Contributor which are necessarily infringed by the use
|
||||
or sale of its Contribution alone or when combined with the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Program" means the Contributions
|
||||
distributed in accordance with this Agreement.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Recipient" means anyone who
|
||||
receives the Program under this Agreement, including all Contributors.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants Recipient
|
||||
a non-exclusive, worldwide, royalty-free copyright license to<span
|
||||
style='color:red'> </span>reproduce, prepare derivative works of, publicly
|
||||
display, publicly perform, distribute and sublicense the Contribution of such
|
||||
Contributor, if any, and such derivative works, in source code and object code
|
||||
form.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
|
||||
patent license under Licensed Patents to make, use, sell, offer to sell, import
|
||||
and otherwise transfer the Contribution of such Contributor, if any, in source
|
||||
code and object code form. This patent license shall apply to the combination
|
||||
of the Contribution and the Program if, at the time the Contribution is added
|
||||
by the Contributor, such addition of the Contribution causes such combination
|
||||
to be covered by the Licensed Patents. The patent license shall not apply to
|
||||
any other combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder. </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
|
||||
Recipient understands that although each Contributor grants the licenses to its
|
||||
Contributions set forth herein, no assurances are provided by any Contributor
|
||||
that the Program does not infringe the patent or other intellectual property
|
||||
rights of any other entity. Each Contributor disclaims any liability to Recipient
|
||||
for claims brought by any other entity based on infringement of intellectual
|
||||
property rights or otherwise. As a condition to exercising the rights and
|
||||
licenses granted hereunder, each Recipient hereby assumes sole responsibility
|
||||
to secure any other intellectual property rights needed, if any. For example,
|
||||
if a third party patent license is required to allow Recipient to distribute
|
||||
the Program, it is Recipient's responsibility to acquire that license before
|
||||
distributing the Program.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
|
||||
Each Contributor represents that to its knowledge it has sufficient copyright
|
||||
rights in its Contribution, if any, to grant the copyright license set forth in
|
||||
this Agreement. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
|
||||
Program in object code form under its own license agreement, provided that:</span>
|
||||
</p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it complies with the terms and conditions of this Agreement; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
its license agreement:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
effectively disclaims on behalf of all Contributors all warranties and
|
||||
conditions, express and implied, including warranties or conditions of title
|
||||
and non-infringement, and implied warranties or conditions of merchantability
|
||||
and fitness for a particular purpose; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
effectively excludes on behalf of all Contributors all liability for damages,
|
||||
including direct, indirect, special, incidental and consequential damages, such
|
||||
as lost profits; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
|
||||
states that any provisions which differ from this Agreement are offered by that
|
||||
Contributor alone and not by any other party; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
|
||||
states that source code for the Program is available from such Contributor, and
|
||||
informs licensees how to obtain it in a reasonable manner on or through a
|
||||
medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>When the Program is made available in source
|
||||
code form:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it must be made available under this Agreement; and </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
|
||||
copy of this Agreement must be included with each copy of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
|
||||
copyright notices contained within the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
|
||||
originator of its Contribution, if any, in a manner that reasonably allows
|
||||
subsequent Recipients to identify the originator of the Contribution. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Commercial distributors of software may
|
||||
accept certain responsibilities with respect to end users, business partners
|
||||
and the like. While this license is intended to facilitate the commercial use
|
||||
of the Program, the Contributor who includes the Program in a commercial
|
||||
product offering should do so in a manner which does not create potential
|
||||
liability for other Contributors. Therefore, if a Contributor includes the
|
||||
Program in a commercial product offering, such Contributor ("Commercial
|
||||
Contributor") hereby agrees to defend and indemnify every other
|
||||
Contributor ("Indemnified Contributor") against any losses, damages and
|
||||
costs (collectively "Losses") arising from claims, lawsuits and other
|
||||
legal actions brought by a third party against the Indemnified Contributor to
|
||||
the extent caused by the acts or omissions of such Commercial Contributor in
|
||||
connection with its distribution of the Program in a commercial product
|
||||
offering. The obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In order
|
||||
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
|
||||
Contributor in writing of such claim, and b) allow the Commercial Contributor
|
||||
to control, and cooperate with the Commercial Contributor in, the defense and
|
||||
any related settlement negotiations. The Indemnified Contributor may participate
|
||||
in any such claim at its own expense.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>For example, a Contributor might include the
|
||||
Program in a commercial product offering, Product X. That Contributor is then a
|
||||
Commercial Contributor. If that Commercial Contributor then makes performance
|
||||
claims, or offers warranties related to Product X, those performance claims and
|
||||
warranties are such Commercial Contributor's responsibility alone. Under this
|
||||
section, the Commercial Contributor would have to defend claims against the
|
||||
other Contributors related to those performance claims and warranties, and if a
|
||||
court requires any other Contributor to pay any damages as a result, the
|
||||
Commercial Contributor must pay those damages.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
|
||||
WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and distributing the
|
||||
Program and assumes all risks associated with its exercise of rights under this
|
||||
Agreement , including but not limited to the risks and costs of program errors,
|
||||
compliance with applicable laws, damage to or loss of data, programs or
|
||||
equipment, and unavailability or interruption of operations. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
|
||||
THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
|
||||
or unenforceable under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this Agreement, and without
|
||||
further action by the parties hereto, such provision shall be reformed to the
|
||||
minimum extent necessary to make such provision valid and enforceable.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
|
||||
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
||||
alleging that the Program itself (excluding combinations of the Program with
|
||||
other software or hardware) infringes such Recipient's patent(s), then such
|
||||
Recipient's rights granted under Section 2(b) shall terminate as of the date
|
||||
such litigation is filed. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
|
||||
shall terminate if it fails to comply with any of the material terms or
|
||||
conditions of this Agreement and does not cure such failure in a reasonable
|
||||
period of time after becoming aware of such noncompliance. If all Recipient's
|
||||
rights under this Agreement terminate, Recipient agrees to cease use and
|
||||
distribution of the Program as soon as reasonably practicable. However,
|
||||
Recipient's obligations under this Agreement and any licenses granted by
|
||||
Recipient relating to the Program shall continue and survive. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
|
||||
copies of this Agreement, but in order to avoid inconsistency the Agreement is
|
||||
copyrighted and may only be modified in the following manner. The Agreement
|
||||
Steward reserves the right to publish new versions (including revisions) of
|
||||
this Agreement from time to time. No one other than the Agreement Steward has
|
||||
the right to modify this Agreement. The Eclipse Foundation is the initial
|
||||
Agreement Steward. The Eclipse Foundation may assign the responsibility to
|
||||
serve as the Agreement Steward to a suitable separate entity. Each new version
|
||||
of the Agreement will be given a distinguishing version number. The Program
|
||||
(including Contributions) may always be distributed subject to the version of
|
||||
the Agreement under which it was received. In addition, after a new version of
|
||||
the Agreement is published, Contributor may elect to distribute the Program
|
||||
(including its Contributions) under the new version. Except as expressly stated
|
||||
in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
|
||||
the intellectual property of any Contributor under this Agreement, whether
|
||||
expressly, by implication, estoppel or otherwise. All rights in the Program not
|
||||
expressly granted under this Agreement are reserved.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
|
||||
State of New York and the intellectual property laws of the United States of
|
||||
America. No party to this Agreement will bring a legal action under this
|
||||
Agreement more than one year after the cause of action arose. Each party waives
|
||||
its rights to a jury trial in any resulting litigation.</span> </p>
|
||||
|
||||
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
5
perl-xCAT-2.0/Makefile.PL
Normal file
5
perl-xCAT-2.0/Makefile.PL
Normal file
@ -0,0 +1,5 @@
|
||||
use ExtUtils::MakeMaker;
|
||||
WriteMakefile(
|
||||
'NAME' => 'xCAT',
|
||||
'VERSION' => '2.0',
|
||||
);
|
62
perl-xCAT-2.0/perl-xCAT.spec
Normal file
62
perl-xCAT-2.0/perl-xCAT.spec
Normal file
@ -0,0 +1,62 @@
|
||||
Summary: xCAT perl libraries
|
||||
Name: perl-xCAT
|
||||
Version: 2.0
|
||||
Release: snap%(date +"%Y%m%d%H%M")
|
||||
License: EPL
|
||||
Group: System Environment/Libraries
|
||||
Source: perl-xCAT-2.0.tar.gz
|
||||
Packager: IBM Corp.
|
||||
Vendor: IBM Corp.
|
||||
Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
|
||||
Prefix: %{_prefix}
|
||||
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root
|
||||
%ifos linux
|
||||
BuildArch: noarch
|
||||
%endif
|
||||
|
||||
Provides: perl(xCAT) = %{version}
|
||||
|
||||
%description
|
||||
Provides perl xCAT libraries for core functionality. Required for all xCAT installations.
|
||||
Includes xCAT::Table, xCAT::NodeRange, among others.
|
||||
|
||||
%prep
|
||||
%setup -q -n perl-xCAT-%{version}
|
||||
|
||||
%build
|
||||
perl Makefile.PL
|
||||
%{__make} %{?mflags}
|
||||
|
||||
%install
|
||||
%{__make} install DESTDIR=$RPM_BUILD_ROOT %{?mflags_install}
|
||||
test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT/%{_datadir} ||:
|
||||
test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT/%{_libdir}/perl5/5* ||:
|
||||
|
||||
find %{buildroot} -name "perllocal.pod" \
|
||||
-o -name ".packlist" \
|
||||
-o -name "*.bs" \
|
||||
|xargs -i rm -f {}
|
||||
|
||||
# ndebug - this seems to break the AIX build - need to investigate
|
||||
%ifos linux
|
||||
find %{buildroot}%{_prefix} \
|
||||
-type d -depth \
|
||||
-exec rmdir {} \; 2>/dev/null
|
||||
%endif
|
||||
|
||||
find $RPM_BUILD_ROOT -type f | sed -e "s@$RPM_BUILD_ROOT@/@" > files.list
|
||||
|
||||
%clean
|
||||
test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files -f files.list
|
||||
%defattr(-, root, root)
|
||||
%doc LICENSE.html
|
||||
|
||||
%changelog
|
||||
* Wed May 2 2007 - Norm Nott nott@us.ibm.com
|
||||
- Made changes to make this work on AIX
|
||||
|
||||
* Wed Jan 24 2007 Jarrod Johnson <jbjohnso@us.ibm.com>
|
||||
-It begins
|
||||
|
380
perl-xCAT-2.0/xCAT/Client.pm
Normal file
380
perl-xCAT-2.0/xCAT/Client.pm
Normal file
@ -0,0 +1,380 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::Client;
|
||||
use xCAT::NodeRange;
|
||||
use IO::Socket::SSL;
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use Storable qw(dclone);
|
||||
my $xcathost='localhost:3001';
|
||||
my $plugins_dir='/usr/lib/xcat/plugins';
|
||||
my %resps;
|
||||
1;
|
||||
|
||||
|
||||
#################################
|
||||
# submit_request will take an xCAT command and pass it to the xCAT
|
||||
# server for execution.
|
||||
#
|
||||
# If the XCATBYPASS env var is set, the connection to the server/daemon
|
||||
# will be bypassed and the plugin will be called directly. If it is
|
||||
# set to one or more directories (separated by ":"), all perl modules
|
||||
# in those directories will be loaded in as plugins (for duplicate
|
||||
# commands, last one in wins). If it is set to any other value
|
||||
# (e.g. "yes", "default", whatever string you want) the default plugin
|
||||
# directory /usr/lib/xcat/plugins will be used.
|
||||
#
|
||||
# Input:
|
||||
# Request hash - A hash ref containing the input command and args to be
|
||||
# passed to the plugin. The the xcatd daemon (or this routine when
|
||||
# XCATBYPASS) reads the {noderange} entry and builds a flattened array
|
||||
# of nodes that gets added as request->{node}
|
||||
# The format for the request hash is:
|
||||
# { command => [ 'xcatcmd' ],
|
||||
# noderange => [ 'noderange_string' ],
|
||||
# arg => [ 'arg1', 'arg2', '...', 'argn' ]
|
||||
# }
|
||||
# Callback - A subroutine ref that will be called to process the output
|
||||
# from the plugin.
|
||||
#
|
||||
# NOTE: The request hash will get converted to XML when passed to the
|
||||
# xcatd daemon, and will get converted back to a hash before being
|
||||
# passed to the plugin. The XMLin ForceArray option is used to
|
||||
# force all XML constructs to be arrays so that the plugin code
|
||||
# and callback routines can access the data consistently.
|
||||
# The input request and the response hash created by the plugin should
|
||||
# always create hashes with array values.
|
||||
#################################
|
||||
sub submit_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
|
||||
# If XCATBYPASS is set, invoke the plugin process_request method directly
|
||||
# without going through the socket connection to the xcatd daemon
|
||||
if ($ENV{XCATBYPASS}) {
|
||||
# Load plugins from either specified or default dir
|
||||
my %cmd_handlers;
|
||||
my @plugins_dirs = split('\:',$ENV{XCATBYPASS});
|
||||
if (-d $plugins_dirs[0]) {
|
||||
foreach (@plugins_dirs) {
|
||||
$plugins_dir = $_;
|
||||
scan_plugins();
|
||||
}
|
||||
} else {
|
||||
scan_plugins();
|
||||
}
|
||||
|
||||
# don't do XML transformation -- assume request is well-formed
|
||||
# my $xmlreq=XMLout($request,RootName=>xcatrequest,NoAttr=>1,KeyAttr=>[]);
|
||||
# $request = XMLin($xmlreq,SuppressEmpty=>undef,ForceArray=>1) ;
|
||||
|
||||
|
||||
# Call the plugin directly
|
||||
# ${"xCAT_plugin::".$modname."::"}{process_request}->($request,$callback);
|
||||
plugin_command($request,undef,$callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
# No XCATBYPASS, so establish a socket connection with the xcatd daemon
|
||||
# and submit the request
|
||||
if ($ENV{XCATHOST}) {
|
||||
$xcathost=$ENV{XCATHOST};
|
||||
}
|
||||
my $client = IO::Socket::SSL->new(
|
||||
PeerAddr => $xcathost,
|
||||
SSL_key_file => $ENV{HOME}."/.xcat/client-key.pem",
|
||||
SSL_cert_file => $ENV{HOME}."/.xcat/client-cert.pem",
|
||||
SSL_ca_file => $ENV{HOME}."/.xcat/ca.pem",
|
||||
SSL_use_cert => 1,
|
||||
);
|
||||
die "Connection failure: $!\n" unless ($client);
|
||||
my $msg=XMLout($request,RootName=>xcatrequest,NoAttr=>1,KeyAttr=>[]);
|
||||
print $client $msg;
|
||||
my $response;
|
||||
my $rsp;
|
||||
while (<$client>) {
|
||||
$response .= $_;
|
||||
if ($response =~ m/<\/xcatresponse>/) {
|
||||
$rsp = XMLin($response,SuppressEmpty=>undef,ForceArray=>1);
|
||||
$response='';
|
||||
if ($rsp->{warning}) {
|
||||
printf ("Warning: ".$rsp->{warning}->[0]."\n");
|
||||
}
|
||||
if ($rsp->{error}) {
|
||||
printf "Error: ". $rsp->{error}->[0]."\n";
|
||||
}
|
||||
$callback->($rsp);
|
||||
if ($rsp->{serverdone}) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
###################################
|
||||
# scan_plugins
|
||||
# will load all plugin perl modules and build a list of supported
|
||||
# commands
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 10/3/07).
|
||||
# Will eventually move to using common source....
|
||||
###################################
|
||||
sub scan_plugins {
|
||||
my @plugins=glob($plugins_dir."/*.pm");
|
||||
foreach (@plugins) {
|
||||
/.*\/([^\/]*).pm$/;
|
||||
my $modname = $1;
|
||||
require "$_";
|
||||
no strict 'refs';
|
||||
my $cmd_adds=${"xCAT_plugin::".$modname."::"}{handled_commands}->();
|
||||
foreach (keys %$cmd_adds) {
|
||||
my $value = $_;
|
||||
if (defined($cmd_handlers{$_})) {
|
||||
my $add=1;
|
||||
#This next bit of code iterates through the handlers.
|
||||
#If the value doesn't contain an equal, and has an equivalent entry added by
|
||||
# another plugin already, don't add (otherwise would hit the DB multiple times)
|
||||
# a better idea, restructure the cmd_handlers as a multi-level hash
|
||||
# prove out this idea real quick before doing that
|
||||
foreach (@{$cmd_handlers{$_}}) {
|
||||
if (($_->[1] eq $cmd_adds->{$value}) and (($cmd_adds->{$value} !~ /=/) or ($_->[0] eq $modname))) {
|
||||
$add = 0;
|
||||
}
|
||||
}
|
||||
if ($add) { push @{$cmd_handlers{$_}},[$modname,$cmd_adds->{$_}]; }
|
||||
#die "Conflicting handler information from $modname";
|
||||
} else {
|
||||
$cmd_handlers{$_} = [ [$modname,$cmd_adds->{$_}] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
###################################
|
||||
# plugin_command
|
||||
# will invoke the correct plugin
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 10/3/07).
|
||||
# Will eventually move to using common source....
|
||||
###################################
|
||||
sub plugin_command {
|
||||
my $req = shift;
|
||||
my $sock = shift;
|
||||
my $callback = shift;
|
||||
my %handler_hash;
|
||||
# use xCAT::NodeRange;
|
||||
$Main::resps={};
|
||||
my @nodes;
|
||||
if ($req->{node}) {
|
||||
@nodes = @{$req->{node}};
|
||||
} elsif ($req->{noderange}) {
|
||||
@nodes = noderange($req->{noderange}->[0]);
|
||||
if (nodesmissed) {
|
||||
# my $rsp = {errorcode=>1,error=>"Invalid nodes in noderange:".join(',',nodesmissed)};
|
||||
print "Invalid nodes in noderange:".join(',',nodesmissed);
|
||||
# if ($sock) {
|
||||
# print $sock XMLout($rsp,RootName=>'xcatresponse' ,NoAttr=>1);
|
||||
# }
|
||||
# return ($rsp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (@nodes) { $req->{node} = \@nodes; }
|
||||
if (defined($cmd_handlers{$req->{command}->[0]})) {
|
||||
my $hdlspec;
|
||||
foreach (@{$cmd_handlers{$req->{command}->[0]}}) {
|
||||
$hdlspec =$_->[1];
|
||||
my $ownmod = $_->[0];
|
||||
if ($hdlspec =~ /:/) { #Specificed a table lookup path for plugin name
|
||||
my $table;
|
||||
my $cols;
|
||||
($table,$cols) = split(/:/,$hdlspec);
|
||||
my @colmns=split(/,/,$cols);
|
||||
my @columns;
|
||||
my $hdlrtable=xCAT::Table->new($table);
|
||||
unless ($hdlrtable) {
|
||||
#TODO: proper error handling
|
||||
}
|
||||
my $node;
|
||||
my $colvals = {};
|
||||
foreach my $colu (@colmns) {
|
||||
if ($colu =~ /=/) { #a value redirect to a pattern/specific name
|
||||
my $coln; my $colv;
|
||||
($coln,$colv) = split(/=/,$colu,2);
|
||||
$colvals->{$coln} = $colv;
|
||||
push (@columns,$coln);
|
||||
} else {
|
||||
push (@columns,$colu);
|
||||
}
|
||||
}
|
||||
|
||||
foreach $node (@nodes) {
|
||||
my $attribs = $hdlrtable->getNodeAttribs($node,\@columns);
|
||||
unless (defined($attribs)) { next; } #TODO: This really ought to craft an unsupported response for this request
|
||||
foreach (@columns) {
|
||||
my $col=$_;
|
||||
if (defined($attribs->{$col})) {
|
||||
if ($colvals->{$col}) { #A pattern match style request.
|
||||
if ($attribs->{$col} =~ /$colvals->{$col}/) {
|
||||
$handler_hash{$ownmod}->{$node} = 1;
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
$handler_hash{$attribs->{$col}}->{$node} = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unless (@nodes) {
|
||||
$handler_hash{$hdlspec} = 1;
|
||||
}
|
||||
foreach (@nodes) { #Specified a specific plugin, not a table lookup
|
||||
$handler_hash{$hdlspec}->{$_} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print "$req->{command}->[0] xCAT command not found \n";
|
||||
return 1; #TODO: error back that request has no known plugin for it
|
||||
}
|
||||
|
||||
## FOR NOW, DON'T FORK CHILD PROCESS TO MAKE BYPASS SIMPLER AND EASIER TO DEBUG
|
||||
# my $children=0;
|
||||
# $SIG{CHLD} = sub {while (waitpid(-1, WNOHANG) > 0) { $children--; } };
|
||||
# my $check_fds;
|
||||
# if ($sock) {
|
||||
# $check_fds = new IO::Select;
|
||||
# }
|
||||
foreach (keys %handler_hash) {
|
||||
my $modname = $_;
|
||||
if (-r $plugins_dir."/".$modname.".pm") {
|
||||
require $plugins_dir."/".$modname.".pm";
|
||||
# $children++;
|
||||
# my $pfd; #will be referenced for inter-process messaging.
|
||||
# my $child;
|
||||
# if ($sock) { #If $sock not passed in, don't fork..
|
||||
# socketpair($pfd, $parent_fd,AF_UNIX,SOCK_STREAM,PF_UNSPEC) or die "socketpair: $!";
|
||||
# #pipe($pfd,$cfd);
|
||||
# $parent_fd->autoflush(1);
|
||||
# $pfd->autoflush(1);
|
||||
# $child = fork;
|
||||
# } else {
|
||||
# $child = 0;
|
||||
# }
|
||||
# unless (defined $child) { die "Fork failed"; }
|
||||
# if ($child == 0) {
|
||||
# if ($sock) { close $pfd; }
|
||||
unless ($handler_hash{$_} == 1) {
|
||||
my @nodes = sort {($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] || $a cmp $b } (keys %{$handler_hash{$_}});
|
||||
$req->{node}=\@nodes;
|
||||
}
|
||||
no strict "refs";
|
||||
${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
|
||||
# if ($sock) {
|
||||
# close($parent_fd);
|
||||
# exit(0);
|
||||
# }
|
||||
# } else {
|
||||
# close $parent_fd;
|
||||
# $check_fds->add($pfd);
|
||||
# }
|
||||
}
|
||||
}
|
||||
unless ($sock) { return $Main::resps };
|
||||
# while ($children > 0) {
|
||||
# relay_fds($check_fds,$sock);
|
||||
# }
|
||||
# #while (relay_fds($check_fds,$sock)) {}
|
||||
# my %done;
|
||||
# $done{serverdone} = {};
|
||||
# if ($req->{transid}) {
|
||||
# $done{transid}=$req->{transid}->[0];
|
||||
# }
|
||||
# if ($sock) { print $sock XMLout(\%done,RootName => 'xcatresponse',NoAttr=>1); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
###################################
|
||||
# do_request
|
||||
# called from a plugin to execute another xCAT plugin command internally
|
||||
#
|
||||
# NOTE: This is copied from xcatd (last merge 10/3/07).
|
||||
# Will eventually move to using common source....
|
||||
###################################
|
||||
sub do_request {
|
||||
my $req = shift;
|
||||
my $second = shift;
|
||||
my $rsphandler = \&build_response;
|
||||
my $sock = undef;
|
||||
if ($second) {
|
||||
if (ref($second) eq "CODE") {
|
||||
$rsphandler = $second;
|
||||
} elsif (ref($second) eq "GLOB") {
|
||||
$sock = $second;
|
||||
}
|
||||
}
|
||||
|
||||
#my $sock = shift; #If no sock, will return a response hash
|
||||
if ($cmd_handlers{$req->{command}->[0]}) {
|
||||
return plugin_command($req,$sock,$rsphandler);
|
||||
} elsif ($req->{command}->[0] eq "noderange" and $req->{noderange}) {
|
||||
my @nodes = noderange($req->{noderange}->[0]);
|
||||
my %resp;
|
||||
if (nodesmissed) {
|
||||
$resp{warning}="Invalid nodes in noderange:".join ',',nodesmissed;
|
||||
}
|
||||
$resp{serverdone} = {};
|
||||
@{$resp{node}}=@nodes;
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
if ($sock) {
|
||||
print $sock XMLout(\%resp,RootName => 'xcatresponse',NoAttr=>1);
|
||||
} else {
|
||||
return (\%resp);
|
||||
}
|
||||
} else {
|
||||
my %resp=(error=>"Unsupported request");
|
||||
$resp{serverdone} = {};
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
if ($sock) {
|
||||
print $sock XMLout(\%resp,RootName => 'xcatresponse',NoAttr=>1);
|
||||
} else {
|
||||
return (\%resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
###################################
|
||||
# build_response
|
||||
# This callback handles responses from nested level plugin calls.
|
||||
# It builds a merged hash of all responses that gets passed back
|
||||
# to the calling plugin.
|
||||
# Note: Need to create a "deep clone" of this response to add to the
|
||||
# return, otherwise next time through the referenced data is overwritten
|
||||
#
|
||||
###################################
|
||||
sub build_response {
|
||||
my $rsp = shift;
|
||||
foreach (keys %$rsp) {
|
||||
my $subresp = dclone($rsp->{$_});
|
||||
push (@{$Main::resps->{$_}}, @{$subresp});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
277
perl-xCAT-2.0/xCAT/MacMap.pm
Executable file
277
perl-xCAT-2.0/xCAT/MacMap.pm
Executable file
@ -0,0 +1,277 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::MacMap;
|
||||
use xCAT::Table;
|
||||
use IO::Select;
|
||||
use IO::Handle;
|
||||
use Sys::Syslog;
|
||||
use Data::Dumper;
|
||||
use SNMP;
|
||||
openlog("MacMap",'','local0');
|
||||
my %cisco_vlans; #Special hash structure to reflect discovered VLANS on Cisco equip
|
||||
#use IF-MIB (1.3.6.1.2.1.2) for all switches
|
||||
# 1.3.6.1.2.1.31.1.1 - ifXtable
|
||||
# 1.3.6.1.2.1.31.1.1.1.1.N = name - ifName
|
||||
#Using BRIDGE-MIB for most switches( 1.3.6.1.2.1.17 )
|
||||
# 1.3.6.1.2.1.17.1.4 - dot1dBasePortTable
|
||||
# 1.3.6.1.2.1.17.1.4.1.1.X = N - dot1dBasePort
|
||||
# 1.3.6.1.2.1.17.4.3 - dot1dTpFdbTable #FAILS on FORCE10,
|
||||
#
|
||||
#If particular result fails, fallback to Q-BRIDGE-MIB for Force10 (1.3.6.1.2.1.17.7)
|
||||
# 1.3.6.1.2.1.17.7.1.2.2 - dot1qTpFdbTable
|
||||
|
||||
|
||||
sub namesmatch {
|
||||
=pod
|
||||
|
||||
MacMap attempts to do it's best to determine whether or not a particular SNMP description of
|
||||
a port matches the user specified value in the configuration. Generally, if the configuration
|
||||
consists of non-stacked switches without line cards, the user should only need to specify the
|
||||
port number without any characters or / characters. If the configuration contains line cards
|
||||
or stacked switches, use of that particular switch's appropriate / syntax in generally called
|
||||
for. The exception being stacked SMC 8848 switches, in which all ports are still single
|
||||
numbers, and the ports on the second switch begin at 57.
|
||||
|
||||
If difficulty is encountered, or a switch is attempted with a format that doesn't match any
|
||||
existing rule, it is recommended to use snmpwalk on the switch with the .1.3.6.1.2.1.31.1.1.1.1
|
||||
OID, and have the switch table port value match exactly the format suggested by that OID.
|
||||
|
||||
=cut
|
||||
my $namepercfg = shift;
|
||||
my $namepersnmp = shift;
|
||||
if ($namepercfg eq $namepersnmp) {
|
||||
return 1; # They matched perfectly
|
||||
}
|
||||
#Begin guessing, first off, all tested scenarios have likely correct guesses ending
|
||||
#in the cfg string, with some non-numeric prefix before it.
|
||||
unless ($namepersnmp =~ /[^0123456789]$namepercfg\z/) {
|
||||
#Most common case, won't match at all
|
||||
return 0;
|
||||
}
|
||||
#stop contemplating vlan, Nu, and console interfaces
|
||||
if (($namepersnmp =~ /vl/i) or ($namepersnmp =~ /Nu/) or ($namepersnmp =~ /onsole/)) {
|
||||
return 0;
|
||||
}
|
||||
#broken up for code readablitiy, don't check port channel numbers or CPU
|
||||
#have to distinguish betweer Port and Po and PortChannel
|
||||
if (($namepersnmp !~ /Port #/) and ($namepersnmp !~ /Port\d/) and ($namepersnmp =~ /Po/) or ($namepersnmp =~ /LAG/) or ($namepersnmp =~ /CPU/)) {
|
||||
return 0;
|
||||
}
|
||||
#don't contemplate ManagementEthernet
|
||||
if (($namepersnmp =~ /Management/)) {
|
||||
return 0;
|
||||
}
|
||||
#The blacklist approach has been exhausted. For now, assuming that means good,
|
||||
#if something ambiguous happens, the whitelist would have been:
|
||||
#'Port','Port #','/' (if namepercfg has no /, then / would be...),
|
||||
#'Gi','Te','GigabitEthernet','TenGigabitEthernet'
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $self = {};
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
|
||||
$self->{switchtab} = xCAT::Table->new('switch', -create => 1);
|
||||
$self->{sitetab} = xCAT::Table->new('site');
|
||||
bless ($self, $class);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub find_mac {
|
||||
# This function is given a mac address, checks for given mac address
|
||||
# and returns undef if unable to find the node, and the nodename otherwise
|
||||
my $self = shift;
|
||||
my $mac = shift;
|
||||
# For now HARDCODE (TODO, configurable?) a cache as stale after five minutes
|
||||
# Also, if things are changed in the config, our cache could be wrong,
|
||||
# invalidate on switch table write?
|
||||
if ($self->{mactable}->{lc($mac)} and ($self->{timestamp} > (time() - 300))) {
|
||||
my $reftbl = 0;
|
||||
foreach (keys %{$self->{mactable}}) {
|
||||
if ((lc($mac) ne $_) and ($self->{mactable}->{lc($mac)} eq $self->{mactable}->{$_})) {
|
||||
$reftbl = 1;
|
||||
#The cache indicates confusion, flush it..
|
||||
}
|
||||
}
|
||||
unless ($reftbl) { return $self->{mactable}->{lc($mac)};}
|
||||
}
|
||||
$self->refresh_table; #not cached or stale cache, refresh
|
||||
if ($self->{mactable}->{lc($mac)}) {
|
||||
return $self->{mactable}->{lc($mac)};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub refresh_table {
|
||||
$self->{mactable}={};
|
||||
my $self = shift;
|
||||
my $community = "public";
|
||||
my $tmp = $self->{sitetab}->getAttribs({key=>'snmpc'},'value');
|
||||
if ($tmp and $tmp->{value}) { $community = $tmp->{value} }
|
||||
else { #Would warn here..
|
||||
}
|
||||
my %checked_pairs;
|
||||
my @entries = $self->{switchtab}->getAllNodeAttribs(['port','switch']);
|
||||
#Build hash of switch port names per switch
|
||||
$self->{switches} = {};
|
||||
foreach $entry (@entries) {
|
||||
$self->{switches}->{$entry->{switch}}->{$entry->{port}}=$entry->{node};
|
||||
}
|
||||
my $children = 0;
|
||||
my $inputs = new IO::Select;
|
||||
$SIG{CHLD}= sub { while(waitpid(-1,WNOHANG) > 0) { $children-- } };
|
||||
foreach $entry (@entries) {
|
||||
if ($checked_pairs{$entry->{switch}}) {
|
||||
next;
|
||||
}
|
||||
$checked_pairs{$entry->{switch}}=1;
|
||||
pipe my $child,my $parent;
|
||||
$child->autoflush(1);
|
||||
$parent->autoflush(1);
|
||||
$children++;
|
||||
$cpid = fork;
|
||||
unless (defined $cpid) { die "Cannot fork" };
|
||||
if ($cpid == 0) {
|
||||
close($child);
|
||||
$self->refresh_switch($parent,$community,$entry->{switch});
|
||||
exit(0);
|
||||
}
|
||||
close($parent);
|
||||
$inputs->add($child);
|
||||
}
|
||||
while($children) {
|
||||
$self->handle_output($inputs);
|
||||
}
|
||||
while ($self->handle_output($inputs)) {}; #Drain the pipes
|
||||
$self->{timestamp}=time;
|
||||
}
|
||||
|
||||
sub handle_output {
|
||||
my $self = shift;
|
||||
my $inputs = shift;
|
||||
my @readied = $inputs->can_read(1);
|
||||
my $rc = @readied;
|
||||
my $ready;
|
||||
foreach $ready (@readied) {
|
||||
my $line = <$ready>;
|
||||
unless ($line) {
|
||||
$inputs->remove($ready);
|
||||
close($ready);
|
||||
next;
|
||||
}
|
||||
$line =~ m/^([^|]*)\|(.*)/;
|
||||
$self->{mactable}->{$1}=$2;
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
sub walkoid {
|
||||
my $session = shift;
|
||||
my $oid = shift;
|
||||
my $retmap = undef;
|
||||
my $varbind = new SNMP::Varbind([$oid,'']);
|
||||
$session->getnext($varbind);
|
||||
if ($session->{ErrorStr}) {
|
||||
syslog("local6|err","Error communicating with ".$session->{DestHost}.": ".$session->{ErrorStr});
|
||||
return undef;
|
||||
}
|
||||
my $count=0;
|
||||
while ($varbind->[0] =~ /^$oid\.?(.*)/) {
|
||||
$count++;
|
||||
if ($1) {
|
||||
$retmap->{$1.".".$varbind->[1]}=$varbind->[2]; #If $1 is set, means key should
|
||||
} else {
|
||||
$retmap->{$varbind->[1]}=$varbind->[2]; #If $1 is set, means key should
|
||||
}
|
||||
|
||||
$session->getnext($varbind);
|
||||
}
|
||||
return $retmap;
|
||||
}
|
||||
|
||||
|
||||
sub refresh_switch {
|
||||
my $self = shift;
|
||||
my $output = shift;
|
||||
my $community = shift;
|
||||
my $switch = shift;
|
||||
$session = new SNMP::Session(
|
||||
DestHost => $switch,
|
||||
Version => '1',
|
||||
Community => $community,
|
||||
UseNumeric => 1
|
||||
);
|
||||
#if ($error) { die $error; }
|
||||
unless ($session) { syslog("err","Failed to communicate with $switch"); return; }
|
||||
my $namemap = walkoid($session,'.1.3.6.1.2.1.31.1.1.1.1');
|
||||
unless ($namemap) {
|
||||
# walkoid errored...
|
||||
return;
|
||||
}
|
||||
#Above is valid without community string indexing, on cisco, we need it on the next one and onward
|
||||
my $iftovlanmap = walkoid($session,'.1.3.6.1.4.1.9.9.68.1.2.2.1.2');
|
||||
my %vlans_to_check;
|
||||
if (defined($iftovlanmap)) { #We have a cisco, the intelligent thing is to do SNMP gets on the ports
|
||||
# that we can verify are populated per switch table
|
||||
my $portid;
|
||||
foreach $portid (keys %{$namemap}) {
|
||||
my $portname;
|
||||
my $switchport = $namemap->{$portid};
|
||||
foreach $portname (keys %{$self->{switches}->{$switch}}) {
|
||||
unless (namesmatch($portname,$switchport)) { next }
|
||||
$vlans_to_check{$iftovlanmap->{$portid}} = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$vlans_to_check{'NA'}=1;
|
||||
}
|
||||
|
||||
my $vlan;
|
||||
foreach $vlan (keys %vlans_to_check) {
|
||||
unless ($vlan eq 'NA') {
|
||||
$session = new SNMP::Session(
|
||||
DestHost => $switch,
|
||||
Version => '1',
|
||||
Community => $community."@".$vlan,
|
||||
UseNumeric => 1
|
||||
);
|
||||
}
|
||||
unless ($session) { return; }
|
||||
my $bridgetoifmap = walkoid($session,'.1.3.6.1.2.1.17.1.4.1.2'); # Good for all switches
|
||||
# my $mactoindexmap = walkoid($session,'.1.3.6.1.2.1.17.4.3.1.2');
|
||||
my $mactoindexmap = walkoid($session,'.1.3.6.1.2.1.17.7.1.2.2.1.2');
|
||||
unless (defined($mactoindexmap)) { #if no qbridge defined, try bridge mib, probably cisco
|
||||
#$mactoindexmap = walkoid($session,'.1.3.6.1.2.1.17.7.1.2.2.1.2');
|
||||
$mactoindexmap = walkoid($session,'.1.3.6.1.2.1.17.4.3.1.2');
|
||||
} #Ok, time to process the data
|
||||
foreach my $oid (keys %$namemap) {
|
||||
#$oid =~ m/1.3.6.1.2.1.31.1.1.1.1.(.*)/;
|
||||
my $ifindex = $oid;
|
||||
my $portname;
|
||||
my $switchport = $namemap->{$oid};
|
||||
foreach $portname (keys %{$self->{switches}->{$switch}}) { # a little redundant, but
|
||||
# computationally trivial
|
||||
unless (namesmatch($portname,$switchport)) { next }
|
||||
#if still running, we have match
|
||||
foreach my $boid (keys %$bridgetoifmap) {
|
||||
unless ($bridgetoifmap->{$boid} == $ifindex) { next; }
|
||||
my $bridgeport = $boid;
|
||||
foreach (keys %$mactoindexmap) {
|
||||
if ($mactoindexmap->{$_} == $bridgeport) {
|
||||
my @tmp = split /\./, $_;
|
||||
my @mac = @tmp[-6 .. -1];
|
||||
printf $output "%02x:%02x:%02x:%02x:%02x:%02x|%s\n",@mac,$self->{switches}->{$switch}->{$portname};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
1;
|
355
perl-xCAT-2.0/xCAT/MsgUtils.pm
Normal file
355
perl-xCAT-2.0/xCAT/MsgUtils.pm
Normal file
@ -0,0 +1,355 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::MsgUtils;
|
||||
|
||||
use strict;
|
||||
|
||||
use locale;
|
||||
use Socket;
|
||||
use File::Path;
|
||||
|
||||
my $msgs;
|
||||
my $distro;
|
||||
|
||||
$::XCATLOG = "/var/log/xcat";
|
||||
$::NOK = -1;
|
||||
$::OK = 0;
|
||||
umask(0022); # This sets umask for all files so that group and world only
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head1 xCAT::MsgUtils
|
||||
|
||||
|
||||
=head2 Package Description
|
||||
|
||||
|
||||
This program module file, supports the xcat messaging and logging
|
||||
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head2 Package Dependancies
|
||||
|
||||
use strict;
|
||||
use Fcntl qw(:flock);
|
||||
use File::Basename;
|
||||
use File::Find;
|
||||
use File::Path; # Provides mkpath()
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head1 Subroutines by Functional Group
|
||||
|
||||
=cut
|
||||
|
||||
=head3 message
|
||||
|
||||
Display a msg stdout, stderr, or a log file.
|
||||
If callback routine is provide, the message will be returned to the callback
|
||||
routine and logged, if logging is requested.
|
||||
This function is primarily meant for commands and other code that is sending
|
||||
output directly to the user. Even the log is really a capture of this
|
||||
interactive output.
|
||||
|
||||
Arguments:
|
||||
The arguments of the message() function are:
|
||||
|
||||
if $::VERBOSE is set, the message will be displayed.
|
||||
|
||||
If $::LOG_FILE_HANDLE is set, the message goes to both
|
||||
the screen and that log file. (Verbose msgs will be sent to
|
||||
the log file even if $::VERBOSE is not set.)
|
||||
A timestamp will automatically be put in front on any message
|
||||
that is logged unless the T option is specified.
|
||||
|
||||
if address of the call_back is provided,
|
||||
then the message will be returned
|
||||
as data to the call_back routine.
|
||||
|
||||
- The argument is the message to be displayed/logged.
|
||||
|
||||
|
||||
Here's the meaning of the 1st character:
|
||||
I - informational goes to stdout
|
||||
E - error. This type of message will be sent to stderr.
|
||||
V - verbose. This message should only be displayed,
|
||||
if $::VERBOSE is set.
|
||||
T - Do not log timestamp,
|
||||
|
||||
If $::LOG_FILE_HANDLE is set, the message goes to both
|
||||
the screen and that log file. (Verbose msgs will be sent to
|
||||
the log file even if $::VERBOSE is not set.)
|
||||
A timestamp will automatically be put in front on any message
|
||||
that is logged.
|
||||
Optionally a T can be put before any of the above characters
|
||||
"not" put a timestamp on
|
||||
before the message when it is logged.
|
||||
Note: T must be the first character.
|
||||
|
||||
|
||||
Returns:
|
||||
none
|
||||
|
||||
Error:
|
||||
_none
|
||||
|
||||
Example:
|
||||
xCAT::MsgUtils->message('E', "Operation $value1 failed\n");
|
||||
Use of T flag
|
||||
xCAT::MsgUtils->message('TI', "Operation $value1 failed\n");
|
||||
Use of callback
|
||||
xCAT::MsgUtils->message('I', $rsp,$call_back);
|
||||
where $rsp is a data response structure for the callback function
|
||||
|
||||
|
||||
Comments:
|
||||
Returns:
|
||||
none
|
||||
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub message
|
||||
{
|
||||
|
||||
# Process the arguments
|
||||
shift; # get rid of the class name
|
||||
my $sevcode = shift;
|
||||
my $msg = shift;
|
||||
my $call_back = shift; # optional
|
||||
|
||||
# Parse the severity code
|
||||
my $i = 1;
|
||||
my $notimestamp = 0;
|
||||
my $sev = substr($sevcode, 0, 1);
|
||||
|
||||
# should be I, E, V, T
|
||||
if ($sev eq 'T') # do not put timestamp
|
||||
{
|
||||
$notimestamp = 1; # no timestamp
|
||||
$i = 2; # logically shift everything by 1 char
|
||||
$sev = substr($sevcode, 1, 1); # now should be either I,E,V
|
||||
}
|
||||
|
||||
my $stdouterrf = \*STDOUT;
|
||||
my $stdouterrd = '';
|
||||
if (my $sev =~ /[E]/)
|
||||
{
|
||||
$stdouterrf = \*STDERR;
|
||||
$stdouterrd = '1>&2';
|
||||
}
|
||||
|
||||
if (defined($::LOG_FILE_HANDLE))
|
||||
{
|
||||
|
||||
if ($notimestamp == 0)
|
||||
{ # print a timestamp
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
|
||||
localtime(time);
|
||||
my $time = $hour . ":" . $min . ":" . $sec . " ";
|
||||
print $::LOG_FILE_HANDLE $time;
|
||||
print $::LOG_FILE_HANDLE " ";
|
||||
}
|
||||
print $::LOG_FILE_HANDLE $msg;
|
||||
}
|
||||
|
||||
# if V option and $::VERBOSE set or not V option then display
|
||||
# Note Verbose messages, will be thrown away if verbose is not
|
||||
# turned on and there is no logging.
|
||||
if (($sev eq 'V' && $::VERBOSE) || ($sev ne 'V'))
|
||||
{
|
||||
if ($::DSH_API)
|
||||
{
|
||||
$::DSH_API_MESSAGE = $::DSH_API_MESSAGE . $msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($call_back) { # callback routine provided
|
||||
$call_back->($msg);
|
||||
} else {
|
||||
print $stdouterrf $msg; # print the message
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head2 Message Logging Routines
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 backup_logfile
|
||||
|
||||
Backup the current logfile. Move logfile to logfile.1. Shift all other logfiles
|
||||
(logfile.[1-3]) up one number. The original logfile.4 is removed as in a FIFO.
|
||||
|
||||
Arguments:
|
||||
$logFileName
|
||||
Returns:
|
||||
$::OK
|
||||
Error:
|
||||
undefined
|
||||
Example:
|
||||
xCAT::MsgUtils->backup_logfile($logfile);
|
||||
Comments:
|
||||
Never used outside of ServerUtils.
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub backup_logfile
|
||||
{
|
||||
my ($class, $logfile) = @_;
|
||||
|
||||
my ($logfile1) = $logfile . ".1";
|
||||
my ($logfile2) = $logfile . ".2";
|
||||
my ($logfile3) = $logfile . ".3";
|
||||
my ($logfile4) = $logfile . ".4";
|
||||
|
||||
if (-f $logfile)
|
||||
{
|
||||
rename($logfile3, $logfile4) if (-f $logfile3);
|
||||
rename($logfile2, $logfile3) if (-f $logfile2);
|
||||
rename($logfile1, $logfile2) if (-f $logfile1);
|
||||
rename($logfile, $logfile1);
|
||||
}
|
||||
return $::OK;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 start_logging
|
||||
|
||||
Start logging messages to a logfile. Return the log file handle so it
|
||||
can be used to close the file when done logging.
|
||||
|
||||
Arguments:
|
||||
$logFile
|
||||
Returns:
|
||||
$::LOG_FILE_HANDLE
|
||||
Globals:
|
||||
$::LOG_FILE_HANDLE
|
||||
$::XCATLOG
|
||||
Error:
|
||||
$::NOK
|
||||
Example:
|
||||
xCAT::MsgUtils->start_logging($cfmupdatenode.log);
|
||||
Comments:
|
||||
Common method for logging script runtime output.
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub start_logging
|
||||
{
|
||||
my ($class, $logfile) = @_;
|
||||
my ($cmd, $rc);
|
||||
xCAT::MsgUtils->backup_logfile($logfile);
|
||||
|
||||
# create the log directory if it's not already there
|
||||
if (!-d $::XCATLOG)
|
||||
{
|
||||
mkdir($::XCATLOG, 0755);
|
||||
}
|
||||
|
||||
# open the log file
|
||||
unless (open(LOGFILE, ">>$logfile"))
|
||||
{
|
||||
|
||||
# Cannot open file
|
||||
xCAT::MsgUtils->message("E", "Cannot open file: $logfile.\n");
|
||||
return $::NOK;
|
||||
}
|
||||
|
||||
$::LOG_FILE_HANDLE = \*LOGFILE;
|
||||
|
||||
# Print the date to the top of the logfile
|
||||
my $sdate = localtime(time);
|
||||
chomp $sdate;
|
||||
my $program = xCAT::Utils->programName();
|
||||
xCAT::MsgUtils->message(
|
||||
"TV",
|
||||
"#--------------------------------------------------------------------------#\n"
|
||||
);
|
||||
xCAT::MsgUtils->message("TV", "$program: Logging Started:$sdate\n");
|
||||
xCAT::MsgUtils->message("TV", "Input: $::command_line\n");
|
||||
xCAT::MsgUtils->message(
|
||||
"TV",
|
||||
"#--------------------------------------------------------------------------#\n"
|
||||
);
|
||||
|
||||
return ($::LOG_FILE_HANDLE);
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 stop_logging
|
||||
|
||||
Turn off message logging close file. Routine expects to have a file handle
|
||||
passed in via the global $::LOG_FILE_HANDLE.
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
$::OK
|
||||
Globals:
|
||||
$::LOG_FILE_HANDLE
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
xCAT::MsgUtils->stop_logging($cfmupdatenode.log);
|
||||
Comments:
|
||||
closes the logfile and undefines $::LOG_FILE_HANDLE
|
||||
even on error.
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub stop_logging
|
||||
{
|
||||
my ($class) = @_;
|
||||
if (defined($::LOG_FILE_HANDLE))
|
||||
{
|
||||
|
||||
my $sdate = localtime(time);
|
||||
chomp $sdate;
|
||||
my $program = xCAT::Utils->programName();
|
||||
xCAT::MsgUtils->message(
|
||||
"TV",
|
||||
"#--------------------------------------------------------------------------#\n"
|
||||
);
|
||||
xCAT::MsgUtils->message("TV", "$program: Logging Stopped: $sdate\n");
|
||||
xCAT::MsgUtils->message(
|
||||
"TV",
|
||||
"#--------------------------------------------------------------------------#\n"
|
||||
);
|
||||
|
||||
close($::LOG_FILE_HANDLE);
|
||||
undef $::LOG_FILE_HANDLE;
|
||||
}
|
||||
return $::OK;
|
||||
}
|
||||
|
||||
1;
|
||||
|
325
perl-xCAT-2.0/xCAT/NodeRange.pm
Normal file
325
perl-xCAT-2.0/xCAT/NodeRange.pm
Normal file
@ -0,0 +1,325 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::NodeRange;
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
require Exporter;
|
||||
use strict;
|
||||
|
||||
#Perl implementation of noderange
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(noderange nodesmissed);
|
||||
|
||||
my $missingnodes=[];
|
||||
my $nodelist; #=xCAT::Table->new('nodelist',-create =>1);
|
||||
my $nodeprefix = "node";
|
||||
|
||||
|
||||
sub subnodes (\@@) {
|
||||
#Subtract set of nodes from the first list
|
||||
my $nodes = shift;
|
||||
my $node;
|
||||
foreach $node (@_) {
|
||||
@$nodes = (grep(!/^$node$/,@$nodes));
|
||||
}
|
||||
}
|
||||
sub nodesmissed {
|
||||
return @$missingnodes;
|
||||
}
|
||||
|
||||
sub expandatom {
|
||||
my $atom = shift;
|
||||
my $verify = (scalar(@_) == 1 ? shift : 1);
|
||||
my @nodes= ();
|
||||
my $nprefix=(defined ($ENV{'XCAT_NODE_PREFIX'}) ? $ENV{'XCAT_NODE_PREFIX'} : 'node');
|
||||
my $nsuffix=(defined ($ENV{'XCAT_NODE_SUFFIX'}) ? $ENV{'XCAT_NODE_PREFIX'} : '');
|
||||
if ($nodelist->getAttribs({node=>$atom},'node')) {
|
||||
#The atom is a plain old nodename
|
||||
return ($atom);
|
||||
}
|
||||
if ($atom =~ /^\(.*\)$/) {
|
||||
$atom =~ s/^\((.*)\)$/$1/;
|
||||
return noderange($atom);
|
||||
}
|
||||
foreach($nodelist->getAllAttribsWhere("groups like '%".$atom."%'",'node','groups')) {
|
||||
my @groups=split(/,/,$_->{groups}); #The where clause doesn't guarantee the atom is a full group name, only that it could be
|
||||
if (grep { $_ eq "$atom" } @groups ) {
|
||||
push @nodes,$_->{node};
|
||||
}
|
||||
}
|
||||
if ($atom =~ m/^[0-9]+\z/) {
|
||||
my $nodename=$nprefix.$atom.$nsuffix;
|
||||
return expandatom($nodename,$verify);
|
||||
}
|
||||
my $nodelen=@nodes;
|
||||
if ($nodelen > 0) {
|
||||
return @nodes;
|
||||
}
|
||||
if ($atom =~ m/(.*)\[(.*)\](.*)/) { #bracket range
|
||||
#for the time being, we are only going to consider one [] per atom
|
||||
#xcat 1.2 does no better
|
||||
my @subelems = split(/([\,\-\:])/,$2);
|
||||
my $subrange="";
|
||||
while (my $subelem = shift @subelems) {
|
||||
my $subop=shift @subelems;
|
||||
$subrange=$subrange."$1$subelem$3$subop";
|
||||
}
|
||||
foreach (split /,/,$subrange) {
|
||||
my @newnodes=expandatom($_,$verify);
|
||||
@nodes=(@nodes,@newnodes);
|
||||
}
|
||||
return @nodes;
|
||||
}
|
||||
if ($atom =~ m/\+/) {#process + operator
|
||||
$atom =~ m/^([^0-9]*)([0-9]+)([^\+]*)\+([0-9]+)/;
|
||||
my $pref=$1;
|
||||
my $startnum=$2;
|
||||
my $suf=$3;
|
||||
my $end=$4+$startnum;
|
||||
my $endnum = sprintf("%d",$end);
|
||||
if (length ($startnum) > length ($endnum)) {
|
||||
$endnum = sprintf("%0".length($startnum)."d",$end);
|
||||
}
|
||||
if (($pref eq "") && ($suf eq "")) {
|
||||
$pref=$nprefix;
|
||||
$suf=$nsuffix;
|
||||
}
|
||||
foreach ("$startnum".."$endnum") {
|
||||
my @addnodes=expandatom($pref.$_.$suf,$verify);
|
||||
@nodes=(@nodes,@addnodes);
|
||||
}
|
||||
return (@nodes);
|
||||
}
|
||||
if ($atom =~ m/[-:]/) {#process - range operator
|
||||
my $left;
|
||||
my $right;
|
||||
if ($atom =~ m/:/) {
|
||||
($left,$right)=split /:/,$atom;
|
||||
} else {
|
||||
my $count= ($atom =~ tr/-//);
|
||||
if (($count % 2)==0) { #can't understand even numbers of - in range context
|
||||
if ($verify) {
|
||||
push @$missingnodes,$atom;
|
||||
return ();
|
||||
} else { #but we might not really be in range context, if noverify
|
||||
return ($atom);
|
||||
}
|
||||
}
|
||||
my $expr="([^-]+?".("-[^-]*"x($count/2)).")-(.*)";
|
||||
$atom =~ m/$expr/;
|
||||
$left=$1;
|
||||
$right=$2;
|
||||
}
|
||||
if ($left eq $right) { #if they said node1-node1 for some strange reason
|
||||
return expandatom($left,$verify);
|
||||
}
|
||||
my @leftarr=split(/(\d+)/,$left);
|
||||
my @rightarr=split(/(\d+)/,$right);
|
||||
if (scalar(@leftarr) != scalar(@rightarr)) { #Mismatch formatting..
|
||||
if ($verify) {
|
||||
push @$missingnodes,$atom;
|
||||
return (); #mismatched range, bail.
|
||||
} else { #Not in verify mode, just have to guess it's meant to be a nodename
|
||||
return ($atom);
|
||||
}
|
||||
}
|
||||
my $prefix = "";
|
||||
my $suffix = "";
|
||||
foreach (0..$#leftarr) {
|
||||
my $idx = $_;
|
||||
if ($leftarr[$idx] =~ /^\d+$/ and $rightarr[$idx] =~ /^\d+$/) { #pure numeric component
|
||||
if ($leftarr[$idx] ne $rightarr[$idx]) { #We have found the iterator (only supporting one for now)
|
||||
my $prefix = join('',@leftarr[0..($idx-1)]); #Make a prefix of the pre-validated parts
|
||||
my $luffix; #However, the remainder must still be validated to be the same
|
||||
my $ruffix;
|
||||
if ($idx eq $#leftarr) {
|
||||
$luffix="";
|
||||
$ruffix="";
|
||||
} else {
|
||||
$ruffix = join('',@rightarr[($idx+1)..$#rightarr]);
|
||||
$luffix = join('',@leftarr[($idx+1)..$#leftarr]);
|
||||
}
|
||||
if ($luffix ne $ruffix) { #the suffixes mismatched..
|
||||
if ($verify) {
|
||||
push @$missingnodes,$atom;
|
||||
return ();
|
||||
} else {
|
||||
return ($atom);
|
||||
}
|
||||
}
|
||||
foreach ($leftarr[$idx]..$rightarr[$idx]) {
|
||||
my @addnodes=expandatom($prefix.$_.$luffix,$verify);
|
||||
@nodes=(@nodes,@addnodes);
|
||||
}
|
||||
return (@nodes); #the return has been built, return, exiting loop and all
|
||||
}
|
||||
} elsif ($leftarr[$idx] ne $rightarr[$idx]) {
|
||||
if ($verify) {
|
||||
push @$missingnodes,$atom;
|
||||
return ();
|
||||
} else {
|
||||
return ($atom);
|
||||
}
|
||||
}
|
||||
$prefix .= $leftarr[$idx]; #If here, it means that the pieces were the same, but more to come
|
||||
}
|
||||
#I cannot conceive how the code could possibly be here, but whatever it is, it must be questionable
|
||||
if ($verify) {
|
||||
push @$missingnodes,$atom;
|
||||
return (); #mismatched range, bail.
|
||||
} else { #Not in verify mode, just have to guess it's meant to be a nodename
|
||||
return ($atom);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($atom =~ m/^\//) { #A regex
|
||||
unless ($verify) { #If not in verify mode, regex makes zero possible sense
|
||||
return ($atom);
|
||||
}
|
||||
#TODO: check against all groups
|
||||
$atom = substr($atom,1);
|
||||
foreach ($nodelist->getAllAttribs('node')) {
|
||||
if ($_->{node} =~ m/^${atom}$/) {
|
||||
push(@nodes,$_->{node});
|
||||
}
|
||||
}
|
||||
return(@nodes);
|
||||
}
|
||||
push @$missingnodes,$atom;
|
||||
if ($verify) {
|
||||
return ();
|
||||
} else {
|
||||
return ($atom);
|
||||
}
|
||||
}
|
||||
|
||||
sub noderange {
|
||||
$missingnodes=[];
|
||||
#We for now just do left to right operations
|
||||
#TODO: Parentheses... A parenthetical group to the right of an intersection makes the obvious
|
||||
#answer not work
|
||||
my $range=shift;
|
||||
my $verify = (scalar(@_) == 1 ? shift : 1);
|
||||
$nodelist =xCAT::Table->new('nodelist',-create =>1);
|
||||
my %nodes = ();
|
||||
my %delnodes = ();
|
||||
my $op = ",";
|
||||
#my @elems = split(/(,(?![^[]*?])|@)/,$range); #, or @ but ignore , within []
|
||||
my @elems = split(/(,(?![^[]*?])(?![^\(]*?\))|@(?![^\(]*?\)))/,$range); #, or @ but ignore , within []
|
||||
|
||||
while (my $atom = shift @elems) {
|
||||
if ($atom =~ /^-/) {
|
||||
$atom = substr($atom,1);
|
||||
$op = $op."-";
|
||||
}
|
||||
if ($atom =~ /^\^(.*)$/) {
|
||||
open(NRF,$1);
|
||||
while (<NRF>) {
|
||||
my $line=$_;
|
||||
unless ($line =~ m/^[\^#]/) {
|
||||
$line =~ m/^([^: ]*)/;
|
||||
my $newrange = $1;
|
||||
chomp($newrange);
|
||||
my @filenodes = noderange($newrange);
|
||||
foreach (@filenodes) {
|
||||
$nodes{$_}=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(NRF);
|
||||
next;
|
||||
}
|
||||
my %newset = map { $_ =>1 } expandatom($atom,$verify);
|
||||
if ($op =~ /@/) {
|
||||
foreach (keys %nodes) {
|
||||
unless ($newset{$_}) {
|
||||
delete $nodes{$_};
|
||||
}
|
||||
}
|
||||
} elsif ($op =~ /,-/) {
|
||||
foreach (keys %newset) {
|
||||
$delnodes{$_}=1; #delay removal to end
|
||||
}
|
||||
} else {
|
||||
foreach (keys %newset) {
|
||||
$nodes{$_}=1;
|
||||
}
|
||||
}
|
||||
$op = shift @elems;
|
||||
}
|
||||
foreach (keys %nodes) {
|
||||
if ($delnodes{$_}) {
|
||||
delete $nodes{$_};
|
||||
}
|
||||
}
|
||||
undef $nodelist;
|
||||
return sort (keys %nodes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
xCAT::NodeRange - Perl module for xCAT noderange expansion
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use xCAT::NodeRange;
|
||||
my @nodes=noderange("storage@rack1,node[1-200],^/tmp/nodelist,node300-node400,node401+10,500-550");
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
noderange interprets xCAT noderange formatted strings and returns a list of xCAT nodelists. The following two operations are supported on elements, and interpreted left to right:
|
||||
|
||||
, union next element with everything to the left.
|
||||
|
||||
@ take intersection of element to the right with everything on the left (i.e. mask out anything to the left not belonging to what is described to the right)
|
||||
|
||||
Each element can be a number of things:
|
||||
|
||||
A node name, i.e.:
|
||||
|
||||
=item * node1
|
||||
|
||||
A hyphenated node range (only one group of numbers may differ between the left and right hand side, and those numbers will increment in a base 10 fashion):
|
||||
|
||||
node1-node200 node1-compute-node200-compute
|
||||
node1:node200 node1-compute:node200-compute
|
||||
|
||||
A noderange denoted by brackets:
|
||||
|
||||
node[1-200] node[001-200]
|
||||
|
||||
A regular expression describing the noderange:
|
||||
|
||||
/d(1.?.?|200)
|
||||
|
||||
A node plus offset (this increments the first number found in nodename):
|
||||
|
||||
node1+199
|
||||
|
||||
And most of the above substituting groupnames.
|
||||
3C
|
||||
3C
|
||||
|
||||
NodeRange tries to be intelligent about detecting padding, so you can:
|
||||
node001-node200
|
||||
And it will increment according to the pattern.
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Jarrod Johnson (jbjohnso@us.ibm.com)
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2007 IBM Corp. All rights reserved.
|
||||
|
||||
TODO: What license is this?
|
||||
|
||||
|
||||
|
||||
|
||||
=cut
|
334
perl-xCAT-2.0/xCAT/NotifHandler.pm
Normal file
334
perl-xCAT-2.0/xCAT/NotifHandler.pm
Normal file
@ -0,0 +1,334 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::NotifHandler;
|
||||
use File::Basename qw(fileparse);
|
||||
|
||||
#%notif is a cache that holds the info from the "notification" table.
|
||||
#the format of it is:
|
||||
# {tablename=>{'a'=>[filename,...]
|
||||
# 'u'=>[filename,,..]
|
||||
# 'd'=>[filename,...]
|
||||
# }
|
||||
# }
|
||||
%notif;
|
||||
$masterpid=$$;
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head1 xCATi::NotifHandler
|
||||
=head2 Package Description
|
||||
This mondule caches the notification table and tracks the changes of it.
|
||||
It also handles the event notification when xCAT database changes.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 setup
|
||||
It is called by xcatd to get set the pid of the parent of all this object.
|
||||
Setup the signal to trap any changes in the notification table. It also
|
||||
initializes the cache with the current data in the notification table.
|
||||
table and store it into %notif variable.
|
||||
Arguments:
|
||||
pid -- the process id of the caller.
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub setup
|
||||
{
|
||||
$masterpid=shift;
|
||||
if ($masterpid =~ /xCAT::NotifHandler/) {
|
||||
$masterpid=shift;
|
||||
}
|
||||
refreshNotification();
|
||||
$SIG{USR1}=\&handleNotifSigal;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 handleNotifSigal
|
||||
It is called when the signal is received. It then update the cache with the
|
||||
latest data in the notification table.
|
||||
Arguments:
|
||||
none.
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub handleNotifSigal {
|
||||
refreshNotification();
|
||||
$SIG{USR1}=\&handleNotifSigal;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 sendNotifSignal
|
||||
It is called by any module that has made changes to the notification table.
|
||||
Arguments:
|
||||
none.
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub sendNotifSignal {
|
||||
kill('USR1', $masterpid);
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 refreshNotification
|
||||
It loads the notification info from the "notification"
|
||||
table and store it into %notif variable.
|
||||
The format of it is:
|
||||
{tablename=>{filename=>{'ops'=>['y/n','y/n','y/n'], 'disable'=>'y/n'}}}
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub refreshNotification
|
||||
{
|
||||
#flush the cache
|
||||
%notif=();
|
||||
my $table=xCAT::Table->new("notification", -create =>0);
|
||||
if ($table) {
|
||||
#get array of rows out of the notification table
|
||||
my @row_array= $table->getTable;
|
||||
if (@row_array) {
|
||||
#store the information to the cache
|
||||
foreach(@row_array) {
|
||||
my $module=$_->{filename};
|
||||
my $ops=$_->{tableops};
|
||||
my $disable= $_->{disable};
|
||||
my @tablenames=split(/,/, $_->{tables});
|
||||
|
||||
foreach(@tablenames) {
|
||||
if (!exists($notif{$_})) {
|
||||
$notif{$_}={};
|
||||
}
|
||||
|
||||
|
||||
my $tempdisable=0;
|
||||
if ($disable) {
|
||||
if ($disable =~ m/^(yes|YES|Yes|Y|y|1)$/) {
|
||||
$tempdisable=1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$disable) {
|
||||
if ($ops) {
|
||||
if ($ops =~ m/a/) {
|
||||
if (exists($notif{$_}->{a})) {
|
||||
my $pa=$notif{$_}->{a};
|
||||
push(@$pa, $module);
|
||||
} else {
|
||||
$notif{$_}->{a}=[$module];
|
||||
}
|
||||
}
|
||||
if ($ops =~ m/d/) {
|
||||
if (exists($notif{$_}->{d})) {
|
||||
my $pa=$notif{$_}->{d};
|
||||
push(@$pa, $module);
|
||||
} else {
|
||||
$notif{$_}->{d}=[$module];
|
||||
}
|
||||
}
|
||||
if ($ops =~ m/u/) {
|
||||
if (exists($notif{$_}->{u})) {
|
||||
my $pa=$notif{$_}->{u};
|
||||
push(@$pa, $module);
|
||||
} else {
|
||||
$notif{$_}->{u}=[$module];
|
||||
}
|
||||
}
|
||||
} #end if
|
||||
}
|
||||
} #end foreach
|
||||
|
||||
} #end foreach(@row_array)
|
||||
}end if (@row_array)
|
||||
} #end if ($table)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 dumpNotificationCache
|
||||
It print out the content of the notification cache for debugging purpose.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
0
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub dumpNotificationCache {
|
||||
print "dump the notification cache:\n";
|
||||
foreach(keys(%notif)) {
|
||||
my $tmptn=$_;
|
||||
print " $tmptn: \n";
|
||||
|
||||
if (exists($notif{$_}->{a})) {
|
||||
print " a--:";
|
||||
my $files=$notif{$_}->{a};
|
||||
print "@$files\n";
|
||||
}
|
||||
if (exists($notif{$_}->{u})) {
|
||||
print " u--:";
|
||||
my $files=$notif{$_}->{u};
|
||||
print "@$files\n";
|
||||
}
|
||||
if (exists($notif{$_}->{d})) {
|
||||
print " d--:";
|
||||
my $files=$notif{$_}->{d};
|
||||
print "@$files\n";
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 needToNotify
|
||||
It check if the given table has interested parties watching for its changes.
|
||||
Arguments:
|
||||
tablename - the name of the table to be checked.
|
||||
tableop - the operation on the table. 'a' for add, 'u' for update
|
||||
and 'd' for delete.
|
||||
Returns:
|
||||
1 - if the table has interested parties.
|
||||
0 - if no parties are interested in its changes.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub needToNotify {
|
||||
if (!defined %notif) {
|
||||
# print "notif not defined\n";
|
||||
refreshNotification();
|
||||
}
|
||||
|
||||
my $tablename=shift;
|
||||
if ($tablename =~ /xCAT::NotifHandler/) {
|
||||
$tablename=shift;
|
||||
}
|
||||
my $tableop=shift;
|
||||
|
||||
if (%notif) {
|
||||
if (exists($notif{$tablename})) {
|
||||
if (exists($notif{$tablename}->{$tableop})) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 notify
|
||||
It notifies the registered the modules with the latest changes in
|
||||
a DB table.
|
||||
Arguments:
|
||||
action - table action. It can be d for rows deleted, a for rows added
|
||||
or u for rows updated.
|
||||
tablename - string. The name of the DB table whose data has been changed.
|
||||
old_data - an array reference of the old row data that has been changed.
|
||||
The first element is an array reference that contains the column names.
|
||||
The rest of the elelments are also array references each contains
|
||||
attribute values of a row.
|
||||
It is set when the action is u or d.
|
||||
new_data - a hash refernce of new row data; only changed values are present
|
||||
in the hash. It is keyed by column names.
|
||||
It is set when the action is u or a.
|
||||
Returns:
|
||||
0
|
||||
Comments:
|
||||
If the curent table is watched by a perl module, the module must implement
|
||||
the following routine:
|
||||
processTableChanges(action, table_name, old_data, new_data)
|
||||
If it is a watched by a command, the data will be passed to the command
|
||||
through STDIN. The format is:
|
||||
action
|
||||
table_name
|
||||
[old data]
|
||||
col1_name,col2_name,...
|
||||
col1_value,col2_value,...
|
||||
...
|
||||
[new data]
|
||||
col1_name,col2_name,...
|
||||
col1_value,col2_value,...
|
||||
...
|
||||
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub notify {
|
||||
my $action=shift;
|
||||
if ($action =~ /xCAT::NotifHandler/) {
|
||||
$action=shift;
|
||||
}
|
||||
my $tablename=shift;
|
||||
my $old_data=shift;
|
||||
my $new_data=shift;
|
||||
|
||||
# print "notify called: tablename=$tablename, action=$action\n";
|
||||
|
||||
my @filenames=();
|
||||
if (%notif) {
|
||||
if (exists($notif{$tablename})) {
|
||||
if (exists($notif{$tablename}->{$action})) {
|
||||
my $pa=$notif{$tablename}->{$action};
|
||||
@filenames=@$pa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach(@filenames) {
|
||||
my ($modname, $path, $suffix) = fileparse($_, ".pm");
|
||||
# print "modname=$modname, path=$path, suffix=$suffix\n";
|
||||
if ($suffix =~ /.pm/) { #it is a perl module
|
||||
my $pid;
|
||||
if ($pid=fork()) { }
|
||||
elsif (defined($pid)) {
|
||||
if (($path eq "") || ($path eq ".\/")) {
|
||||
#default path is /usr/lib/xcat/monitoring/ if there is no path specified
|
||||
require "/usr/lib/xcat/monitoring/".$modname.".pm";
|
||||
} else {
|
||||
require $_;
|
||||
}
|
||||
${"xCAT_monitoring::".$modname."::"}{processTableChanges}->($action, $tablename, $old_data, $new_data);
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
else { #it is a command
|
||||
my $pid;
|
||||
if ($pid=fork()) { }
|
||||
elsif (defined($pid)) {
|
||||
# print "command=$_\n";
|
||||
if (open(CMD, "|$_")) {
|
||||
print(CMD "$action\n");
|
||||
print(CMD "$tablename\n");
|
||||
|
||||
print(CMD "[old data]\n");
|
||||
foreach (@$old_data) {
|
||||
print(CMD join(',', @$_)."\n");
|
||||
}
|
||||
|
||||
print(CMD "[new data]\n");
|
||||
if (%$new_data) {
|
||||
print(CMD join(',', keys %$new_data) . "\n");
|
||||
print(CMD join(',', values %$new_data) . "\n");
|
||||
}
|
||||
close(CMD) or print "Cannot close the command $_\n";
|
||||
}
|
||||
else {
|
||||
print "Command $_ cannot be found\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
} #elsif
|
||||
}
|
||||
} #foreach
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
297
perl-xCAT-2.0/xCAT/Postage.pm
Normal file
297
perl-xCAT-2.0/xCAT/Postage.pm
Normal file
@ -0,0 +1,297 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::Postage;
|
||||
use xCAT::Table;
|
||||
use xCAT::NodeRange;
|
||||
use Data::Dumper;
|
||||
my $depsfile = "/etc/xcat/postscripts.dep";
|
||||
my $rulesfile = "/etc/xcat/postscripts.rules";
|
||||
my $rules;
|
||||
my $deps;
|
||||
my $rulec;
|
||||
my $node;
|
||||
|
||||
sub writescript {
|
||||
if (scalar(@_) eq 3) { shift; } #Discard self
|
||||
$node = shift;
|
||||
my $scriptfile = shift;
|
||||
my $script;
|
||||
open($rules,"<",$rulesfile);
|
||||
open($deps,"<",$depsfile);
|
||||
unless($rules) {
|
||||
return undef;
|
||||
}
|
||||
open($script,">",$scriptfile);
|
||||
unless ($scriptfile) {
|
||||
return undef;
|
||||
}
|
||||
#Some common variables...
|
||||
my $noderestab=xCAT::Table->new('noderes');
|
||||
my $typetab=xCAT::Table->new('nodetype');
|
||||
unless ($noderestab and $typetab) {
|
||||
die "Unable to open noderes or nodetype table";
|
||||
}
|
||||
my $master;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
(my $et) = $sitetab->getAttribs({key=>"master"},'value');
|
||||
if ($et and $et->{value}) {
|
||||
$master = $et->{value};
|
||||
}
|
||||
$et = $noderestab->getNodeAttribs($node,['xcatmaster']);
|
||||
if ($et and $et->{'xcatmaster'}) {
|
||||
$master = $et->{'xcatmaster'};
|
||||
}
|
||||
unless ($master) {
|
||||
die "Unable to identify master for $node";
|
||||
}
|
||||
print $script "MASTER=".$master."\n";
|
||||
print $script "export MASTER\n";
|
||||
my $et = $typetab->getNodeAttribs($node,['os','arch']);
|
||||
unless ($et and $et->{'os'} and $et->{'arch'}) {
|
||||
die "No os/arch setting in nodetype table for $node";
|
||||
}
|
||||
print $script "OSVER=".$et->{'os'}."\n";
|
||||
print $script "ARCH=".$et->{'arch'}."\n";
|
||||
print $script "export OSVER ARCH\n";
|
||||
print $script 'PATH=`dirname $0`:$PATH'."\n";
|
||||
print $script "export PATH\n";
|
||||
$rulec="";
|
||||
my @scripts;
|
||||
my $inlist = 0;
|
||||
my $pushmode = 0;
|
||||
my $critline="";
|
||||
while (<$rules>) {
|
||||
my $line = $_;
|
||||
$line =~ s/^\s*//;
|
||||
$line =~ s/\s*$//;
|
||||
$line =~ s/#.*//;
|
||||
if ($line =~ /^$/) {
|
||||
next;
|
||||
}
|
||||
# we are left with content lines..
|
||||
my $donewithline=0;
|
||||
while (not $donewithline) {
|
||||
if ($line =~ /^\s*$/) {
|
||||
$donewithline=1;
|
||||
next;
|
||||
}
|
||||
if ($inlist) {
|
||||
if ($line =~/^[^\}]*\{/) {
|
||||
#TODO: error unbalanced {} in postscripts.rules
|
||||
die "Unbalanced {}";
|
||||
return undef;
|
||||
}
|
||||
if ($pushmode) {
|
||||
my $toadd;
|
||||
($toadd) = $line =~ /(^[^\}]*)/;
|
||||
$line =~ s/(^[^\}]*)//;
|
||||
unless ($toadd =~ /^\s*$/) {
|
||||
push @scripts,$toadd;
|
||||
}
|
||||
} else { #strip non } characters leading
|
||||
$line =~ s/^[^\}]*//;
|
||||
}
|
||||
if ($line =~ /\}/) {
|
||||
$line =~ s/\}//;
|
||||
$inlist=0;
|
||||
}
|
||||
} else {
|
||||
if ($line =~/^[^\{]*\}/) {
|
||||
#TODO: error unbalanced {} in postscripts.rules
|
||||
return undef;
|
||||
}
|
||||
(my $tcritline) = $line =~ /^([^\{]*)/;
|
||||
$critline .= $tcritline . " ";
|
||||
if ($line =~ /\{/) {
|
||||
if (criteriamatches($critline)) {
|
||||
$pushmode=1;
|
||||
} else {
|
||||
$pushmode=0;
|
||||
}
|
||||
$critline = "";
|
||||
$inlist = 1;
|
||||
$line =~ s/[^\{]*\{//;
|
||||
} else {
|
||||
$donewithline=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (@scripts) {
|
||||
print $script $_."\n";
|
||||
}
|
||||
close($script);
|
||||
chmod 0755,$scriptfile;
|
||||
}
|
||||
|
||||
#shamelessly brought forth from postrules.pl in xCAT 1.3
|
||||
sub criteriamatches {
|
||||
my $cline = shift;
|
||||
my $level=0;
|
||||
my $pline;
|
||||
my @opstack;
|
||||
my @expstack;
|
||||
my $r;
|
||||
$cline =~ s/\{//g;
|
||||
$cline =~ s/(\(|\))/ $1 /g;
|
||||
$cline =~ s/\s*=\s*/=/g;
|
||||
$cline =~ s/^\s*//;
|
||||
$cline =~ s/\s*$//;
|
||||
$cline =~ s/\s+/ /;
|
||||
if ($cline =~ /^ALL$/) {
|
||||
return 1;
|
||||
}
|
||||
my @tokens = split('\s+',$cline);
|
||||
my $token;
|
||||
foreach $token (@tokens) {
|
||||
if ($token eq ')') {
|
||||
$level--;
|
||||
if ($level == 0) {
|
||||
push @expstack,criteriamatches($pline);
|
||||
$pline="";
|
||||
next;
|
||||
} elsif ($level < 0) {
|
||||
die "Unbalanecd () in postrules";
|
||||
}
|
||||
}
|
||||
if ($level) {
|
||||
$pline .= " $token";
|
||||
}
|
||||
if ($token eq '(') {
|
||||
$level++;
|
||||
next;
|
||||
}
|
||||
if ($level) {
|
||||
next;
|
||||
}
|
||||
if ($token =~ /=/) {
|
||||
push(@expstack,$token);
|
||||
next;
|
||||
}
|
||||
if ($token =~ /^(and|or|not)$/i) {
|
||||
push (@opstack,$token);
|
||||
next;
|
||||
}
|
||||
die "Syntax error in postscripts rules, bad token $token";
|
||||
}
|
||||
if ($level) {
|
||||
die "Unbalanced () in postscripts rules";
|
||||
}
|
||||
|
||||
while (@opstack) {
|
||||
my $op;
|
||||
my $r1 = 0;
|
||||
my $r2 = 0;
|
||||
|
||||
$op = pop(@opstack);
|
||||
unless (defined $op) {
|
||||
die "Stack underflow in postscripts rules";
|
||||
}
|
||||
if ($op =~ /and/i) {
|
||||
$r1 = popeval(\@expstack);
|
||||
$r2 = popeval(\@expstack);
|
||||
|
||||
if ($r1 && $r2) {
|
||||
push(@expstack,1);
|
||||
} else {
|
||||
push(@expstack,0);
|
||||
}
|
||||
} elsif ($op =~ /or/i) {
|
||||
$r1 = popeval(\@expstack);
|
||||
$r2 = popeval(\@expstack);
|
||||
if ($r1 || $r2) {
|
||||
push(@expstack,1);
|
||||
} else {
|
||||
push(@expstack,0);
|
||||
}
|
||||
} elsif ($op =~ /not/i) {
|
||||
$r1 = popeval(\@expstack);
|
||||
if ($r1==0) {
|
||||
push(@expstack,1);
|
||||
} else {
|
||||
push (@expstack,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (@expstack == 1) {
|
||||
$r = popeval(\@expstack);
|
||||
push(@expstack,$r);
|
||||
}
|
||||
|
||||
$r = pop(@expstack);
|
||||
unless (defined $r) {
|
||||
die "Stack underflow in postscripts processing";
|
||||
}
|
||||
if (@expstack != 0 || @opstack != 0) {
|
||||
die "Stack underflow in postscripts processing";
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
sub popeval {
|
||||
my ($expstack) = @_;
|
||||
my $exp;
|
||||
my $v;
|
||||
my $r;
|
||||
$exp = pop(@$expstack);
|
||||
if (defined ($exp)) {
|
||||
if ($exp =~ /=/) {
|
||||
my @eqarr = split(/=/,$exp);
|
||||
$r = $eqarr[$#eqarr];
|
||||
$v = join('=',@eqarr[0..($#eqarr-1)]);
|
||||
#($v,$r) = split(/=/,$exp);
|
||||
if ($v =~ /^OSVER$/) { #OSVER is redundant, but a convenient shortcut
|
||||
$v = 'TABLE:nodetype:$NODE:os';
|
||||
}
|
||||
if ($v =~ /^NODERANGE$/i) {
|
||||
my @nr = noderange $r;
|
||||
foreach (@nr) {
|
||||
if ($node eq $_) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if ($v =~ /^TABLE:/) {
|
||||
my $table;
|
||||
my $key;
|
||||
my $field;
|
||||
($table,$key,$field) = $v =~ m/TABLE:([^:]+):([^:]+):(.*)/;
|
||||
my $tabref = xCAT::Table->new($table);
|
||||
unless ($tabref) { return 0; }
|
||||
my $ent;
|
||||
if ($key =~ /^\$NODE/) {
|
||||
$ent = $tabref->getNodeAttribs($node,[$field]);
|
||||
} else {
|
||||
my @keys = split /,/,$key;
|
||||
my %keyh;
|
||||
foreach (@keys) {
|
||||
my $keycol;
|
||||
my $keyval;
|
||||
($keycol,$keyvol)=split /=/,$_;
|
||||
$keyh{$keycol}=$keyvol;
|
||||
}
|
||||
($ent)=$tabref->getAttribs(\%keyh,$field);
|
||||
}
|
||||
|
||||
unless ($ent and $ent->{$field}) { return 0; }
|
||||
if ($ent->{$field} =~ /^$r$/) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#TODO? support for env vars? Don't see much of a point now, but need input
|
||||
} elsif ($exp == 0 || $exp == 1) {
|
||||
return ($exp);
|
||||
} else {
|
||||
die "Invalid expression $exp in postcripts rules";
|
||||
}
|
||||
} else {
|
||||
die "Stack underflow in postscripts rules...";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
347
perl-xCAT-2.0/xCAT/Schema.pm
Normal file
347
perl-xCAT-2.0/xCAT/Schema.pm
Normal file
@ -0,0 +1,347 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::Schema;
|
||||
|
||||
#Note that the SQL is far from imaginative. Fact of the matter is that
|
||||
#certain SQL backends don't ascribe meaning to the data types anyway.
|
||||
#New format, not sql statements, but info enough to describe xcat tables
|
||||
%tabspec = (
|
||||
nodetype => {
|
||||
cols => [qw(node os arch profile comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
nodepos => {
|
||||
cols => [qw(node rack u chassis slot room comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
vpd => {
|
||||
cols => [qw(node serial mtm comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
nodehm => {
|
||||
cols => [qw(node power mgt cons termserver termport conserver serialspeed serialflow getmac comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
hosts => {
|
||||
cols => [qw(node ip hostnames comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
mp => {
|
||||
cols => [qw(node mpa id comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
mpa => {
|
||||
cols => [qw(mpa username password comments disable)],
|
||||
keys => [qw(mpa)],
|
||||
},
|
||||
mac => {
|
||||
cols => [qw(node interface mac comments disable)],
|
||||
keys => [qw(node interface)],
|
||||
},
|
||||
chain => {
|
||||
cols => [qw(node currstate currchain chain ondiscover comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
noderes => {
|
||||
cols => [qw(node servicenode netboot tftpserver nfsserver kernel initrd kcmdline nfsdir serialport installnic primarynic xcatmaster current_osimage next_osimage comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
networks => {
|
||||
cols => [qw(netname net mask gateway dhcpserver tftpserver nameservers dynamicrange comments disable)],
|
||||
keys => [qw(net mask)]
|
||||
},
|
||||
switch => {
|
||||
cols => [qw(node switch vlan port comments disable)],
|
||||
keys => [qw(node switch port)]
|
||||
},
|
||||
nodelist => {
|
||||
cols => [qw(node nodetype groups comments disable)],
|
||||
keys => [qw(node)],
|
||||
},
|
||||
site => {
|
||||
cols => [qw(key value comments disable)],
|
||||
keys => [qw(key)]
|
||||
},
|
||||
passwd => {
|
||||
cols => [qw(key username password comments disable)],
|
||||
keys => [qw(key)]
|
||||
},
|
||||
ipmi => {
|
||||
cols => [qw(node bmc username password comments disable )],
|
||||
keys => [qw(node)]
|
||||
},
|
||||
policy => {
|
||||
cols => [qw(priority name host commands noderange parameters time rule comments disable)],
|
||||
keys => [qw(priority)]
|
||||
},
|
||||
notification => {
|
||||
cols => [qw(filename tables tableops comments disable)],
|
||||
keys => [qw(filename)],
|
||||
required => [qw(tables filename)]
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
####################################################
|
||||
#
|
||||
# Data abstraction definitions
|
||||
# For each table entry added to the database schema,
|
||||
# a corresponding attribute should be added to one of
|
||||
# the data objects below, or new data objects should
|
||||
# be created as needed.
|
||||
#
|
||||
# Definition format:
|
||||
# List of data object hashes:
|
||||
# <dataobject_name> =>
|
||||
# {attrs =>
|
||||
# [ {attr_name => '<attribute_name>',
|
||||
# only_if => '<attr>=<value>',
|
||||
# # optional, used to define conditional attributes.
|
||||
# # <attr> is a previously resolved attribute from
|
||||
# # this data object.
|
||||
# tabentry => '<table.attr>',
|
||||
# # where the data is stored in the database
|
||||
# access_tabentry => '<table.attr>=<value>',
|
||||
# # how to look up tabentry. For <value>,
|
||||
# # if "attr:<attrname>", use a previously resolved
|
||||
# # attribute value from the data object
|
||||
# # if "str:<value>" use the value directly
|
||||
# description => '<description of this attribute>',
|
||||
# },
|
||||
# {attr_name => <attribute_name>,
|
||||
# ...
|
||||
# } ],
|
||||
# attrhash => {}, # internally generated hash of attrs array
|
||||
# # to allow code direct access to an attr def
|
||||
# objkey => 'attribute_name' # key attribute for this data object
|
||||
# }
|
||||
#
|
||||
#
|
||||
####################################################
|
||||
%defspec = (
|
||||
node => { attrs => [], attrhash => {}, objkey => 'node' },
|
||||
osimage => { attrs => [], attrhash => {}, objkey => 'imagename' },
|
||||
network => { attrs => [], attrhash => {}, objkey => 'netname' },
|
||||
site => { attrs => [], attrhash => {}, objkey => 'master' }
|
||||
);
|
||||
|
||||
#############
|
||||
# TODO: Need to figure out how to map the following to data objects:
|
||||
# nodetype table (does this get moved to the osimage table?)
|
||||
# --> do we need an arch attr per node that is stored in nodehm?
|
||||
# mac table (are we going to have an interface object definition?)
|
||||
# switch table (each interface on a node can have its own switch
|
||||
# table entry, part of interface object, too?)
|
||||
# username/password from password, hmc, ivm, mpa, and ipmi tables
|
||||
# (do we need special encryption and display masking for passwords?)
|
||||
# chain table (I think this is internal use only, do not abstract?)
|
||||
# noderes entries for kernel, initrd, kcmdline
|
||||
# ppc table (waiting on Scot to add to tabspec)
|
||||
# policy table - ? do we need a data abstraction for this?
|
||||
# notification - is this handled by Ling's commands?
|
||||
# site - need to figure out what entries we will have in the
|
||||
# site table since they are not listed individually in the
|
||||
# tabspec
|
||||
# nodelist.groups
|
||||
# new group table and object
|
||||
# new osimage table and object
|
||||
###############
|
||||
# TODO: need to fill out all the "description" fields
|
||||
# These will be used for verbose usage with the def* cmds
|
||||
##############
|
||||
@{$defspec{node}->{'attrs'}} = (
|
||||
{attr_name => 'node',
|
||||
tabentry => 'nodelist.node',
|
||||
access_tabentry => 'objkeyvalue'},
|
||||
############
|
||||
# TODO: The attr name for nodelist.nodetype is in conflict with the existing
|
||||
# nodetype table. With the osimage table, the nodetype table should go
|
||||
# away. Will reuse of this name cause confusion for xcat users?
|
||||
############
|
||||
{attr_name => 'nodetype',
|
||||
tabentry => 'nodelist.nodetype',
|
||||
access_tabentry => 'nodelist.node=attr:node',
|
||||
description => 'Type of node: osi,hmc,fsp,mpa,???'},
|
||||
{attr_name => 'xcatmaster',
|
||||
tabentry => 'noderes.xcatmaster',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'servicenode',
|
||||
tabentry => 'noderes.servicenode',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'mgt',
|
||||
tabentry => 'nodehm.mgt',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'power',
|
||||
tabentry => 'nodehm.power',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'cons',
|
||||
tabentry => 'nodehm.cons',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'termserver',
|
||||
tabentry => 'nodehm.termserver',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'termport',
|
||||
tabentry => 'nodehm.termport',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'conserver',
|
||||
tabentry => 'nodehm.conserver',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'getmac',
|
||||
tabentry => 'nodehm.getmac',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'serialport',
|
||||
tabentry => 'noderes.serialport',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'serialspeed',
|
||||
tabentry => 'nodehm.serialspeed',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'serialflow',
|
||||
tabentry => 'nodehm.serialflow',
|
||||
access_tabentry => 'nodehm.node=attr:node'},
|
||||
{attr_name => 'ip',
|
||||
tabentry => 'hosts.ip',
|
||||
access_tabentry => 'hosts.node=attr:node'},
|
||||
{attr_name => 'hostnames',
|
||||
tabentry => 'hosts.hostnames',
|
||||
access_tabentry => 'hosts.node=attr:node'},
|
||||
{attr_name => 'serialnumber',
|
||||
tabentry => 'vpd.serial',
|
||||
access_tabentry => 'vpd.node=attr:node'},
|
||||
{attr_name => 'mtm',
|
||||
tabentry => 'vpd.mtm',
|
||||
access_tabentry => 'vpd.node=attr:node'},
|
||||
{attr_name => 'rackloc',
|
||||
tabentry => 'nodepos.rack',
|
||||
access_tabentry => 'nodepos.node=attr:node'},
|
||||
{attr_name => 'unitloc',
|
||||
tabentry => 'nodepos.u',
|
||||
access_tabentry => 'nodepos.node=attr:node'},
|
||||
{attr_name => 'chassisloc',
|
||||
tabentry => 'nodepos.chassis',
|
||||
access_tabentry => 'nodepos.node=attr:node'},
|
||||
{attr_name => 'slotloc',
|
||||
tabentry => 'nodepos.slot',
|
||||
access_tabentry => 'nodepos.node=attr:node'},
|
||||
{attr_name => 'roomloc',
|
||||
tabentry => 'nodepos.room',
|
||||
access_tabentry => 'nodepos.node=attr:node'},
|
||||
|
||||
# Conditional attributes:
|
||||
# OSI node attributes:
|
||||
{attr_name => 'tftpserver',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.tftpserver',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'nfsserver',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.nfsserver',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'nfsdir',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.nfsdir',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'primarynic',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.primarynic',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'installnic',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.installnic',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'netboot',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.netboot',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'current_osimage',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.current_osimage',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
{attr_name => 'next_osimage',
|
||||
only_if => 'nodetype=osi',
|
||||
tabentry => 'noderes.next_osimage',
|
||||
access_tabentry => 'noderes.node=attr:node'},
|
||||
|
||||
# Hardware Control node attributes:
|
||||
{attr_name => hdwctrlpoint,
|
||||
only_if => 'mgtmethod=mp',
|
||||
tabentry => 'mp.mpa',
|
||||
access_tabentry => 'mp.node=attr:node'},
|
||||
# {attr_name => hdwctrlpoint,
|
||||
# only_if => 'mgtmethod=hmc',
|
||||
# tabentry => 'ppc.hcp',
|
||||
# access_tabentry => 'ppc.node=attr:node'},
|
||||
{attr_name => hdwctrlpoint,
|
||||
only_if => 'mgtmethod=ipmi',
|
||||
tabentry => 'ipmi.bmc',
|
||||
access_tabentry => 'ipmi.node=attr:node'},
|
||||
{attr_name => hdwctrlnodeid,
|
||||
only_if => 'mgtmethod=mp',
|
||||
tabentry => 'mp.id',
|
||||
access_tabentry => 'mp.node=attr:node'},
|
||||
# {attr_name => hdwctrlnodeid,
|
||||
# only_if => 'mgtmethod=hmc',
|
||||
# tabentry => 'ppc.id',
|
||||
# access_tabentry => 'ppc.node=attr:node'}
|
||||
);
|
||||
|
||||
@{$defspec{osimage}->{'attrs'}} = (
|
||||
{attr_name => 'imagename',
|
||||
tabentry => 'osimage.imagename',
|
||||
access_tabentry => 'objkeyvalue',
|
||||
description => 'Name of OS image'},
|
||||
{attr_name => 'osdistro',
|
||||
tabentry => 'osimage.osdistro',
|
||||
access_tabentry => 'osimage.objname=attr:imagename'},
|
||||
);
|
||||
|
||||
@{$defspec{network}->{'attrs'}} = (
|
||||
{attr_name => 'netname',
|
||||
tabentry => 'networks.netname',
|
||||
access_tabentry => 'objkeyvalue',
|
||||
description => 'Name to identify the network'},
|
||||
{attr_name => 'net',
|
||||
tabentry => 'networks.net',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
{attr_name => 'mask',
|
||||
tabentry => 'networks.mask',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
{attr_name => 'gateway',
|
||||
tabentry => 'networks.gateway',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
{attr_name => 'dhcpserver',
|
||||
tabentry => 'networks.dhcpserver',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
{attr_name => 'tftpserver',
|
||||
tabentry => 'networks.tftpserver',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
{attr_name => 'nameservers',
|
||||
tabentry => 'networks.nameservers',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
{attr_name => 'dynamicrange',
|
||||
tabentry => 'networks.dynamicrange',
|
||||
access_tabentry => 'networks.netname=attr:netname'},
|
||||
);
|
||||
|
||||
##############
|
||||
# TODO: need to figure out how to handle a key for the site table.
|
||||
# since this is really implemented differently than all the other
|
||||
# data objects, it doesn't map as cleanly.
|
||||
# change format of site table so each column is an attr and there
|
||||
# is only a single row in the table keyed by xcatmaster name?
|
||||
#############
|
||||
@{$defspec{site}->{'attrs'}} = (
|
||||
{attr_name => 'master',
|
||||
tabentry => 'site.value',
|
||||
access_tabentry => 'site.key=str:master',
|
||||
description => 'The management node'},
|
||||
{attr_name => 'installdir',
|
||||
tabentry => 'site.value',
|
||||
access_tabentry => 'site.key=str:installdir',
|
||||
description => 'The installation directory'},
|
||||
{attr_name => 'xcatdport',
|
||||
tabentry => 'site.value',
|
||||
access_tabentry => 'site.key=str:xcatdport',
|
||||
description => 'Port used by xcatd daemon on master'},
|
||||
);
|
||||
|
||||
|
1470
perl-xCAT-2.0/xCAT/Table.pm
Normal file
1470
perl-xCAT-2.0/xCAT/Table.pm
Normal file
File diff suppressed because it is too large
Load Diff
213
perl-xCAT-2.0/xCAT/Template.pm
Executable file
213
perl-xCAT-2.0/xCAT/Template.pm
Executable file
@ -0,0 +1,213 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::Template;
|
||||
use strict;
|
||||
use xCAT::Table;
|
||||
use File::Basename;
|
||||
use File::Path;
|
||||
use Data::Dumper;
|
||||
use Sys::Syslog;
|
||||
|
||||
my $table;
|
||||
my $key;
|
||||
my $field;
|
||||
my $idir;
|
||||
my $node;
|
||||
|
||||
sub subvars {
|
||||
my $self = shift;
|
||||
my $inf = shift;
|
||||
my $outf = shift;
|
||||
$node = shift;
|
||||
my $outh;
|
||||
my $inh;
|
||||
$idir = dirname($inf);
|
||||
open($inh,"<",$inf);
|
||||
unless ($inh) {
|
||||
return undef;
|
||||
}
|
||||
mkpath(dirname($outf));
|
||||
open($outh,">",$outf);
|
||||
unless($outh) {
|
||||
return undef;
|
||||
}
|
||||
my $inc;
|
||||
#First load input into memory..
|
||||
while (<$inh>) {
|
||||
$inc.=$_;
|
||||
}
|
||||
close($inh);
|
||||
my $master;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
my $noderestab = xCAT::Table->new('noderes');
|
||||
(my $et) = $sitetab->getAttribs({key=>"master"},'value');
|
||||
if ($et and $et->{value}) {
|
||||
$master = $et->{value};
|
||||
}
|
||||
$et = $noderestab->getNodeAttribs($node,['xcatmaster']);
|
||||
if ($et and $et->{'xcatmaster'}) {
|
||||
$master = $et->{'xcatmaster'};
|
||||
}
|
||||
unless ($master) {
|
||||
die "Unable to identify master for $node";
|
||||
}
|
||||
$ENV{XCATMASTER}=$master;
|
||||
#FIRST, do *all* includes, recursive and all
|
||||
my $doneincludes=0;
|
||||
while (not $doneincludes) {
|
||||
$doneincludes=1;
|
||||
if ($inc =~ /#INCLUDE:[^#]+#/) {
|
||||
$doneincludes=0;
|
||||
$inc =~ s/#INCLUDE:([^#]+)#/includefile($1)/eg;
|
||||
}
|
||||
}
|
||||
#ok, now do everything else..
|
||||
$inc =~ s/#COMMAND:([^#]+)#/command($1)/eg;
|
||||
$inc =~ s/#TABLE:([^:]+):([^:]+):([^#]+)#/tabdb($1,$2,$3)/eg;
|
||||
$inc =~ s/#CRYPT:([^:]+):([^:]+):([^#]+)#/crydb($1,$2,$3)/eg;
|
||||
$inc =~ s/#XCATVAR:([^#]+)#/envvar($1)/eg;
|
||||
$inc =~ s/#ENV:([^#]+)#/envvar($1)/eg;
|
||||
print $outh $inc;
|
||||
close($outh);
|
||||
return 1;
|
||||
}
|
||||
sub includefile
|
||||
{
|
||||
my $file = shift;
|
||||
my $text = "";
|
||||
unless ($file =~ /^\//) {
|
||||
$file = $idir."/".$file;
|
||||
}
|
||||
|
||||
open(INCLUDE,$file) || \
|
||||
return "#INCLUDEBAD:cannot open $file#";
|
||||
|
||||
while(<INCLUDE>) {
|
||||
$text .= "$_";
|
||||
}
|
||||
|
||||
close(INCLUDE);
|
||||
|
||||
chomp($text);
|
||||
return($text);
|
||||
}
|
||||
|
||||
sub command
|
||||
{
|
||||
my $command = shift;
|
||||
my $r;
|
||||
|
||||
# if(($r = `$command`) == 0) {
|
||||
# chomp($r);
|
||||
# return($r);
|
||||
# }
|
||||
# else {
|
||||
# return("#$command: failed $r#");
|
||||
# }
|
||||
|
||||
$r = `$command`;
|
||||
chomp($r);
|
||||
return($r);
|
||||
}
|
||||
|
||||
sub envvar
|
||||
{
|
||||
my $envvar = shift;
|
||||
|
||||
if($envvar =~ /^\$/) {
|
||||
$envvar =~ s/^\$//;
|
||||
}
|
||||
|
||||
return($ENV{$envvar});
|
||||
}
|
||||
|
||||
sub genpassword {
|
||||
#Generate a pseudo-random password of specified length
|
||||
my $length = shift;
|
||||
my $password='';
|
||||
my $characters= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
|
||||
srand; #have to reseed, rand is not rand otherwise
|
||||
while (length($password) < $length) {
|
||||
$password .= substr($characters,int(rand 63),1);
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
sub crydb
|
||||
{
|
||||
my $result = tabdb(@_);
|
||||
unless ($result =~ /^\$1\$/) {
|
||||
$result = crypt($result,'$1$'.genpassword(8));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
sub tabdb
|
||||
{
|
||||
my $table = shift;
|
||||
my $key = shift;
|
||||
my $field = shift;
|
||||
my $tabh = xCAT::Table->new($table);
|
||||
my $ent;
|
||||
if ($key eq "THISNODE" or $key eq '$NODE') {
|
||||
$ent = $tabh->getNodeAttribs($node,[$field]);
|
||||
} else {
|
||||
my %kp;
|
||||
foreach (split /,/,$key) {
|
||||
my $key;
|
||||
my $val;
|
||||
($key,$val) = split /=/,$_;
|
||||
$kp{$key}=$val;
|
||||
}
|
||||
($ent) = $tabh->getAttribs(\%kp,$field);
|
||||
}
|
||||
$tabh->close;
|
||||
unless($ent and $ent->{$field}) {
|
||||
return "#TABLEBAD:$table:field $field not found#";
|
||||
}
|
||||
return $ent->{$field};
|
||||
|
||||
|
||||
#if($key =~ /^\$/) {
|
||||
# $key =~ s/^\$//;
|
||||
# $key = $ENV{$key};
|
||||
#}
|
||||
#if($field =~ /^\$/) {
|
||||
# $field =~ s/^\$//;
|
||||
# $field = $ENV{$field};
|
||||
#}
|
||||
#if($field == '*') {
|
||||
# $field = 1;
|
||||
# $all = 1;
|
||||
#}
|
||||
|
||||
#--$field;
|
||||
|
||||
#if($field < 0) {
|
||||
# return "#TABLE:field not found#"
|
||||
#}
|
||||
|
||||
#open(TAB,$table) || \
|
||||
# return "#TABLE:cannot open $table#";
|
||||
|
||||
#while(<TAB>) {
|
||||
# if(/^$key(\t|,| )/) {
|
||||
# m/^$key(\t|,| )+(.*)/;
|
||||
# if($all == 1) {
|
||||
# return "$2";
|
||||
# }
|
||||
# @fields = split(',',$2);
|
||||
# if(defined $fields[$field]) {
|
||||
# return "$fields[$field]";
|
||||
# }
|
||||
# else {
|
||||
# return "#TABLE:field not found#"
|
||||
# }
|
||||
# }
|
||||
#}
|
||||
|
||||
#close(TAB);
|
||||
#return "#TABLE:key not found#"
|
||||
}
|
||||
|
||||
1;
|
411
perl-xCAT-2.0/xCAT/Utils.pm
Normal file
411
perl-xCAT-2.0/xCAT/Utils.pm
Normal file
@ -0,0 +1,411 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::Utils;
|
||||
use xCAT::Table;
|
||||
use xCAT::Schema;
|
||||
use Data::Dumper;
|
||||
use xCAT::NodeRange;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head1 xCAT::Utils
|
||||
|
||||
=head2 Package Description
|
||||
|
||||
This program module file, is a set of utilities used by xCAT commands.
|
||||
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 quote
|
||||
|
||||
Quote a string, taking into account embedded quotes. This function is most
|
||||
useful when passing string through the shell to another cmd. It handles one
|
||||
level of embedded double quotes, single quotes, and dollar signs.
|
||||
|
||||
Arguments:
|
||||
string to quote
|
||||
Returns:
|
||||
quoted string
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
if (defined($$opthashref{'WhereStr'})) {
|
||||
$where = xCAT::Utils->quote($$opthashref{'WhereStr'});
|
||||
}
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub quote
|
||||
{
|
||||
my ($class, $str) = @_;
|
||||
|
||||
# if the value has imbedded double quotes, use single quotes. If it also has
|
||||
# single quotes, escape the double quotes.
|
||||
if (!($str =~ /\"/)) # no embedded double quotes
|
||||
{
|
||||
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
||||
$str =~ s/\`/\\\`/sg;
|
||||
$str = qq("$str");
|
||||
}
|
||||
elsif (!($str =~ /\'/))
|
||||
{
|
||||
$str = qq('$str');
|
||||
} # no embedded single quotes
|
||||
else # has both embedded double and single quotes
|
||||
{
|
||||
|
||||
# Escape the double quotes. (Escaping single quotes does not seem to work
|
||||
# in the shells.)
|
||||
$str =~ s/\"/\\\"/sg; #" this comment helps formating
|
||||
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
||||
$str =~ s/\`/\\\`/sg;
|
||||
$str = qq("$str");
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 isAIX
|
||||
|
||||
returns 1 if localHost is AIX
|
||||
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
1 - localHost is AIX
|
||||
0 - localHost is some other platform
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
if (xCAT::Utils->isAIX()) { blah; }
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub isAIX
|
||||
{
|
||||
if ($^O =~ /^aix/i) { return 1; }
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 isLinux
|
||||
|
||||
returns 1 if localHost is Linux
|
||||
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
1 - localHost is Linux
|
||||
0 - localHost is some other platform
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
if (xCAT::Utils->isLinux()) { blah; }
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub isLinux
|
||||
{
|
||||
if ($^O =~ /^linux/i) { return 1; }
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 make_node_list_file
|
||||
|
||||
Makes a node list file.
|
||||
|
||||
Arguments:
|
||||
(\@list_of_nodes) - reference to an arrary of nodes.
|
||||
Returns:
|
||||
$file_name and sets the global var: $::NODE_LIST_FILE
|
||||
Globals:
|
||||
the ENV vars: DSH_LIST, RPOWER_LIST, RCONSOLE_LIST
|
||||
Error:
|
||||
None documented
|
||||
Example:
|
||||
xCAT::Utils->make_node_list_file(\@nodelist);
|
||||
|
||||
Comments:
|
||||
IMPORTANT:
|
||||
Make sure to cleanup afterwards with:
|
||||
|
||||
xCAT::Utils->close_delete_file($file_handle, $file_name)
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub make_node_list_file
|
||||
{
|
||||
my ($class, $ref_node_list) = @_;
|
||||
my @node_list = @$ref_node_list;
|
||||
srand(time | $$); #random number generator start
|
||||
|
||||
my $file = "/tmp/csm_$$";
|
||||
while (-e $file)
|
||||
{
|
||||
$file = xCAT::Utils->CreateRandomName($file);
|
||||
}
|
||||
|
||||
open($::NODE_LIST_FILE, ">$file")
|
||||
or MsgUtils->message("E", "Cannot write to file: $file\n");
|
||||
foreach my $node (@node_list)
|
||||
{
|
||||
print $::NODE_LIST_FILE "$node\n";
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 CreateRandomName
|
||||
|
||||
Create a randome file name.
|
||||
Arguments:
|
||||
Prefix of name
|
||||
Returns:
|
||||
Prefix with 8 random letters appended
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
$file = xCAT::Utils->CreateRandomName($namePrefix);
|
||||
Comments:
|
||||
None
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub CreateRandomName
|
||||
{
|
||||
my ($class, $name) = @_;
|
||||
|
||||
my $nI;
|
||||
for ($nI = 0 ; $nI < 8 ; $nI++)
|
||||
{
|
||||
my $char = ('a' .. 'z', 'A' .. 'Z')[int(rand(52)) + 1];
|
||||
$name .= $char;
|
||||
}
|
||||
$name;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
close_delete_file.
|
||||
|
||||
Arguments:
|
||||
file handle,filename
|
||||
Returns:
|
||||
none
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
undef
|
||||
Example:
|
||||
xCAT::Utils->close_delete_file($file_handle, $file_name);
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub close_delete_file
|
||||
{
|
||||
my ($class, $file_handle, $file_name) = @_;
|
||||
close $file_handle;
|
||||
|
||||
unlink($file_name);
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
list_all_nodes
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
an array of all define nodes from the nodelist table
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
undef
|
||||
Example:
|
||||
@nodes=xCAT::Utils->list_all_nodes;
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub list_all_nodes
|
||||
{
|
||||
my @nodes;
|
||||
my @nodelist;
|
||||
my $nodelisttab;
|
||||
if ($nodelisttab = xCAT::Table->new("nodelist"))
|
||||
{
|
||||
my @attribs = ("node");
|
||||
@nodes = $nodelisttab->getAllAttribs(@attribs);
|
||||
foreach my $node (@nodes)
|
||||
{
|
||||
push @nodelist, $node->{node};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
|
||||
}
|
||||
return @nodelist;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
list_all_nodegroups
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
an array of all define node groups from the nodelist table
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
undef
|
||||
Example:
|
||||
@nodegrps=xCAT::Utils->list_all_nodegroups;
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub list_all_node_groups
|
||||
{
|
||||
my @grouplist;
|
||||
my @grouplist2;
|
||||
my @distinctgroups;
|
||||
my $nodelisttab;
|
||||
if ($nodelisttab = xCAT::Table->new("nodelist"))
|
||||
{
|
||||
my @attribs = ("groups");
|
||||
@grouplist = $nodelisttab->getAllAttribs(@attribs);
|
||||
|
||||
# build a distinct list of unique group names
|
||||
foreach my $group (@grouplist)
|
||||
{
|
||||
my $gnames = $group->{groups};
|
||||
my @groupnames = split ",", $gnames;
|
||||
foreach my $groupname (@groupnames)
|
||||
{
|
||||
if (!grep(/$groupname/, @distinctgroups))
|
||||
{ # not already in list
|
||||
push @distinctgroups, $groupname;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
|
||||
}
|
||||
return @distinctgroups;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
list_nodes_in_nodegroup
|
||||
|
||||
Arguments: nodegroup
|
||||
|
||||
Returns:
|
||||
an array of all define nodes in the node group
|
||||
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
undef
|
||||
Example:
|
||||
@nodes=xCAT::Utils->list_nodes_in_nodegroup($group);
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub list_nodes_in_nodegroups
|
||||
{
|
||||
my ($class, $group) = @_;
|
||||
$req->{noderange}->[0] = $group;
|
||||
my @nodes = noderange($req->{noderange}->[0]);
|
||||
return @nodes;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
get_site_attribute
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
The value of the attribute requested from the site table
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
undef
|
||||
Example:
|
||||
@attr=xCAT::Utils->get_site_attribute($attribute);
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub get_site_attribute
|
||||
{
|
||||
my ($class, $attr) = @_;
|
||||
my $values;
|
||||
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
if ($sitetab)
|
||||
{
|
||||
(my $ref) = $sitetab->getAttribs({key => $attr}, value);
|
||||
if ($ref and $ref->{value})
|
||||
{
|
||||
$values = $ref->{value};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xCAT::MsgUtils->message("E", " Could not read the site table\n");
|
||||
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
1;
|
89
perl-xCAT-2.0/xCAT/data/ibmleds.pm
Normal file
89
perl-xCAT-2.0/xCAT/data/ibmleds.pm
Normal file
@ -0,0 +1,89 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#ibmleds,tab, mfg,prod_id,led_id,desc
|
||||
package xCAT::data::ibmleds;
|
||||
|
||||
my %x3755_leds = (
|
||||
0x0065=>'Dimm 6',
|
||||
0x0011=>'VRM',
|
||||
0x00d9=>'Alert',
|
||||
0x0030=>'CPU1',
|
||||
0x0032=>'CPU3',
|
||||
0x00ca=>'Dimm 27',
|
||||
0x0075=>'PCI 6',
|
||||
0x00c1=>'Dimm 18',
|
||||
0x0019=>'NMI',
|
||||
0x0040=>'UNKNOWN',
|
||||
0x0067=>'Dimm 8',
|
||||
0x000f=>'RAID',
|
||||
0x00c4=>'Dimm 21',
|
||||
0x0057=>'Fan 8',
|
||||
0x00d0=>'ServeRAID 8k Batt',
|
||||
0x0069=>'Dimm 10',
|
||||
0x000e=>'BOARD',
|
||||
0x00c3=>'Dimm 20',
|
||||
0x00cf=>'Dimm 32',
|
||||
0x006f=>'Dimm 16',
|
||||
0x0054=>'Fan 5',
|
||||
0x00cd=>'Dimm 30',
|
||||
0x0000=>'FAULT',
|
||||
0x0014=>'FAN',
|
||||
0x00c8=>'Dimm 25',
|
||||
0x006c=>'Dimm 13',
|
||||
0x0061=>'Dimm 2',
|
||||
0x00c2=>'Dimm 19',
|
||||
0x0074=>'PCI 5',
|
||||
0x006a=>'Dimm 11',
|
||||
0x00b9=>'CPU2_BOARD',
|
||||
0x0047=>'UNKNOWN',
|
||||
0x0050=>'Fan 1',
|
||||
0x0072=>'PCI 3',
|
||||
0x00c5=>'Dimm 22',
|
||||
0x00c0=>'Dimm 17',
|
||||
0x0070=>'PCI 1',
|
||||
0x00c9=>'Dimm 26',
|
||||
0x0006=>'CNFG',
|
||||
0x006b=>'Dimm 12',
|
||||
0x00d8=>'BK_Blue',
|
||||
0x0068=>'Dimm 9',
|
||||
0x00bb=>'CPU4_BOARD',
|
||||
0x00c6=>'Dimm 23',
|
||||
0x0031=>'CPU2',
|
||||
0x0010=>'CPU',
|
||||
0x00b8=>'CPU1_BOARD',
|
||||
0x0056=>'Fan 7',
|
||||
0x0063=>'Dimm 4',
|
||||
0x00b0=>'HTX',
|
||||
0x0001=>'LOCATION',
|
||||
0x000b=>'SEER',
|
||||
0x0013=>'DASD',
|
||||
0x00cb=>'Dimm 28',
|
||||
0x0052=>'Fan 3',
|
||||
0x0064=>'Dimm 5',
|
||||
0x001c=>'TEMP',
|
||||
0x00c7=>'Dimm 24',
|
||||
0x0060=>'Dimm 1',
|
||||
0x00d1=>'ServeRAID 8k Err',
|
||||
0x0073=>'PCI 4',
|
||||
0x0015=>'MEM',
|
||||
0x0003=>'INFO',
|
||||
0x006e=>'Dimm 15',
|
||||
0x0071=>'PCI 2',
|
||||
0x00ba=>'CPU3_BOARD',
|
||||
0x00ce=>'Dimm 31',
|
||||
0x001b=>'OVERSPEC',
|
||||
0x0041=>'UNKNOWN',
|
||||
0x006d=>'Dimm 14',
|
||||
0x0051=>'Fan 2',
|
||||
0x001e=>'SP',
|
||||
0x0066=>'Dimm 7',
|
||||
0x0053=>'Fan 4',
|
||||
0x0055=>'Fan 6',
|
||||
0x0033=>'CPU4',
|
||||
0x00cc=>'Dimm 29',
|
||||
0x0020=>'PCI',
|
||||
0x0062=>'Dimm 3',
|
||||
);
|
||||
|
||||
%leds = (
|
||||
"2,14" => \%x3755_leds,
|
||||
);
|
66
perl-xCAT-2.0/xCAT/data/ipmigenericevents.pm
Normal file
66
perl-xCAT-2.0/xCAT/data/ipmigenericevents.pm
Normal file
@ -0,0 +1,66 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#ipmigenericevent.tab",
|
||||
#DO NOT EDIT",
|
||||
#",
|
||||
#<sensor type code>",<sensor offset>,<sensor type>,<event>",
|
||||
package xCAT::data::ipmigenericevents;
|
||||
|
||||
%ipmigenericevents = (
|
||||
"01h,00h"=>"Threshold,Lower Non-critical - going low",
|
||||
"01h,01h"=>"Threshold,Lower Non-critical - going high",
|
||||
"01h,02h"=>"Threshold,Lower Critical - going low",
|
||||
"01h,03h"=>"Threshold,Lower Critical - going high",
|
||||
"01h,04h"=>"Threshold,Lower Non-recoverable - going low",
|
||||
"01h,05h"=>"Threshold,Lower Non-recoverable - going high",
|
||||
"01h,06h"=>"Threshold,Upper Non-critical - going low",
|
||||
"01h,07h"=>"Threshold,Upper Non-critical - going high",
|
||||
"01h,08h"=>"Threshold,Upper Critical - going low",
|
||||
"01h,09h"=>"Threshold,Upper Critical - going high",
|
||||
"01h,0Ah"=>"Threshold,Upper Non-recoverable - going low",
|
||||
"01h,0Bh"=>"Threshold,Upper Non-recoverable - going high",
|
||||
"02h,00h"=>"Discrete,Transition to Idle",
|
||||
"02h,01h"=>"Discrete,Transition to Active",
|
||||
"02h,02h"=>"Discrete,Transition to Busy",
|
||||
"03h,00h"=>"'digital' Discrete,State Deasserted",
|
||||
"03h,01h"=>"'digital' Discrete,State Asserted",
|
||||
"04h,00h"=>"'digital' Discrete,Predictive Failure Deasserted",
|
||||
"04h,01h"=>"'digital' Discrete,Predictive Failure Asserted",
|
||||
"05h,00h"=>"'digital' Discrete,Limit Not Exceeded",
|
||||
"05h,01h"=>"'digital' Discrete,Limit Exceeded",
|
||||
"06h,00h"=>"'digital' Discrete,Performance Met",
|
||||
"06h,01h"=>"'digital' Discrete,Performance Lags",
|
||||
"07h,00h"=>"Discrete,transition to OK",
|
||||
"07h,01h"=>"Discrete,transition to Non-Critical from OK",
|
||||
"07h,02h"=>"Discrete,transition to Critical from Less Severe",
|
||||
"07h,03h"=>"Discrete,transition to Non-recoverable from Less Severe",
|
||||
"07h,04h"=>"Discrete,transition to Non-Critical from More Severe",
|
||||
"07h,05h"=>"Discrete,transition to Critical from Non-recoverable",
|
||||
"07h,06h"=>"Discrete,transition to Non-recoverable",
|
||||
"07h,07h"=>"Discrete,Monitor",
|
||||
"07h,08h"=>"Discrete,Informational",
|
||||
"08h,00h"=>"'digital' Discrete,Device Removed / Device Absent",
|
||||
"08h,01h"=>"'digital' Discrete,Device Inserted / Device Present",
|
||||
"09h,00h"=>"'digital' Discrete,Device Disabled",
|
||||
"09h,01h"=>"'digital' Discrete,Device Enabled",
|
||||
"0Ah,00h"=>"Discrete,transition to Running",
|
||||
"0Ah,01h"=>"Discrete,transition to In Test",
|
||||
"0Ah,02h"=>"Discrete,transition to Power Off",
|
||||
"0Ah,03h"=>"Discrete,transition to On Line",
|
||||
"0Ah,04h"=>"Discrete,transition to Off Line",
|
||||
"0Ah,05h"=>"Discrete,transition to Off Duty",
|
||||
"0Ah,06h"=>"Discrete,transition to Degraded",
|
||||
"0Ah,07h"=>"Discrete,transition to Power Save",
|
||||
"0Ah,08h"=>"Discrete,Install Error",
|
||||
"0Bh,00h"=>"Discrete,Redundancy Regained",
|
||||
"0Bh,01h"=>"Discrete,Redundancy Lost",
|
||||
"0Bh,02h"=>"Discrete,Redundancy Degraded",
|
||||
"0Bh,03h"=>"Discrete,Non-redundant:Sufficient resources",
|
||||
"0Bh,04h"=>"Discrete,Non-redundant:Sufficient from insufficient resources",
|
||||
"0Bh,05h"=>"Discrete,Non-redundant:Insufficient resources",
|
||||
"0Bh,06h"=>"Discrete,Redundancy Degraded from Fully Reduntant",
|
||||
"0Bh,06h"=>"Discrete,Redundancy Degraded from Non-Reduntant",
|
||||
"0Ch,00h"=>"Discrete,D0 Power State",
|
||||
"0Ch,01h"=>"Discrete,D1 Power State",
|
||||
"0Ch,02h"=>"Discrete,D2 Power State",
|
||||
"0Ch,03h"=>"Discrete,D3 Power State",
|
||||
);
|
169
perl-xCAT-2.0/xCAT/data/ipmisensorevents.pm
Normal file
169
perl-xCAT-2.0/xCAT/data/ipmisensorevents.pm
Normal file
@ -0,0 +1,169 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#ipmisensorevent.tab",
|
||||
#DO NOT EDIT",
|
||||
#",
|
||||
#<sensor type code>",<sensor offset>,<sensor type>,<event>",
|
||||
package xCAT::data::ipmisensorevents;
|
||||
%ipmisensorevents = (
|
||||
"00h,-"=>"reserved,Reserved",
|
||||
"01h,-"=>"Temperature,Temperature",
|
||||
"02h,-"=>"Voltage,Voltage",
|
||||
"03h,-"=>"Current,Current",
|
||||
"04h,-"=>"Fan,Fan",
|
||||
"05h,00h"=>"Physical Security,General Chassis Intrusion",
|
||||
"05h,01h"=>"Physical Security,Drive Bay Intrusion",
|
||||
"05h,02h"=>"Physical Security,I/O Card area Intrusion",
|
||||
"05h,03h"=>"Physical Security,Processor area Intrusion",
|
||||
"05h,04h"=>"Physical Security,LAN Leash Lost (system has been unplugged from LAN)",
|
||||
"05h,05h"=>"Physical Security,Unauthorized Dock/Undock",
|
||||
"05h,06h"=>"Physical Security,FAN area intrusion",
|
||||
"06h,00h"=>"Platform Security Violation Attempt,Secure Mode Violation Attempt",
|
||||
"06h,01h"=>"Platform Security Violation Attempt,Pre-boot Password Violation - user password",
|
||||
"06h,02h"=>"Platform Security Violation Attempt,Pre-boot Password Violation Attempt - setup password",
|
||||
"06h,03h"=>"Platform Security Violation Attempt,Pre-boot Password Violation - network boot password",
|
||||
"06h,04h"=>"Platform Security Violation Attempt,Other pre-boot Password Violation",
|
||||
"06h,05h"=>"Platform Security Violation Attempt,Out-of-band Access Password Violation",
|
||||
"07h,00h"=>"Processor,IERR",
|
||||
"07h,01h"=>"Processor,Thermal Trip",
|
||||
"07h,02h"=>"Processor,FRB1/BIST Failure",
|
||||
"07h,03h"=>"Processor,FRB2/Hang in POST Failure",
|
||||
"07h,04h"=>"Processor,FRB3/Processor Startup/Initialization failure (CPU didn't start)",
|
||||
"07h,05h"=>"Processor,Configuration Error (for DMI)",
|
||||
"07h,06h"=>"Processor,SM BIOS Uncorrectable CPU-complex Error",
|
||||
"07h,07h"=>"Processor,Processor Presence Detected",
|
||||
"07h,08h"=>"Processor,Processor Disabled",
|
||||
"07h,09h"=>"Processor,Terminator Presence Detected",
|
||||
"08h,00h"=>"Power Supply,Presence Detected",
|
||||
"08h,01h"=>"Power Supply,Power Supply Failure Detected",
|
||||
"08h,02h"=>"Power Supply,Predictive Failure Asserted",
|
||||
"08h,03h"=>"Power Supply,Power Supply AC lost",
|
||||
"08h,04h"=>"Power Supply,AC lost or out-of-range",
|
||||
"08h,05h"=>"Power Supply,AC out-of-range, but present",
|
||||
"09h,00h"=>"Power Unit,Power Off / Power Down",
|
||||
"09h,01h"=>"Power Unit,Power Cycle",
|
||||
"09h,02h"=>"Power Unit,240VA Power Down",
|
||||
"09h,03h"=>"Power Unit,Interlock Power Down",
|
||||
"09h,04h"=>"Power Unit,A/C Lost",
|
||||
"09h,05h"=>"Power Unit,Soft Power Control Failure",
|
||||
"09h,06h"=>"Power Unit,Power Unit Failure Detected",
|
||||
"09h,07h"=>"Power Unit,Predictive Failure",
|
||||
"0Ah,-"=>"Cooling Device,-",
|
||||
"0Bh,-"=>"Other Units-based Sensor,-",
|
||||
"0Ch,00h"=>"Memory,Correctable ECC",
|
||||
"0Ch,01h"=>"Memory,Uncorrectable ECC",
|
||||
"0Ch,02h"=>"Memory,Parity",
|
||||
"0Ch,03h"=>"Memory,Memory Scrub Failed (stuck bit)",
|
||||
"0Ch,04h"=>"Memory,Memory Device Disabled",
|
||||
"0Ch,05h"=>"Memory,Correctable ECC (loggin limit reached)",
|
||||
"0Dh,-"=>"Drive Slot,-",
|
||||
"0Eh,-"=>"POST Memory Resize,-",
|
||||
"0Fh,00h"=>"System Firmware Progress,POST Error",
|
||||
"0Fh,01h"=>"System Firmware Progress,System Firmware Hung",
|
||||
"0Fh,02h"=>"System Firmware Progress,System Firmware Progress",
|
||||
"10h,00h"=>"Event Logging Disabled,Correctable Memory Error Logging Disabled",
|
||||
"10h,01h"=>"Event Logging Disabled,Event 'Type' Logging Disabled",
|
||||
"10h,02h"=>"Event Logging Disabled,Log Area Reset/Cleared",
|
||||
"10h,03h"=>"Event Logging Disabled,All Event Logging Disabled",
|
||||
"11h,00h"=>"Watchdog 1,BIOS Watchdog Reset",
|
||||
"11h,01h"=>"Watchdog 1,OS Watchdog Reset",
|
||||
"11h,02h"=>"Watchdog 1,OS Watchdog Shut Down",
|
||||
"11h,03h"=>"Watchdog 1,OS Watchdog Power Down",
|
||||
"11h,04h"=>"Watchdog 1,OS Watchdog Power Cycle",
|
||||
"11h,05h"=>"Watchdog 1,OS Watchdog NMI",
|
||||
"11h,06h"=>"Watchdog 1,OS Watchdog Expired, status only",
|
||||
"11h,07h"=>"Watchdog 1,OS Watchdog Pre-timeout Interrupt, non-NMI",
|
||||
"12h,00h"=>"System Event,System Reconfigured",
|
||||
"12h,01h"=>"System Event,Boot",
|
||||
"12h,02h"=>"System Event,Undetermined system hardware failure",
|
||||
"12h,03h"=>"System Event,Entry added to Auxiliary Log",
|
||||
"12h,04h"=>"System Event,PEF Action",
|
||||
"13h,00h"=>"Critical Interrupt,Front Panel NMI ",
|
||||
"13h,01h"=>"Critical Interrupt,Bus Timeout",
|
||||
"13h,02h"=>"Critical Interrupt,I/O Channel Check NMI",
|
||||
"13h,03h"=>"Critical Interrupt,Software NMI",
|
||||
"13h,04h"=>"Critical Interrupt,PCI PERR",
|
||||
"13h,05h"=>"Critical Interrupt,PCI SERR",
|
||||
"13h,06h"=>"Critical Interrupt,EISA Fail Safe Timeout",
|
||||
"13h,07h"=>"Critical Interrupt,Bus Correctable Error",
|
||||
"13h,08h"=>"Critical Interrupt,Bus Uncorrectable Error",
|
||||
"13h,09h"=>"Critical Interrupt,Fatal NMI (port 61h, bit 7)",
|
||||
"14h,00h"=>"Button,Power Button pressed",
|
||||
"14h,01h"=>"Button,Sleep Button pressed",
|
||||
"14h,02h"=>"Button,Reset Button pressed",
|
||||
"15h,-"=>"Module / Board,-",
|
||||
"16h,-"=>"Microcontroller / Coprocessor,-",
|
||||
"17h,-"=>"Add-in Card,-",
|
||||
"18h,-"=>"Chassis,-",
|
||||
"19h,-"=>"Chip Set,-",
|
||||
"1Ah,-"=>"Other FRU,-",
|
||||
"1Bh,-"=>"Cable / Interconnect,-",
|
||||
"1Ch,-"=>"Terminator,-",
|
||||
"1Dh,00h"=>"System Boot Initiated,Initiated by power up",
|
||||
"1Dh,01h"=>"System Boot Initiated,Initiated by hard reset",
|
||||
"1Dh,02h"=>"System Boot Initiated,Initiated by warm reset",
|
||||
"1Dh,03h"=>"System Boot Initiated,User requested PXE boot",
|
||||
"1Dh,04h"=>"System Boot Initiated,Automatic boot to diagnostic",
|
||||
"1Eh,00h"=>"Boot Error,No bootable media",
|
||||
"1Eh,01h"=>"Boot Error,Non-bootable diskette left in drive",
|
||||
"1Eh,02h"=>"Boot Error,PXE Server not found",
|
||||
"1Eh,03h"=>"Boot Error,Invalid boot sector",
|
||||
"1Eh,04h"=>"Boot Error,Timeout waiting for user selection of boot source",
|
||||
"1Fh,00h"=>"OS Boot,A: boot completed",
|
||||
"1Fh,01h"=>"OS Boot,C: boot completed",
|
||||
"1Fh,02h"=>"OS Boot,PXE boot completed",
|
||||
"1Fh,03h"=>"OS Boot,Diagnostic boot completed",
|
||||
"1Fh,04h"=>"OS Boot,CD-ROM boot completed",
|
||||
"1Fh,05h"=>"OS Boot,ROM boot completed",
|
||||
"1Fh,06h"=>"OS Boot,Boot completed - boot device not specified",
|
||||
"20h,00h"=>"OS Critical Stop,Stop during OS load / initialization",
|
||||
"20h,01h"=>"OS Critical Stop,Run-time Stop",
|
||||
"21h,00h"=>"Slot / Connector,Fault Status asserted",
|
||||
"21h,01h"=>"Slot / Connector,Identify Status asserted",
|
||||
"21h,02h"=>"Slot / Connector,Slot / Connector Device installed/attached",
|
||||
"21h,03h"=>"Slot / Connector,Slot / Connector Ready for Device Installation",
|
||||
"21h,04h"=>"Slot / Connector,Slot/Connector Ready for Device Removal",
|
||||
"21h,05h"=>"Slot / Connector,Slot Power is Off",
|
||||
"21h,06h"=>"Slot / Connector,Slot / Connector Device Removal Request",
|
||||
"21h,07h"=>"Slot / Connector,Interlock asserted",
|
||||
"21h,08h"=>"Slot / Connector,Slot is Disabled",
|
||||
"22h,00h"=>"System ACPI Power State,S0 / G0 working",
|
||||
"22h,01h"=>"System ACPI Power State,S1 sleeping with system h/w & processor context maintained",
|
||||
"22h,02h"=>"System ACPI Power State,S2 sleeping, processor context lost",
|
||||
"22h,03h"=>"System ACPI Power State,S3 sleeping, processor & h/w context lost, memory retained.",
|
||||
"22h,04h"=>"System ACPI Power State,S4 non-volatile sleep / suspend-to disk",
|
||||
"22h,05h"=>"System ACPI Power State,S5 / G2 soft-off",
|
||||
"22h,06h"=>"System ACPI Power State,S4 / S5 soft-off, particular S4 / S5 state cannot be determined",
|
||||
"22h,07h"=>"System ACPI Power State,G3 / Mechanical Off",
|
||||
"22h,08h"=>"System ACPI Power State,Sleeping in an S1, S2, or S3 states",
|
||||
"22h,09h"=>"System ACPI Power State,G1 sleeping",
|
||||
"22h,0Ah"=>"System ACPI Power State,S5 entered by override",
|
||||
"22h,0Bh"=>"System ACPI Power State,Legacy ON state",
|
||||
"22h,0Ch"=>"System ACPI Power State,Legacy OFF state",
|
||||
"22h,0Eh"=>"System ACPI Power State,Unknown",
|
||||
"23h,00h"=>"Watchdog 2,Timer expired, status only",
|
||||
"23h,01h"=>"Watchdog 2,Hard Reset",
|
||||
"23h,02h"=>"Watchdog 2,Power Down",
|
||||
"23h,03h"=>"Watchdog 2,Power Cycle",
|
||||
"23h,04h"=>"Watchdog 2,reserved",
|
||||
"23h,05h"=>"Watchdog 2,reserved",
|
||||
"23h,06h"=>"Watchdog 2,reserved",
|
||||
"23h,07h"=>"Watchdog 2,reserved",
|
||||
"23h,08h"=>"Watchdog 2,Timer interrupt",
|
||||
"24h,00h"=>"Platform Alert,Platform generated page",
|
||||
"24h,01h"=>"Platform Alert,Platform generated LAN alert",
|
||||
"24h,02h"=>"Platform Alert,Platform Event Trap generated, formatted per IPMI PET specification",
|
||||
"24h,03h"=>"Platform Alert,Platform generated SNMP trap, OEM format",
|
||||
"25h,00h"=>"Entity Presence,Entity Present",
|
||||
"25h,01h"=>"Entity Presence,Entity Absent",
|
||||
"25h,02h"=>"Entity Presence,Entity Disabled",
|
||||
"26h,-"=>"Monitor ASIC / IC,-",
|
||||
"27h,00h"=>"LAN,LAN Heartbeat Lost",
|
||||
"27h,01h"=>"LAN,LAN Heartbeat",
|
||||
"28h,00h"=>"Management Subsystem Health,sensor access degraded or unavailable",
|
||||
"28h,01h"=>"Management Subsystem Health,controller access degraded or unavailable",
|
||||
"28h,02h"=>"Management Subsystem Health,management controller off-line",
|
||||
"28h,03h"=>"Management Subsystem Health,management controller unavailable",
|
||||
"29h,00h"=>"Battery,battery low (predictive failure)",
|
||||
"29h,01h"=>"Battery,battery failed",
|
||||
"29h,02h"=>"Battery,battery presense detected",
|
||||
);
|
4
svn-commit.2.tmp
Normal file
4
svn-commit.2.tmp
Normal file
@ -0,0 +1,4 @@
|
||||
xCAT 2.0 core import
|
||||
--This line, and those below, will be ignored--
|
||||
|
||||
A .
|
4
svn-commit.tmp
Normal file
4
svn-commit.tmp
Normal file
@ -0,0 +1,4 @@
|
||||
Import xCAT 2.0 tree as of 10/26
|
||||
--This line, and those below, will be ignored--
|
||||
|
||||
A .
|
326
xCAT-client-2.0/LICENSE.html
Normal file
326
xCAT-client-2.0/LICENSE.html
Normal file
@ -0,0 +1,326 @@
|
||||
<html xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||||
<meta name=ProgId content=Word.Document>
|
||||
<meta name=Generator content="Microsoft Word 9">
|
||||
<meta name=Originator content="Microsoft Word 9">
|
||||
<title>Eclipse Public License - Version 1.0</title>
|
||||
<!--[if gte mso 9]><xml>
|
||||
<o:DocumentProperties>
|
||||
<o:Revision>2</o:Revision>
|
||||
<o:TotalTime>3</o:TotalTime>
|
||||
<o:Created>2004-03-05T23:03:00Z</o:Created>
|
||||
<o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
|
||||
<o:Pages>4</o:Pages>
|
||||
<o:Words>1626</o:Words>
|
||||
<o:Characters>9270</o:Characters>
|
||||
<o:Lines>77</o:Lines>
|
||||
<o:Paragraphs>18</o:Paragraphs>
|
||||
<o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
|
||||
<o:Version>9.4402</o:Version>
|
||||
</o:DocumentProperties>
|
||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||
<w:WordDocument>
|
||||
<w:TrackRevisions/>
|
||||
</w:WordDocument>
|
||||
</xml><![endif]-->
|
||||
<style>
|
||||
<!--
|
||||
/* Font Definitions */
|
||||
@font-face
|
||||
{font-family:Tahoma;
|
||||
panose-1:2 11 6 4 3 5 4 4 2 4;
|
||||
mso-font-charset:0;
|
||||
mso-generic-font-family:swiss;
|
||||
mso-font-pitch:variable;
|
||||
mso-font-signature:553679495 -2147483648 8 0 66047 0;}
|
||||
/* Style Definitions */
|
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||||
{mso-style-parent:"";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p
|
||||
{margin-right:0in;
|
||||
mso-margin-top-alt:auto;
|
||||
mso-margin-bottom-alt:auto;
|
||||
margin-left:0in;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p.BalloonText, li.BalloonText, div.BalloonText
|
||||
{mso-style-name:"Balloon Text";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:8.0pt;
|
||||
font-family:Tahoma;
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
@page Section1
|
||||
{size:8.5in 11.0in;
|
||||
margin:1.0in 1.25in 1.0in 1.25in;
|
||||
mso-header-margin:.5in;
|
||||
mso-footer-margin:.5in;
|
||||
mso-paper-source:0;}
|
||||
div.Section1
|
||||
{page:Section1;}
|
||||
-->
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body lang=EN-US style='tab-interval:.5in'>
|
||||
|
||||
<div class=Section1>
|
||||
|
||||
<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
|
||||
</p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
|
||||
THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
|
||||
REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
|
||||
OF THIS AGREEMENT.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
in the case of the initial Contributor, the initial code and documentation
|
||||
distributed under this Agreement, and<br clear=left>
|
||||
b) in the case of each subsequent Contributor:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
changes to the Program, and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
additions to the Program;</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
|
||||
such changes and/or additions to the Program originate from and are distributed
|
||||
by that particular Contributor. A Contribution 'originates' from a Contributor
|
||||
if it was added to the Program by such Contributor itself or anyone acting on
|
||||
such Contributor's behalf. Contributions do not include additions to the
|
||||
Program which: (i) are separate modules of software distributed in conjunction
|
||||
with the Program under their own license agreement, and (ii) are not derivative
|
||||
works of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contributor" means any person or
|
||||
entity that distributes the Program.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
|
||||
claims licensable by a Contributor which are necessarily infringed by the use
|
||||
or sale of its Contribution alone or when combined with the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Program" means the Contributions
|
||||
distributed in accordance with this Agreement.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Recipient" means anyone who
|
||||
receives the Program under this Agreement, including all Contributors.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants Recipient
|
||||
a non-exclusive, worldwide, royalty-free copyright license to<span
|
||||
style='color:red'> </span>reproduce, prepare derivative works of, publicly
|
||||
display, publicly perform, distribute and sublicense the Contribution of such
|
||||
Contributor, if any, and such derivative works, in source code and object code
|
||||
form.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
|
||||
patent license under Licensed Patents to make, use, sell, offer to sell, import
|
||||
and otherwise transfer the Contribution of such Contributor, if any, in source
|
||||
code and object code form. This patent license shall apply to the combination
|
||||
of the Contribution and the Program if, at the time the Contribution is added
|
||||
by the Contributor, such addition of the Contribution causes such combination
|
||||
to be covered by the Licensed Patents. The patent license shall not apply to
|
||||
any other combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder. </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
|
||||
Recipient understands that although each Contributor grants the licenses to its
|
||||
Contributions set forth herein, no assurances are provided by any Contributor
|
||||
that the Program does not infringe the patent or other intellectual property
|
||||
rights of any other entity. Each Contributor disclaims any liability to Recipient
|
||||
for claims brought by any other entity based on infringement of intellectual
|
||||
property rights or otherwise. As a condition to exercising the rights and
|
||||
licenses granted hereunder, each Recipient hereby assumes sole responsibility
|
||||
to secure any other intellectual property rights needed, if any. For example,
|
||||
if a third party patent license is required to allow Recipient to distribute
|
||||
the Program, it is Recipient's responsibility to acquire that license before
|
||||
distributing the Program.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
|
||||
Each Contributor represents that to its knowledge it has sufficient copyright
|
||||
rights in its Contribution, if any, to grant the copyright license set forth in
|
||||
this Agreement. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
|
||||
Program in object code form under its own license agreement, provided that:</span>
|
||||
</p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it complies with the terms and conditions of this Agreement; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
its license agreement:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
effectively disclaims on behalf of all Contributors all warranties and
|
||||
conditions, express and implied, including warranties or conditions of title
|
||||
and non-infringement, and implied warranties or conditions of merchantability
|
||||
and fitness for a particular purpose; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
effectively excludes on behalf of all Contributors all liability for damages,
|
||||
including direct, indirect, special, incidental and consequential damages, such
|
||||
as lost profits; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
|
||||
states that any provisions which differ from this Agreement are offered by that
|
||||
Contributor alone and not by any other party; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
|
||||
states that source code for the Program is available from such Contributor, and
|
||||
informs licensees how to obtain it in a reasonable manner on or through a
|
||||
medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>When the Program is made available in source
|
||||
code form:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it must be made available under this Agreement; and </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
|
||||
copy of this Agreement must be included with each copy of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
|
||||
copyright notices contained within the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
|
||||
originator of its Contribution, if any, in a manner that reasonably allows
|
||||
subsequent Recipients to identify the originator of the Contribution. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Commercial distributors of software may
|
||||
accept certain responsibilities with respect to end users, business partners
|
||||
and the like. While this license is intended to facilitate the commercial use
|
||||
of the Program, the Contributor who includes the Program in a commercial
|
||||
product offering should do so in a manner which does not create potential
|
||||
liability for other Contributors. Therefore, if a Contributor includes the
|
||||
Program in a commercial product offering, such Contributor ("Commercial
|
||||
Contributor") hereby agrees to defend and indemnify every other
|
||||
Contributor ("Indemnified Contributor") against any losses, damages and
|
||||
costs (collectively "Losses") arising from claims, lawsuits and other
|
||||
legal actions brought by a third party against the Indemnified Contributor to
|
||||
the extent caused by the acts or omissions of such Commercial Contributor in
|
||||
connection with its distribution of the Program in a commercial product
|
||||
offering. The obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In order
|
||||
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
|
||||
Contributor in writing of such claim, and b) allow the Commercial Contributor
|
||||
to control, and cooperate with the Commercial Contributor in, the defense and
|
||||
any related settlement negotiations. The Indemnified Contributor may participate
|
||||
in any such claim at its own expense.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>For example, a Contributor might include the
|
||||
Program in a commercial product offering, Product X. That Contributor is then a
|
||||
Commercial Contributor. If that Commercial Contributor then makes performance
|
||||
claims, or offers warranties related to Product X, those performance claims and
|
||||
warranties are such Commercial Contributor's responsibility alone. Under this
|
||||
section, the Commercial Contributor would have to defend claims against the
|
||||
other Contributors related to those performance claims and warranties, and if a
|
||||
court requires any other Contributor to pay any damages as a result, the
|
||||
Commercial Contributor must pay those damages.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
|
||||
WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and distributing the
|
||||
Program and assumes all risks associated with its exercise of rights under this
|
||||
Agreement , including but not limited to the risks and costs of program errors,
|
||||
compliance with applicable laws, damage to or loss of data, programs or
|
||||
equipment, and unavailability or interruption of operations. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
|
||||
THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
|
||||
or unenforceable under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this Agreement, and without
|
||||
further action by the parties hereto, such provision shall be reformed to the
|
||||
minimum extent necessary to make such provision valid and enforceable.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
|
||||
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
||||
alleging that the Program itself (excluding combinations of the Program with
|
||||
other software or hardware) infringes such Recipient's patent(s), then such
|
||||
Recipient's rights granted under Section 2(b) shall terminate as of the date
|
||||
such litigation is filed. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
|
||||
shall terminate if it fails to comply with any of the material terms or
|
||||
conditions of this Agreement and does not cure such failure in a reasonable
|
||||
period of time after becoming aware of such noncompliance. If all Recipient's
|
||||
rights under this Agreement terminate, Recipient agrees to cease use and
|
||||
distribution of the Program as soon as reasonably practicable. However,
|
||||
Recipient's obligations under this Agreement and any licenses granted by
|
||||
Recipient relating to the Program shall continue and survive. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
|
||||
copies of this Agreement, but in order to avoid inconsistency the Agreement is
|
||||
copyrighted and may only be modified in the following manner. The Agreement
|
||||
Steward reserves the right to publish new versions (including revisions) of
|
||||
this Agreement from time to time. No one other than the Agreement Steward has
|
||||
the right to modify this Agreement. The Eclipse Foundation is the initial
|
||||
Agreement Steward. The Eclipse Foundation may assign the responsibility to
|
||||
serve as the Agreement Steward to a suitable separate entity. Each new version
|
||||
of the Agreement will be given a distinguishing version number. The Program
|
||||
(including Contributions) may always be distributed subject to the version of
|
||||
the Agreement under which it was received. In addition, after a new version of
|
||||
the Agreement is published, Contributor may elect to distribute the Program
|
||||
(including its Contributions) under the new version. Except as expressly stated
|
||||
in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
|
||||
the intellectual property of any Contributor under this Agreement, whether
|
||||
expressly, by implication, estoppel or otherwise. All rights in the Program not
|
||||
expressly granted under this Agreement are reserved.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
|
||||
State of New York and the intellectual property laws of the United States of
|
||||
America. No party to this Agreement will bring a legal action under this
|
||||
Agreement more than one year after the cause of action arose. Each party waives
|
||||
its rights to a jury trial in any resulting litigation.</span> </p>
|
||||
|
||||
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
8
xCAT-client-2.0/README
Normal file
8
xCAT-client-2.0/README
Normal file
@ -0,0 +1,8 @@
|
||||
This is the README for xCAT - Extreme Cluster Administration Toolkit,
|
||||
Version 2.0 alpha release. xCAT is a toolkit for the deployment and administration of clusters.
|
||||
xCAT 2.0 is offered OSS under a EPL license.
|
||||
|
||||
See http://www.eclipse.org/legal/epl-v10.html for license details.
|
||||
|
||||
The xCAT 2.0 code and documentation can be downloaded from http://xcat.org.
|
||||
For support, go to http://xcat.org for instructions on joining the mailing list.
|
67
xCAT-client-2.0/usr/bin/getnodecfg
Executable file
67
xCAT-client-2.0/usr/bin/getnodecfg
Executable file
@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use xCAT::Table;
|
||||
use xCAT::NodeRange;
|
||||
use IO::Socket::SSL;
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use strict;
|
||||
my $xcathost='localhost:3001';
|
||||
if ($ENV{XCATHOST}) {
|
||||
$xcathost=$ENV{XCATHOST};
|
||||
}
|
||||
|
||||
my $server = IO::Socket::SSL->new(
|
||||
PeerAddr=>$xcathost,
|
||||
SSL_key_file=>$ENV{HOME}."/.xcat/client-key.pem",
|
||||
SSL_cert_file=>$ENV{HOME}."/.xcat/client-cert.pem",
|
||||
SSL_ca_file => $ENV{HOME}."/.xcat/ca.pem",
|
||||
SSL_use_cert => 1,
|
||||
#SSL_verify_mode => 1,
|
||||
);
|
||||
die "Connection failure: $!\n" unless ($server);
|
||||
my $target=shift(@ARGV);
|
||||
my %request=(); #Start building the hash to XML-ify
|
||||
$request{command}='getnodeattributes';
|
||||
$request{noderange}=$target;
|
||||
|
||||
for (@ARGV) {
|
||||
my $temp;
|
||||
my $table;
|
||||
my $column;
|
||||
my $value;
|
||||
($table,$column) = split('\.',$_,2);
|
||||
$request{table}=$table; #build/reuse request specific elements
|
||||
$request{attribute}=$column;
|
||||
print $server XMLout(\%request,RootName => 'xcatrequest',NoAttr => 1);
|
||||
alarm(30);
|
||||
my $response;
|
||||
while (<$server>) {
|
||||
alarm(0);
|
||||
$response .= $_;
|
||||
if ($response =~ m/<\/xcatresponse>/) {
|
||||
my $reply=XMLin($response);
|
||||
$response="";
|
||||
if ($reply->{error}) {
|
||||
printf "ERROR: ".$reply->{error}."\n";
|
||||
}
|
||||
if ($reply->{warning}) {
|
||||
printf "Warning: ".$reply->{warning}."\n";
|
||||
}
|
||||
if ($reply->{attributes}{$column}) {
|
||||
printf "$table.$column:".$reply->{attributes}{$column}."\n";
|
||||
}
|
||||
if ($reply->{serverdone}) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#my $tab = xCAT::Table->new($table,-create => 1);
|
||||
#my $rec = $tab->getAttribs($key,$val,$column);
|
||||
|
||||
# if ($rec->{$column}) { printf $rec->{$column}."\n"; }
|
||||
#}
|
73
xCAT-client-2.0/usr/bin/pping
Executable file
73
xCAT-client-2.0/usr/bin/pping
Executable file
@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#Note, this pping still frontends fping. I think it would be possible to write a perl equivalent, but
|
||||
#I've not had the time. Net::Ping shows perl code I could see being adapted for a somewhat
|
||||
#asynchronous ICMP ping (the tcp syn is interesting, but far too limited, and that is currently the only async
|
||||
#method Net::Ping provides.
|
||||
use IO::Socket::SSL;
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use IO::Handle;
|
||||
use IO::Select;
|
||||
use xCAT::Utils;
|
||||
use Getopt::Long;
|
||||
my $interface;
|
||||
GetOptions("interface=s" => \$interface);
|
||||
my $xcathost='localhost:3001';
|
||||
if ($ENV{XCATHOST}) {
|
||||
$xcathost=$ENV{XCATHOST};
|
||||
}
|
||||
|
||||
unless (@ARGV) {
|
||||
print "Usage: pping [-i suffix] <noderange>\n";
|
||||
exit(1);
|
||||
}
|
||||
my $noderange = $ARGV[0];
|
||||
my $client = IO::Socket::SSL->new(
|
||||
PeerAddr=>$xcathost,
|
||||
SSL_key_file=>$ENV{HOME}."/.xcat/client-key.pem",
|
||||
SSL_cert_file=>$ENV{HOME}."/.xcat/client-cert.pem",
|
||||
SSL_ca_file => $ENV{HOME}."/.xcat/ca.pem",
|
||||
SSL_use_cert => 1,
|
||||
#SSL_verify_mode => 1,
|
||||
);
|
||||
die "Connection failure: $!\n" unless ($client);
|
||||
my %cmdref = (command => 'noderange', noderange => $noderange);
|
||||
$SIG{ALRM} = sub { die "No response getting noderange" };
|
||||
alarm(15);
|
||||
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
|
||||
alarm(15);
|
||||
my $response="";
|
||||
my @nodes=();
|
||||
while (<$client>) {
|
||||
alarm(0);
|
||||
$response .= $_;
|
||||
if ($response =~ m/<\/xcatresponse>/) {
|
||||
$rsp=XMLin($response, ForceArray => ['node']);
|
||||
$response='';
|
||||
if ($rsp->{warning}) {
|
||||
printf "Warning: ".$rsp->{warning}."\n";
|
||||
}
|
||||
if ($rsp->{error}) {
|
||||
die ("ERROR: ".$rsp->{error}."\n");
|
||||
} elsif ($rsp->{node}) {
|
||||
@nodes=@{$rsp->{node}};
|
||||
}
|
||||
if ($rsp->{serverdone}) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close($client);
|
||||
my $children = 0;
|
||||
my $inputs = new IO::Select;
|
||||
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { $children--; } };
|
||||
if ($interface) {
|
||||
foreach (@nodes) {
|
||||
s/$/-$interface/;
|
||||
}
|
||||
}
|
||||
|
||||
exec "fping ".join(' ',@nodes). " 2> /dev/null";
|
||||
|
||||
|
108
xCAT-client-2.0/usr/bin/psh
Executable file
108
xCAT-client-2.0/usr/bin/psh
Executable file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use IO::Socket::SSL;
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use IO::Handle;
|
||||
use IO::Select;
|
||||
use xCAT::Utils;
|
||||
use Getopt::Long;
|
||||
use POSIX qw(:signal_h :errno_h :sys_wait_h);
|
||||
my $interface;
|
||||
Getopt::Long::Configure("require_order");
|
||||
GetOptions(
|
||||
"interface=s" => \$interface,
|
||||
);
|
||||
my %nodehdl;
|
||||
my $xcathost='localhost:3001';
|
||||
if ($ENV{XCATHOST}) {
|
||||
$xcathost=$ENV{XCATHOST};
|
||||
}
|
||||
|
||||
my $pshmaxp = 64; #TODO: should this be server dictated or local conf?
|
||||
unless (@ARGV) {
|
||||
print "Usage: psh [-i <suffix] <noderange> <command>\n";
|
||||
}
|
||||
my $noderange = $ARGV[0];
|
||||
my $client = IO::Socket::SSL->new(
|
||||
PeerAddr=>$xcathost,
|
||||
SSL_key_file=>$ENV{HOME}."/.xcat/client-key.pem",
|
||||
SSL_cert_file=>$ENV{HOME}."/.xcat/client-cert.pem",
|
||||
SSL_ca_file => $ENV{HOME}."/.xcat/ca.pem",
|
||||
SSL_use_cert => 1,
|
||||
#SSL_verify_mode => 1,
|
||||
);
|
||||
die "Connection failure: $!\n" unless ($client);
|
||||
my %cmdref = (command => 'noderange', noderange => $noderange);
|
||||
$SIG{ALRM} = sub { die "No response getting noderange" };
|
||||
alarm(15);
|
||||
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
|
||||
alarm(15);
|
||||
my $response="";
|
||||
my @nodes=();
|
||||
while (<$client>) {
|
||||
alarm(0);
|
||||
$response .= $_;
|
||||
if ($response =~ m/<\/xcatresponse>/) {
|
||||
$rsp=XMLin($response, ForceArray => ['node']);
|
||||
$response='';
|
||||
if ($rsp->{warning}) {
|
||||
printf "Warning: ".$rsp->{warning}."\n";
|
||||
}
|
||||
if ($rsp->{error}) {
|
||||
die ("ERROR: ".$rsp->{error}."\n");
|
||||
} elsif ($rsp->{node}) {
|
||||
@nodes=@{$rsp->{node}};
|
||||
}
|
||||
if ($rsp->{serverdone}) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close($client);
|
||||
my $children = 0;
|
||||
my $inputs = new IO::Select;
|
||||
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { $children--; } };
|
||||
if ($interface) {
|
||||
foreach (@nodes) {
|
||||
s/$/-$interface/;
|
||||
}
|
||||
}
|
||||
foreach (@nodes) {
|
||||
my $node=$_;
|
||||
while ($children > $pshmaxp) { processoutput($inputs); }
|
||||
my $child;
|
||||
$children++;
|
||||
sshnode(\$child,$node,@ARGV[1 .. $#ARGV]);
|
||||
$inputs->add($child);
|
||||
$nodehdl{$child} = $node;
|
||||
}
|
||||
while ($children) {
|
||||
processoutput($inputs);
|
||||
}
|
||||
while (processoutput($inputs)) {};
|
||||
exit(0);
|
||||
|
||||
sub processoutput { #This way, one arbiter handles output, no interrupting
|
||||
my $inputs = shift;
|
||||
my @readyins = $inputs->can_read(1);
|
||||
my $rc = @readyins;
|
||||
my $readyh;
|
||||
foreach $readyh (@readyins) {
|
||||
my $line = <$readyh>;
|
||||
unless ($line) {
|
||||
$inputs->remove($readyh);
|
||||
close($readyh);
|
||||
next;
|
||||
}
|
||||
print $nodehdl{$readyh}.": ".$line;
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
sub sshnode {
|
||||
my $out = shift;
|
||||
my $node = shift;
|
||||
my $in;
|
||||
my $args = join(" ",@_);
|
||||
open($$out,"ssh -o BatchMode=yes $node " . xCAT::Utils->quote($args) . " 2>&1 |");
|
||||
}
|
241
xCAT-client-2.0/usr/bin/xcatDBcmds
Executable file
241
xCAT-client-2.0/usr/bin/xcatDBcmds
Executable file
@ -0,0 +1,241 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
use File::Basename;
|
||||
use xCAT::Client submit_request;
|
||||
|
||||
my $bname = basename($0);
|
||||
|
||||
#########################################
|
||||
# Main
|
||||
#
|
||||
# xcatDBcmds
|
||||
#
|
||||
# Handles xCAT DB object management commands:
|
||||
# xdefmk, xdefch, xdefls, & xdefrm.
|
||||
#
|
||||
# Builds hash and submits request.
|
||||
#
|
||||
# Note: The subroutines that implement these commands
|
||||
# are in /usr/lib/xcat/plugins/DBobjectdefs.pm
|
||||
# on the xCAT management node.
|
||||
#
|
||||
#########################################
|
||||
|
||||
my $cmdref;
|
||||
|
||||
# set the command name to pass to the plugin
|
||||
if ($bname =~ /xcatDBcmds/)
|
||||
{
|
||||
$cmdref->{command}->[0] = shift @ARGV;
|
||||
}
|
||||
elsif ($bname =~ /^(.*$)/)
|
||||
{
|
||||
$cmdref->{command}->[0] = $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Bad usage\n");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print "The command \'$cmdref->{command}->[0]\' is not yet available.\n";
|
||||
exit 0;
|
||||
|
||||
# add all the cmd line args to the hash - to pass to the plugin subroutine
|
||||
foreach (@ARGV)
|
||||
{
|
||||
push(@{$cmdref->{arg}}, $_);
|
||||
}
|
||||
|
||||
if (!($bname =~ /xdefmk/))
|
||||
{
|
||||
|
||||
#
|
||||
# We need to see if a noderange was provided on the command line
|
||||
# - the command line could be flags(options) -> noderange -> attr=val pairs
|
||||
# - the noderange is used by xCAT remote access support infrastructure
|
||||
# so we need to set it now
|
||||
#
|
||||
|
||||
use Getopt::Long;
|
||||
|
||||
# Allows opts to be grouped (e.g. -avx)
|
||||
Getopt::Long::Configure("bundling");
|
||||
|
||||
# parse the options
|
||||
if (
|
||||
!GetOptions(
|
||||
'all|a' => \$::opt_a,
|
||||
'dynamic|d' => \$::opt_d,
|
||||
'f=s' => \$::opt_f,
|
||||
'i=s' => \$::opt_i,
|
||||
'help|h' => \$::opt_h,
|
||||
'long|l' => \$::opt_l,
|
||||
'm|minus' => \$::opt_m,
|
||||
'o=s' => \$::opt_o,
|
||||
'r|relace' => \$::opt_r,
|
||||
't=s' => \$::opt_t,
|
||||
'verbose|V' => \$::opt_V,
|
||||
'version|v' => \$::opt_v,
|
||||
'w=s' => \$::opt_w,
|
||||
'x=s' => \$::opt_x,
|
||||
'z=s' => \$::opt_z
|
||||
)
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
# a node range would be the next arg - but not if it contains an "=" sign
|
||||
# - then it would be an attr=val operand
|
||||
my $arg = shift(@ARGV);
|
||||
if (!($arg =~ /=/))
|
||||
{
|
||||
$cmdref->{noderange}->[0] = $arg;
|
||||
|
||||
# could check if valid noderange at this point???
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
xCAT::Client::submit_request($cmdref, \&handle_response);
|
||||
|
||||
print "\n";
|
||||
|
||||
exit 0;
|
||||
|
||||
# may want to modify handle_response at some point!!!!!!!
|
||||
|
||||
##########################################
|
||||
# handle_response is the callback that is
|
||||
# invoked to print out the data returned by
|
||||
# the plugin.
|
||||
#
|
||||
# Format of the response hash:
|
||||
# {data => [ 'data str1', 'data str2', '...' ] }
|
||||
#
|
||||
# Results are printed as:
|
||||
# data str1
|
||||
# data str2
|
||||
#
|
||||
# or:
|
||||
# {data => [ {desc => [ 'desc1' ],
|
||||
# contents => [ 'contents1' ] },
|
||||
# {desc => [ 'desc2 ],
|
||||
# contents => [ 'contents2' ] }
|
||||
# :
|
||||
# ] }
|
||||
# NOTE: In this format, only the data array can have more than one
|
||||
# element. All other arrays are assumed to be a single element.
|
||||
# Results are printed as:
|
||||
# desc1: contents1
|
||||
# desc2: contents2
|
||||
#
|
||||
# or:
|
||||
# {node => [ {name => ['node1'],
|
||||
# data => [ {desc => [ 'node1 desc' ],
|
||||
# contents => [ 'node1 contents' ] } ] },
|
||||
# {name => ['node2'],
|
||||
# data => [ {desc => [ 'node2 desc' ],
|
||||
# contents => [ 'node2 contents' ] } ] },
|
||||
# :
|
||||
# ] }
|
||||
# NOTE: Only the node array can have more than one element.
|
||||
# All other arrays are assumed to be a single element.
|
||||
#
|
||||
# This was generated from the corresponding HTML:
|
||||
# <xcatrequest>
|
||||
# <node>
|
||||
# <name>node1</name>
|
||||
# <data>
|
||||
# <desc>node1 desc</desc>
|
||||
# <contents>node1 contents</contents>
|
||||
# </data>
|
||||
# </node>
|
||||
# <node>
|
||||
# <name>node2</name>
|
||||
# <data>
|
||||
# <desc>node2 desc</desc>
|
||||
# <contents>node2 contents</contents>
|
||||
# </data>
|
||||
# </node>
|
||||
# </xcatrequest>
|
||||
#
|
||||
# Results are printed as:
|
||||
# node_name: desc: contents
|
||||
##########################################
|
||||
sub handle_response
|
||||
{
|
||||
my $rsp = shift;
|
||||
|
||||
# Handle {node} structure
|
||||
if ($rsp->{node})
|
||||
{
|
||||
my $nodes = ($rsp->{node});
|
||||
my $node;
|
||||
foreach $node (@$nodes)
|
||||
{
|
||||
my $desc = $node->{name}->[0];
|
||||
if ($node->{data})
|
||||
{
|
||||
if (ref(\($node->{data}->[0])) eq 'SCALAR')
|
||||
{
|
||||
$desc = $desc . ": " . $node->{data}->[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($node->{data}->[0]->{desc})
|
||||
{
|
||||
$desc = $desc . ": " . $node->{data}->[0]->{desc}->[0];
|
||||
}
|
||||
if ($node->{data}->[0]->{contents})
|
||||
{
|
||||
$desc = "$desc: " . $node->{data}->[0]->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc)
|
||||
{
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Handle {data} structure with no nodes
|
||||
if ($rsp->{data})
|
||||
{
|
||||
my $data = ($rsp->{data});
|
||||
my $data_entry;
|
||||
foreach $data_entry (@$data)
|
||||
{
|
||||
my $desc;
|
||||
if (ref(\($data_entry)) eq 'SCALAR')
|
||||
{
|
||||
$desc = $data_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($data_entry->{desc})
|
||||
{
|
||||
$desc = $data_entry->{desc}->[0];
|
||||
}
|
||||
if ($data_entry->{contents})
|
||||
{
|
||||
if ($desc)
|
||||
{
|
||||
$desc = "$desc: " . $data_entry->{contents}->[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$desc = $data_entry->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc)
|
||||
{
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
168
xCAT-client-2.0/usr/bin/xcatclient
Executable file
168
xCAT-client-2.0/usr/bin/xcatclient
Executable file
@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use IO::Socket::SSL;
|
||||
use IO::Socket::INET;
|
||||
use File::Basename;
|
||||
use Data::Dumper;
|
||||
use xCAT::Client submit_request;
|
||||
my $bname = basename($0);
|
||||
|
||||
#########################################
|
||||
# Main
|
||||
# Build hash and submit request
|
||||
#########################################
|
||||
|
||||
my $exitcode = 0; #var to store exit code that results from responses
|
||||
my $cmdref;
|
||||
if($bname =~ /xcatclient/) {
|
||||
$cmdref->{command}->[0]=shift @ARGV;
|
||||
} elsif ($bname =~/^(.*$)/) {
|
||||
$cmdref->{command}->[0] = $1;
|
||||
} else {
|
||||
printf("Bad usage\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (-p STDIN) {
|
||||
my $data;
|
||||
while ( <STDIN> ) {
|
||||
$data.=$_;
|
||||
}
|
||||
$cmdref->{stdin}->[0]=$data;
|
||||
}
|
||||
|
||||
my $arg=shift(@ARGV);
|
||||
while ($arg =~ /^-/) {
|
||||
push (@{$cmdref->{arg}}, $arg);
|
||||
$arg=shift(@ARGV);
|
||||
}
|
||||
if ($arg ne "NO_NODE_RANGE") {
|
||||
$cmdref->{noderange}->[0]=$arg;
|
||||
}
|
||||
foreach (@ARGV) { push (@{$cmdref->{arg}}, $_ ); }
|
||||
#$cmdref->{arg}=\@ARGV;
|
||||
xCAT::Client::submit_request($cmdref,\&handle_response);
|
||||
exit $exitcode;
|
||||
|
||||
|
||||
##########################################
|
||||
# handle_response is the callback that is
|
||||
# invoked to print out the data returned by
|
||||
# the plugin.
|
||||
#
|
||||
# Format of the response hash:
|
||||
# {data => [ 'data str1', 'data str2', '...' ] }
|
||||
#
|
||||
# Results are printed as:
|
||||
# data str1
|
||||
# data str2
|
||||
#
|
||||
# or:
|
||||
# {data => [ {desc => [ 'desc1' ],
|
||||
# contents => [ 'contents1' ] },
|
||||
# {desc => [ 'desc2 ],
|
||||
# contents => [ 'contents2' ] }
|
||||
# :
|
||||
# ] }
|
||||
# NOTE: In this format, only the data array can have more than one
|
||||
# element. All other arrays are assumed to be a single element.
|
||||
# Results are printed as:
|
||||
# desc1: contents1
|
||||
# desc2: contents2
|
||||
#
|
||||
# or:
|
||||
# {node => [ {name => ['node1'],
|
||||
# data => [ {desc => [ 'node1 desc' ],
|
||||
# contents => [ 'node1 contents' ] } ] },
|
||||
# {name => ['node2'],
|
||||
# data => [ {desc => [ 'node2 desc' ],
|
||||
# contents => [ 'node2 contents' ] } ] },
|
||||
# :
|
||||
# ] }
|
||||
# NOTE: Only the node array can have more than one element.
|
||||
# All other arrays are assumed to be a single element.
|
||||
#
|
||||
# This was generated from the corresponding HTML:
|
||||
# <xcatrequest>
|
||||
# <node>
|
||||
# <name>node1</name>
|
||||
# <data>
|
||||
# <desc>node1 desc</desc>
|
||||
# <contents>node1 contents</contents>
|
||||
# </data>
|
||||
# </node>
|
||||
# <node>
|
||||
# <name>node2</name>
|
||||
# <data>
|
||||
# <desc>node2 desc</desc>
|
||||
# <contents>node2 contents</contents>
|
||||
# </data>
|
||||
# </node>
|
||||
# </xcatrequest>
|
||||
#
|
||||
# Results are printed as:
|
||||
# node_name: desc: contents
|
||||
##########################################
|
||||
sub handle_response {
|
||||
my $rsp = shift;
|
||||
# Handle {node} structure
|
||||
if ($rsp->{errorcode}) {
|
||||
foreach my $ecode (@{$rsp->{errorcode}}) {
|
||||
$exitcode |= $ecode;
|
||||
}
|
||||
}
|
||||
if ($rsp->{node}) {
|
||||
my $nodes=($rsp->{node});
|
||||
my $node;
|
||||
foreach $node (@$nodes) {
|
||||
my $desc=$node->{name}->[0];
|
||||
if ($node->{errorcode}) {
|
||||
foreach my $ecode (@{$node->{errorcode}}) {
|
||||
$exitcode |= $ecode;
|
||||
}
|
||||
}
|
||||
if ($node->{data}) {
|
||||
if (ref(\($node->{data}->[0])) eq 'SCALAR') {
|
||||
$desc=$desc.": ".$node->{data}->[0];
|
||||
} else {
|
||||
if ($node->{data}->[0]->{desc}) {
|
||||
$desc=$desc.": ".$node->{data}->[0]->{desc}->[0];
|
||||
}
|
||||
if ($node->{data}->[0]->{contents}) {
|
||||
$desc="$desc: ".$node->{data}->[0]->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc) {
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Handle {data} structure with no nodes
|
||||
if ($rsp->{data}) {
|
||||
my $data=($rsp->{data});
|
||||
my $data_entry;
|
||||
foreach $data_entry (@$data) {
|
||||
my $desc;
|
||||
if (ref(\($data_entry)) eq 'SCALAR') {
|
||||
$desc=$data_entry;
|
||||
} else {
|
||||
if ($data_entry->{desc}) {
|
||||
$desc=$data_entry->{desc}->[0];
|
||||
}
|
||||
if ($data_entry->{contents}) {
|
||||
if ($desc) {
|
||||
$desc="$desc: ".$data_entry->{contents}->[0];
|
||||
} else {
|
||||
$desc=$data_entry->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc) {
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
xCAT-client-2.0/usr/bin/xcatclientnnr
Executable file
25
xCAT-client-2.0/usr/bin/xcatclientnnr
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use File::Basename;
|
||||
|
||||
#######################################
|
||||
# It handles the commands without noderanges.
|
||||
#######################################
|
||||
my $bname = basename($0);
|
||||
my $cmd;
|
||||
if($bname =~ /xcatclientnnr/) {
|
||||
$cmd = shift @ARGV;
|
||||
} elsif ($bname =~/^(.*$)/) {
|
||||
$cmd = $1;
|
||||
} else {
|
||||
printf("Bad usage\n");
|
||||
exit(1);
|
||||
}
|
||||
exec("/usr/bin/xcatclient $cmd NO_NODE_RANGE @ARGV 2>&1");
|
||||
#if (system("/usr/bin/xcatclient $cmd NO_NODE_RANGE @ARGV 2>&1") != 0) {
|
||||
# print "$cmd failed: $?\n";
|
||||
#}
|
||||
|
||||
#exit;
|
||||
|
||||
|
27
xCAT-client-2.0/usr/bin/xcoll
Executable file
27
xCAT-client-2.0/usr/bin/xcoll
Executable file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use Data::Dumper;
|
||||
my %output;
|
||||
while (<STDIN>) {
|
||||
my $node;
|
||||
my $output;
|
||||
if (/:/) {
|
||||
($node,$output) = split /:/,$_,2;
|
||||
} else {
|
||||
$node= "UNKNOWN";
|
||||
$output = $_;
|
||||
}
|
||||
$output =~ s/^ //;
|
||||
$output{$node}.=$output;
|
||||
}
|
||||
my %collated;
|
||||
foreach (keys %output) {
|
||||
$collated{$output{$_}}->{$_}=1;
|
||||
}
|
||||
foreach (keys %collated) {
|
||||
my $nodes = join(',',sort (keys %{$collated{$_}}));
|
||||
print "====================================\n";
|
||||
print "$nodes\n";
|
||||
print "====================================\n";
|
||||
print $_;
|
||||
}
|
446
xCAT-client-2.0/usr/bin/xdsh
Normal file
446
xCAT-client-2.0/usr/bin/xdsh
Normal file
@ -0,0 +1,446 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use IO::Socket::SSL;
|
||||
use IO::Socket::INET;
|
||||
use File::Basename;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT::Client submit_request;
|
||||
my $bname = basename($0);
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head1 xdsh/xdcp
|
||||
|
||||
This program is the client interface for xdsh/xdcp.
|
||||
|
||||
|
||||
xdsh/xdcp command
|
||||
This is the client interface for the xdsh/xdcp command
|
||||
Call parse_args to verify input
|
||||
Build hash and submit request
|
||||
Note: xdsh/xdcp (dsh/dcp for xCAT) only supports a subset of the options
|
||||
supported by dsh/dcp. See help and man page of each command for the
|
||||
differences.
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Main
|
||||
|
||||
#$ENV{XCATBYPASS} = "yes"; # set bypass mode
|
||||
my $rc = 0;
|
||||
|
||||
# check for help and Environment Variables
|
||||
if ($bname eq "xdsh")
|
||||
{
|
||||
&parse_args_xdsh;
|
||||
}
|
||||
else
|
||||
{ # xdcp
|
||||
&parse_args_xdcp;
|
||||
}
|
||||
|
||||
# report unsupported dsh exports
|
||||
&check_invalid_exports;
|
||||
|
||||
my $cmdref;
|
||||
$cmdref->{command}->[0] = $bname; # save my command name
|
||||
|
||||
my $arg = shift(@ARGV);
|
||||
while ($arg =~ /^-/)
|
||||
{
|
||||
push(@{$cmdref->{arg}}, $arg); # save command arguments
|
||||
$arg = shift(@ARGV);
|
||||
}
|
||||
$cmdref->{noderange}->[0] = $arg; # save nodes
|
||||
|
||||
#
|
||||
# add flgs for all the valid dsh/dcp Env Variable set
|
||||
#
|
||||
# The first ones are common to dsh/dcp
|
||||
# if nodes from file and none on the command line
|
||||
if ($ENV{'DSH_NODE_RSH'})
|
||||
{
|
||||
my $value = $ENV{'DSH_NODE_RSH'};
|
||||
push(@{$cmdref->{arg}}, "-r $value ");
|
||||
|
||||
}
|
||||
if ($ENV{'DSH_NODE_OPTS'})
|
||||
{
|
||||
my $value = $ENV{'DSH_NODE_OPTS'};
|
||||
push(@{$cmdref->{arg}}, "-o $value ");
|
||||
|
||||
}
|
||||
if ($ENV{'DSH_FANOUT'})
|
||||
{
|
||||
my $value = $ENV{'DSH_FANOUT'};
|
||||
push(@{$cmdref->{arg}}, "-f $value ");
|
||||
|
||||
}
|
||||
if ($ENV{'DSH_TIMEOUT'})
|
||||
{
|
||||
my $value = $ENV{'DSH_TIMEOUT'};
|
||||
push(@{$cmdref->{arg}}, "-t $value ");
|
||||
|
||||
}
|
||||
if ($bname eq "xdsh")
|
||||
{
|
||||
if ($ENV{'DSH_REPORT'})
|
||||
{
|
||||
my $value = $ENV{'DSH_REPORT'};
|
||||
push(@{$cmdref->{arg}}, "--report $value ");
|
||||
|
||||
}
|
||||
}
|
||||
## set XCAT Context always ##
|
||||
push(@{$cmdref->{arg}}, "-C XCAT");
|
||||
|
||||
foreach (@ARGV) { push(@{$cmdref->{arg}}, $_); }
|
||||
|
||||
xCAT::Client::submit_request($cmdref, \&handle_response);
|
||||
exit $rc;
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 parse_args_xdsh
|
||||
|
||||
Parses for dsh input
|
||||
Check if the command ask for help and display usage
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub parse_args_xdsh
|
||||
{
|
||||
|
||||
my $usagemsg1 =
|
||||
" xdsh -h \n xdsh -q \n xdsh -v \n xdsh [noderange] [group]\n";
|
||||
my $usagemsg2 =
|
||||
" [-C context] [-c] [-e] [-E environment_file] [-f fanout]\n";
|
||||
my $usagemsg3 =
|
||||
" [-F output_file] [-i] [-l user_ID] [-L] [--log log_file]\n";
|
||||
my $usagemsg4 = " [-m] [-o options] [-Q] [-r remote_shell] \n";
|
||||
my $usagemsg5 =
|
||||
" [-s] [-S ksh | csh] [-t timeout] [-T] [-X environment variables] [-v] [-z]\n";
|
||||
my $usagemsg6 =
|
||||
" [--report report_path] [--report-name report_name]\n";
|
||||
my $usagemsg7 = " [command_list]\n";
|
||||
my $usagemsg8 = "Note:Context is always set to XCAT\n";
|
||||
my $usagemsg .= $usagemsg1 .= $usagemsg2 .= $usagemsg3 .= $usagemsg4 .=
|
||||
$usagemsg5 .= $usagemsg6 .= $usagemsg7;
|
||||
|
||||
Getopt::Long::Configure("posix_default");
|
||||
Getopt::Long::Configure("no_gnu_compat");
|
||||
Getopt::Long::Configure("bundling");
|
||||
|
||||
if (
|
||||
!GetOptions(
|
||||
'e|execute' => \$::EXECUTE,
|
||||
'f|fanout=i' => \$::FANOUT,
|
||||
'h|help' => \$::HELP,
|
||||
'i|notify' => \$::NOTIFY,
|
||||
'l|user=s' => \$::USER,
|
||||
'm|monitor' => \$::MONITOR,
|
||||
'o|node-options=s' => \$::NODEOPTS,
|
||||
'q|show-config' => \$::SHOWCFG,
|
||||
'r|node-rsh=s' => \$::NODERSH,
|
||||
's|stream' => \$::STREAM,
|
||||
't|timeout=i' => \$::TIMEOUT,
|
||||
'v|verify' => \$::VERIFY,
|
||||
'z|exit-status' => \$::EXITSTAT,
|
||||
'E|environment=s' => \$::ENV,
|
||||
'F|output-file=s' => \$::OUTPUTFILE,
|
||||
'I|ignore-sig|ignoresig=s' => \$::IGNORESIG,
|
||||
'L|no-locale' => \$::NOLOCALE,
|
||||
'Q|silent' => \$::SILENT,
|
||||
'S|syntax=s' => \$::SYNTAX,
|
||||
'T|trace' => \$::TRACE,
|
||||
'V|version' => \$::VERSION,
|
||||
'command-name|commandName=s' => \$::COMMANDNAME,
|
||||
'command-description|commandDescription=s' => \$::COMMANDDES,
|
||||
'log=s' => \$::LOG,
|
||||
'report=s' => \$::REPORT,
|
||||
'R|reports=s' => \$::REPORTS,
|
||||
'report-name|reportName=s' => \$::REPORTNAME,
|
||||
'W|noFileWriting' => \$::NOFILEWRITE,
|
||||
|
||||
'w|wcoll=s' => \$::WCOLL,
|
||||
'X:s' => \$::IGNORENV
|
||||
|
||||
)
|
||||
)
|
||||
{
|
||||
xCAT::MsgUtils->message("I", "$usagemsg");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($::HELP)
|
||||
{
|
||||
xCAT::MsgUtils->message("I", "$usagemsg");
|
||||
exit 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 parse_args_xdcp
|
||||
|
||||
Parses for dcp input
|
||||
Check if the command ask for help and display usage
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub parse_args_xdcp
|
||||
{
|
||||
my $usagemsg1 =
|
||||
" xdcp -h \n xdcp -q \n xdcp -v \n xdcp [noderange] [group]\n";
|
||||
my $usagemsg2 = " [-C context] [-c] [-f fanout] [-l user_ID]\n";
|
||||
my $usagemsg3 =
|
||||
" [-o options] [-s] [-p] [-P] [-Q] [-r node_remote_copy]\n";
|
||||
my $usagemsg4 =
|
||||
" [-R] [-t timeout] [-T] [-X environment variables] [-v] \n";
|
||||
my $usagemsg5 = " source_file... target_path\n";
|
||||
my $usagemsg6 = "Note:Context is always set to XCAT\n";
|
||||
my $usagemsg .= $usagemsg1 .= $usagemsg2 .= $usagemsg3 .= $usagemsg4 .=
|
||||
$usagemsg5 .= $usagemsg6;
|
||||
|
||||
Getopt::Long::Configure("posix_default");
|
||||
Getopt::Long::Configure("no_gnu_compat");
|
||||
Getopt::Long::Configure("bundling");
|
||||
|
||||
if (
|
||||
!GetOptions(
|
||||
'f|fanout=i' => \$::FANOUT,
|
||||
'h|help' => \$::HELP,
|
||||
'l|user=s' => \$::USER,
|
||||
'o|node-options=s' => \$::NODEOPTS,
|
||||
'p|preserver' => \$::PRESERVE,
|
||||
'q|show-config' => \$::SHOWCFG,
|
||||
'r|c|node-rcp=s' => \$::NODERCP,
|
||||
's' => \$::RSYNC,
|
||||
't|timeout=i' => \$::TIMEOUT,
|
||||
'v|verify' => \$::VERIFY,
|
||||
'Q|silent' => \$::SILENT,
|
||||
'P|pull' => \$::PULL,
|
||||
'R|recursive' => \$::RECURSIVE,
|
||||
'T|trace' => \$::TRACE,
|
||||
'V|version' => \$::VERSION,
|
||||
'w|wcoll=s' => \$::WCOLL,
|
||||
'X:s' => \$::IGNORENV
|
||||
|
||||
)
|
||||
)
|
||||
{
|
||||
xCAT::MsgUtils->message("I", "$usagemsg");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($::HELP)
|
||||
{
|
||||
xCAT::MsgUtils->message("I", "$usagemsg");
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 check_invalid_exports
|
||||
Check for unsupported dsh exports and warns
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub check_invalid_exports
|
||||
|
||||
{
|
||||
##
|
||||
# Check for unsupported Environment Variables
|
||||
# DSH_DEVICE_LIST, DSH_DEVICE_OPTS, DSH_DEVICE_RCP,DSH_DEVICE_RSH,
|
||||
# DSH_NODEGROUP_PATH
|
||||
##
|
||||
if ($ENV{'DSH_NODE_LIST'})
|
||||
{
|
||||
xCAT::MsgUtils->message(
|
||||
"I",
|
||||
"DSH_NODE_LIST is set but is not supported. It will be ignored.\n"
|
||||
);
|
||||
}
|
||||
if ($ENV{'DSH_DEVICE_LIST'})
|
||||
{
|
||||
xCAT::MsgUtils->message(
|
||||
"I",
|
||||
"DSH_DEVICE_LIST is set but is not supported. It will be ignored.\n"
|
||||
);
|
||||
}
|
||||
if ($ENV{'DSH_DEVICE_OPTS'})
|
||||
{
|
||||
xCAT::MsgUtils->message(
|
||||
"I",
|
||||
"DSH_DEVICE_OPTS is set but is not supported. It will be ignored.\n"
|
||||
);
|
||||
}
|
||||
if ($ENV{'DSH_DEVICE_RCP'})
|
||||
{
|
||||
xCAT::MsgUtils->message(
|
||||
"I",
|
||||
"DSH_DEVICE_RCP is set but is not supported. It will be ignored.\n"
|
||||
);
|
||||
}
|
||||
if ($ENV{'DSH_DEVICE_RSH'})
|
||||
{
|
||||
xCAT::MsgUtils->message(
|
||||
"I",
|
||||
"DSH_DEVICE_RSH is set but is not supported. It will be ignored.\n"
|
||||
);
|
||||
}
|
||||
if ($ENV{'DSH_NODEGROUP_PATH'})
|
||||
{
|
||||
xCAT::MsgUtils->message(
|
||||
"I",
|
||||
"DSH_NODEGROUP_PATH is set but is not supported. It will be ignored.\n"
|
||||
);
|
||||
}
|
||||
if ($ENV{'RSYNC_RSH'})
|
||||
{
|
||||
xCAT::MsgUtils->message("I",
|
||||
" RSYNC_RSH is set but is not supported. It will be ignored.\n");
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 handle_response
|
||||
handle_response is the callback that is
|
||||
invoked to print out the data returned by
|
||||
the plugin.
|
||||
|
||||
Format of the response hash:
|
||||
{data => [ 'data str1', 'data str2', '...' ] }
|
||||
|
||||
Results are printed as:
|
||||
data str1
|
||||
data str2
|
||||
|
||||
or:
|
||||
{data => [ {desc => [ 'desc1' ],
|
||||
contents => [ 'contents1' ] },
|
||||
{desc => [ 'desc2 ],
|
||||
contents => [ 'contents2' ] }
|
||||
:
|
||||
] }
|
||||
NOTE: In this format, only the data array can have more than one
|
||||
element. All other arrays are assumed to be a single element.
|
||||
Results are printed as:
|
||||
desc1: contents1
|
||||
desc2: contents2
|
||||
|
||||
or:
|
||||
{node => [ {name => ['node1'],
|
||||
data => [ {desc => [ 'node1 desc' ],
|
||||
contents => [ 'node1 contents' ] } ] },
|
||||
{name => ['node2'],
|
||||
data => [ {desc => [ 'node2 desc' ],
|
||||
contents => [ 'node2 contents' ] } ] },
|
||||
:
|
||||
] }
|
||||
NOTE: Only the node array can have more than one element.
|
||||
All other arrays are assumed to be a single element.
|
||||
|
||||
This was generated from the corresponding HTML:
|
||||
<xcatrequest>
|
||||
<node>
|
||||
<name>node1</name>
|
||||
<data>
|
||||
<desc>node1 desc</desc>
|
||||
<contents>node1 contents</contents>
|
||||
</data>
|
||||
</node>
|
||||
<node>
|
||||
<name>node2</name>
|
||||
<data>
|
||||
<desc>node2 desc</desc>
|
||||
<contents>node2 contents</contents>
|
||||
</data>
|
||||
</node>
|
||||
</xcatrequest>
|
||||
|
||||
Results are printed as:
|
||||
node_name: desc: contents
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub handle_response
|
||||
{
|
||||
my $rsp = shift;
|
||||
|
||||
# Handle {node} structure
|
||||
if ($rsp->{node})
|
||||
{
|
||||
my $nodes = ($rsp->{node});
|
||||
my $node;
|
||||
foreach $node (@$nodes)
|
||||
{
|
||||
my $desc = $node->{name}->[0];
|
||||
if ($node->{data})
|
||||
{
|
||||
if (ref(\($node->{data}->[0])) eq 'SCALAR')
|
||||
{
|
||||
$desc = $desc . ": " . $node->{data}->[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($node->{data}->[0]->{desc})
|
||||
{
|
||||
$desc = $desc . ": " . $node->{data}->[0]->{desc}->[0];
|
||||
}
|
||||
if ($node->{data}->[0]->{contents})
|
||||
{
|
||||
$desc = "$desc: " . $node->{data}->[0]->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc)
|
||||
{
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Handle {data} structure with no nodes
|
||||
if ($rsp->{data})
|
||||
{
|
||||
my $data = ($rsp->{data});
|
||||
my $data_entry;
|
||||
foreach $data_entry (@$data)
|
||||
{
|
||||
my $desc;
|
||||
if (ref(\($data_entry)) eq 'SCALAR')
|
||||
{
|
||||
$desc = $data_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($data_entry->{desc})
|
||||
{
|
||||
$desc = $data_entry->{desc}->[0];
|
||||
}
|
||||
if ($data_entry->{contents})
|
||||
{
|
||||
if ($desc)
|
||||
{
|
||||
$desc = "$desc: " . $data_entry->{contents}->[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$desc = $data_entry->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc)
|
||||
{
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
xCAT-client-2.0/usr/sbin/tabedit
Executable file
42
xCAT-client-2.0/usr/sbin/tabedit
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
function cexit {
|
||||
if [ -d /tmp/tabedit.$$ ]; then
|
||||
rm -rf /tmp/tabedit.$$;
|
||||
fi
|
||||
exit
|
||||
}
|
||||
trap cexit 2 15
|
||||
|
||||
TABLE=$1
|
||||
if [ -z "$EDITOR" ]; then
|
||||
echo "Define EDITOR environment variable before running this command"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TABLE" ]; then
|
||||
echo "Usage: tabedit <tablename>";
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p /tmp/tabedit.$$/
|
||||
xcatclientnnr tabdump $1 > /tmp/tabedit.$$/$1.csv
|
||||
#use md5sum to check if it actually changes..
|
||||
SUM=`md5sum /tmp/tabedit.$$/$1.csv`
|
||||
EXIT=0
|
||||
while [ $EXIT -eq 0 ]; do
|
||||
cd /tmp/tabedit.$$
|
||||
"$EDITOR" $1.csv
|
||||
cd -
|
||||
NEWSUM=`md5sum /tmp/tabedit.$$/$1.csv`
|
||||
if [ "$NEWSUM" == "$SUM" ]; then
|
||||
echo "No file modifications detected, not restoring."
|
||||
break;
|
||||
fi
|
||||
if `dirname $0`/tabrestore /tmp/tabedit.$$/$1.csv; then
|
||||
break;
|
||||
else
|
||||
echo "Above errors occured, hit enter to edit, or ctrl-c to abort"
|
||||
read JNK
|
||||
fi
|
||||
done
|
||||
cexit
|
||||
|
161
xCAT-client-2.0/usr/sbin/tabrestore
Executable file
161
xCAT-client-2.0/usr/sbin/tabrestore
Executable file
@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#Just like xcatclient, but needs to read a file in and pass it as $request->data
|
||||
use IO::Socket::SSL;
|
||||
use IO::Socket::INET;
|
||||
use File::Basename;
|
||||
use Data::Dumper;
|
||||
use xCAT::Client submit_request;
|
||||
my $bname = basename($0);
|
||||
|
||||
#########################################
|
||||
# Main
|
||||
# Build hash and submit request
|
||||
#########################################
|
||||
|
||||
my $cmdref;
|
||||
my $exitcode=0;
|
||||
$cmdref->{command}->[0] = "tabrestore";
|
||||
|
||||
my $arg=shift(@ARGV);
|
||||
while ($arg =~ /^-/) {
|
||||
push (@{$cmdref->{arg}}, $arg);
|
||||
$arg=shift(@ARGV);
|
||||
}
|
||||
unless ($arg) {
|
||||
printf("Usage: tabrestore [tablename].csv\n");
|
||||
exit(1);
|
||||
}
|
||||
my $filename = $arg;
|
||||
unless (-r $filename) {
|
||||
printf("Unable to open $arg for reading.\n");
|
||||
exit(1);
|
||||
}
|
||||
my $tabname = basename($filename);
|
||||
$tabname =~ s/\..*//;
|
||||
$cmdref->{table}->[0] = $tabname;
|
||||
my $fh;
|
||||
open($fh,$filename);
|
||||
while (<$fh>) {
|
||||
push @{$cmdref->{data}},$_;
|
||||
}
|
||||
|
||||
foreach (@ARGV) { push (@{$cmdref->{arg}}, $_ ); }
|
||||
#$cmdref->{arg}=\@ARGV;
|
||||
xCAT::Client::submit_request($cmdref,\&handle_response);
|
||||
exit $exitcode;
|
||||
|
||||
|
||||
##########################################
|
||||
# handle_response is the callback that is
|
||||
# invoked to print out the data returned by
|
||||
# the plugin.
|
||||
#
|
||||
# Format of the response hash:
|
||||
# {data => [ 'data str1', 'data str2', '...' ] }
|
||||
#
|
||||
# Results are printed as:
|
||||
# data str1
|
||||
# data str2
|
||||
#
|
||||
# or:
|
||||
# {data => [ {desc => [ 'desc1' ],
|
||||
# contents => [ 'contents1' ] },
|
||||
# {desc => [ 'desc2 ],
|
||||
# contents => [ 'contents2' ] }
|
||||
# :
|
||||
# ] }
|
||||
# NOTE: In this format, only the data array can have more than one
|
||||
# element. All other arrays are assumed to be a single element.
|
||||
# Results are printed as:
|
||||
# desc1: contents1
|
||||
# desc2: contents2
|
||||
#
|
||||
# or:
|
||||
# {node => [ {name => ['node1'],
|
||||
# data => [ {desc => [ 'node1 desc' ],
|
||||
# contents => [ 'node1 contents' ] } ] },
|
||||
# {name => ['node2'],
|
||||
# data => [ {desc => [ 'node2 desc' ],
|
||||
# contents => [ 'node2 contents' ] } ] },
|
||||
# :
|
||||
# ] }
|
||||
# NOTE: Only the node array can have more than one element.
|
||||
# All other arrays are assumed to be a single element.
|
||||
#
|
||||
# This was generated from the corresponding HTML:
|
||||
# <xcatrequest>
|
||||
# <node>
|
||||
# <name>node1</name>
|
||||
# <data>
|
||||
# <desc>node1 desc</desc>
|
||||
# <contents>node1 contents</contents>
|
||||
# </data>
|
||||
# </node>
|
||||
# <node>
|
||||
# <name>node2</name>
|
||||
# <data>
|
||||
# <desc>node2 desc</desc>
|
||||
# <contents>node2 contents</contents>
|
||||
# </data>
|
||||
# </node>
|
||||
# </xcatrequest>
|
||||
#
|
||||
# Results are printed as:
|
||||
# node_name: desc: contents
|
||||
##########################################
|
||||
sub handle_response {
|
||||
my $rsp = shift;
|
||||
# Handle {node} structure
|
||||
if ($rsp->{node}) {
|
||||
my $nodes=($rsp->{node});
|
||||
my $node;
|
||||
foreach $node (@$nodes) {
|
||||
my $desc=$node->{name}->[0];
|
||||
if ($node->{data}) {
|
||||
if (ref(\($node->{data}->[0])) eq 'SCALAR') {
|
||||
$desc=$desc.": ".$node->{data}->[0];
|
||||
} else {
|
||||
if ($node->{data}->[0]->{desc}) {
|
||||
$desc=$desc.": ".$node->{data}->[0]->{desc}->[0];
|
||||
}
|
||||
if ($node->{data}->[0]->{contents}) {
|
||||
$desc="$desc: ".$node->{data}->[0]->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc) {
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Handle {data} structure with no nodes
|
||||
if ($rsp->{error}) {
|
||||
$exitcode=1;
|
||||
}
|
||||
if ($rsp->{data}) {
|
||||
my $data=($rsp->{data});
|
||||
my $data_entry;
|
||||
foreach $data_entry (@$data) {
|
||||
my $desc;
|
||||
if (ref(\($data_entry)) eq 'SCALAR') {
|
||||
$desc=$data_entry;
|
||||
} else {
|
||||
if ($data_entry->{desc}) {
|
||||
$desc=$data_entry->{desc}->[0];
|
||||
}
|
||||
if ($data_entry->{contents}) {
|
||||
if ($desc) {
|
||||
$desc="$desc: ".$data_entry->{contents}->[0];
|
||||
} else {
|
||||
$desc=$data_entry->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc) {
|
||||
print "$desc\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
4
xCAT-client-2.0/usr/svn-commit.tmp
Normal file
4
xCAT-client-2.0/usr/svn-commit.tmp
Normal file
@ -0,0 +1,4 @@
|
||||
Add a basic xcoll, without reverse noderange, reverse noderange will come post alpha
|
||||
--This line, and those below, will be ignored--
|
||||
|
||||
AM bin/xcoll
|
89
xCAT-client-2.0/xCAT-client.spec
Normal file
89
xCAT-client-2.0/xCAT-client.spec
Normal file
@ -0,0 +1,89 @@
|
||||
Summary: Core executables and data of the xCAT management project
|
||||
Name: xCAT-client
|
||||
Version: 2.0
|
||||
Release: snap%(date +"%Y%m%d%H%M")
|
||||
License: EPL
|
||||
Group: Applications/System
|
||||
Source: xCAT-client-2.0.tar.gz
|
||||
Packager: IBM Corp.
|
||||
Vendor: IBM Corp.
|
||||
Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
|
||||
Prefix: %{_prefix}
|
||||
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root
|
||||
|
||||
# AIX will build with an arch of "ppc"
|
||||
%ifos linux
|
||||
BuildArch: noarch
|
||||
%endif
|
||||
|
||||
Provides: xCAT-client = %{version}
|
||||
|
||||
%description
|
||||
xCAT-client provides the fundamental xCAT commands (chtab, chnode, rpower, etc) helpful in administrating systems at scale, with particular attention paid to large HPC clusters.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%build
|
||||
%install
|
||||
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/sbin
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/xcat/scripts
|
||||
|
||||
cp usr/bin/* $RPM_BUILD_ROOT/usr/bin
|
||||
chmod 755 $RPM_BUILD_ROOT/usr/bin/*
|
||||
cp usr/sbin/* $RPM_BUILD_ROOT/usr/sbin
|
||||
chmod 755 $RPM_BUILD_ROOT/usr/sbin/*
|
||||
|
||||
#cp usr/share/xcat/scripts/setup-local-client.sh $RPM_BUILD_ROOT/usr/share/xcat/scripts/setup-local-client.sh
|
||||
#chmod 755 $RPM_BUILD_ROOT/usr/share/xcat/scripts/setup-local-client.sh
|
||||
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rpower
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/sbin/makedhcp
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/sbin/makehosts
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/sbin/nodeset
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/sbin/makeconservercf
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rbeacon
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rvitals
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rinv
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rspreset
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rsetboot
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/rbootseq
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/reventlog
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/nodels
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/nodech
|
||||
ln -sf /usr/bin/xcatclient $RPM_BUILD_ROOT/usr/bin/noderm
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/sbin/tabdump
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/sbin/makedns
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/bin/gettab
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/sbin/nodeadd
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/sbin/makenetworks
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/sbin/copycds
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/bin/regnotif
|
||||
ln -sf /usr/bin/xcatclientnnr $RPM_BUILD_ROOT/usr/bin/unregnotif
|
||||
ln -sf /usr/bin/xcatDBcmds $RPM_BUILD_ROOT/usr/bin/xdefmk
|
||||
ln -sf /usr/bin/xcatDBcmds $RPM_BUILD_ROOT/usr/bin/xdefch
|
||||
ln -sf /usr/bin/xcatDBcmds $RPM_BUILD_ROOT/usr/bin/xdefls
|
||||
ln -sf /usr/bin/xcatDBcmds $RPM_BUILD_ROOT/usr/bin/xdefrm
|
||||
ln -sf /usr/bin/xdsh $RPM_BUILD_ROOT/usr/bin/xdcp
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc README
|
||||
%doc LICENSE.html
|
||||
/usr/bin/*
|
||||
/usr/sbin/*
|
||||
#/usr/share/xcat/scripts/setup-local-client.sh
|
||||
|
||||
%changelog
|
||||
* Wed May 2 2007 - Norm Nott <nott@us.ibm.com>
|
||||
- Made changes to make this work on AIX
|
||||
|
||||
* Tue Feb 20 2007 Jarrod Johnson <jbjohnso@us.ibm.com>
|
||||
- Start core rpm for 1.3 work
|
||||
|
326
xCAT-nbroot/LICENSE.html
Normal file
326
xCAT-nbroot/LICENSE.html
Normal file
@ -0,0 +1,326 @@
|
||||
<html xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||||
<meta name=ProgId content=Word.Document>
|
||||
<meta name=Generator content="Microsoft Word 9">
|
||||
<meta name=Originator content="Microsoft Word 9">
|
||||
<title>Eclipse Public License - Version 1.0</title>
|
||||
<!--[if gte mso 9]><xml>
|
||||
<o:DocumentProperties>
|
||||
<o:Revision>2</o:Revision>
|
||||
<o:TotalTime>3</o:TotalTime>
|
||||
<o:Created>2004-03-05T23:03:00Z</o:Created>
|
||||
<o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
|
||||
<o:Pages>4</o:Pages>
|
||||
<o:Words>1626</o:Words>
|
||||
<o:Characters>9270</o:Characters>
|
||||
<o:Lines>77</o:Lines>
|
||||
<o:Paragraphs>18</o:Paragraphs>
|
||||
<o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
|
||||
<o:Version>9.4402</o:Version>
|
||||
</o:DocumentProperties>
|
||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||
<w:WordDocument>
|
||||
<w:TrackRevisions/>
|
||||
</w:WordDocument>
|
||||
</xml><![endif]-->
|
||||
<style>
|
||||
<!--
|
||||
/* Font Definitions */
|
||||
@font-face
|
||||
{font-family:Tahoma;
|
||||
panose-1:2 11 6 4 3 5 4 4 2 4;
|
||||
mso-font-charset:0;
|
||||
mso-generic-font-family:swiss;
|
||||
mso-font-pitch:variable;
|
||||
mso-font-signature:553679495 -2147483648 8 0 66047 0;}
|
||||
/* Style Definitions */
|
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||||
{mso-style-parent:"";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p
|
||||
{margin-right:0in;
|
||||
mso-margin-top-alt:auto;
|
||||
mso-margin-bottom-alt:auto;
|
||||
margin-left:0in;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p.BalloonText, li.BalloonText, div.BalloonText
|
||||
{mso-style-name:"Balloon Text";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:8.0pt;
|
||||
font-family:Tahoma;
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
@page Section1
|
||||
{size:8.5in 11.0in;
|
||||
margin:1.0in 1.25in 1.0in 1.25in;
|
||||
mso-header-margin:.5in;
|
||||
mso-footer-margin:.5in;
|
||||
mso-paper-source:0;}
|
||||
div.Section1
|
||||
{page:Section1;}
|
||||
-->
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body lang=EN-US style='tab-interval:.5in'>
|
||||
|
||||
<div class=Section1>
|
||||
|
||||
<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
|
||||
</p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
|
||||
THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
|
||||
REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
|
||||
OF THIS AGREEMENT.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
in the case of the initial Contributor, the initial code and documentation
|
||||
distributed under this Agreement, and<br clear=left>
|
||||
b) in the case of each subsequent Contributor:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
changes to the Program, and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
additions to the Program;</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
|
||||
such changes and/or additions to the Program originate from and are distributed
|
||||
by that particular Contributor. A Contribution 'originates' from a Contributor
|
||||
if it was added to the Program by such Contributor itself or anyone acting on
|
||||
such Contributor's behalf. Contributions do not include additions to the
|
||||
Program which: (i) are separate modules of software distributed in conjunction
|
||||
with the Program under their own license agreement, and (ii) are not derivative
|
||||
works of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contributor" means any person or
|
||||
entity that distributes the Program.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
|
||||
claims licensable by a Contributor which are necessarily infringed by the use
|
||||
or sale of its Contribution alone or when combined with the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Program" means the Contributions
|
||||
distributed in accordance with this Agreement.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Recipient" means anyone who
|
||||
receives the Program under this Agreement, including all Contributors.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants Recipient
|
||||
a non-exclusive, worldwide, royalty-free copyright license to<span
|
||||
style='color:red'> </span>reproduce, prepare derivative works of, publicly
|
||||
display, publicly perform, distribute and sublicense the Contribution of such
|
||||
Contributor, if any, and such derivative works, in source code and object code
|
||||
form.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
|
||||
patent license under Licensed Patents to make, use, sell, offer to sell, import
|
||||
and otherwise transfer the Contribution of such Contributor, if any, in source
|
||||
code and object code form. This patent license shall apply to the combination
|
||||
of the Contribution and the Program if, at the time the Contribution is added
|
||||
by the Contributor, such addition of the Contribution causes such combination
|
||||
to be covered by the Licensed Patents. The patent license shall not apply to
|
||||
any other combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder. </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
|
||||
Recipient understands that although each Contributor grants the licenses to its
|
||||
Contributions set forth herein, no assurances are provided by any Contributor
|
||||
that the Program does not infringe the patent or other intellectual property
|
||||
rights of any other entity. Each Contributor disclaims any liability to Recipient
|
||||
for claims brought by any other entity based on infringement of intellectual
|
||||
property rights or otherwise. As a condition to exercising the rights and
|
||||
licenses granted hereunder, each Recipient hereby assumes sole responsibility
|
||||
to secure any other intellectual property rights needed, if any. For example,
|
||||
if a third party patent license is required to allow Recipient to distribute
|
||||
the Program, it is Recipient's responsibility to acquire that license before
|
||||
distributing the Program.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
|
||||
Each Contributor represents that to its knowledge it has sufficient copyright
|
||||
rights in its Contribution, if any, to grant the copyright license set forth in
|
||||
this Agreement. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
|
||||
Program in object code form under its own license agreement, provided that:</span>
|
||||
</p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it complies with the terms and conditions of this Agreement; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
its license agreement:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
effectively disclaims on behalf of all Contributors all warranties and
|
||||
conditions, express and implied, including warranties or conditions of title
|
||||
and non-infringement, and implied warranties or conditions of merchantability
|
||||
and fitness for a particular purpose; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
effectively excludes on behalf of all Contributors all liability for damages,
|
||||
including direct, indirect, special, incidental and consequential damages, such
|
||||
as lost profits; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
|
||||
states that any provisions which differ from this Agreement are offered by that
|
||||
Contributor alone and not by any other party; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
|
||||
states that source code for the Program is available from such Contributor, and
|
||||
informs licensees how to obtain it in a reasonable manner on or through a
|
||||
medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>When the Program is made available in source
|
||||
code form:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it must be made available under this Agreement; and </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
|
||||
copy of this Agreement must be included with each copy of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
|
||||
copyright notices contained within the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
|
||||
originator of its Contribution, if any, in a manner that reasonably allows
|
||||
subsequent Recipients to identify the originator of the Contribution. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Commercial distributors of software may
|
||||
accept certain responsibilities with respect to end users, business partners
|
||||
and the like. While this license is intended to facilitate the commercial use
|
||||
of the Program, the Contributor who includes the Program in a commercial
|
||||
product offering should do so in a manner which does not create potential
|
||||
liability for other Contributors. Therefore, if a Contributor includes the
|
||||
Program in a commercial product offering, such Contributor ("Commercial
|
||||
Contributor") hereby agrees to defend and indemnify every other
|
||||
Contributor ("Indemnified Contributor") against any losses, damages and
|
||||
costs (collectively "Losses") arising from claims, lawsuits and other
|
||||
legal actions brought by a third party against the Indemnified Contributor to
|
||||
the extent caused by the acts or omissions of such Commercial Contributor in
|
||||
connection with its distribution of the Program in a commercial product
|
||||
offering. The obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In order
|
||||
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
|
||||
Contributor in writing of such claim, and b) allow the Commercial Contributor
|
||||
to control, and cooperate with the Commercial Contributor in, the defense and
|
||||
any related settlement negotiations. The Indemnified Contributor may participate
|
||||
in any such claim at its own expense.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>For example, a Contributor might include the
|
||||
Program in a commercial product offering, Product X. That Contributor is then a
|
||||
Commercial Contributor. If that Commercial Contributor then makes performance
|
||||
claims, or offers warranties related to Product X, those performance claims and
|
||||
warranties are such Commercial Contributor's responsibility alone. Under this
|
||||
section, the Commercial Contributor would have to defend claims against the
|
||||
other Contributors related to those performance claims and warranties, and if a
|
||||
court requires any other Contributor to pay any damages as a result, the
|
||||
Commercial Contributor must pay those damages.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
|
||||
WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and distributing the
|
||||
Program and assumes all risks associated with its exercise of rights under this
|
||||
Agreement , including but not limited to the risks and costs of program errors,
|
||||
compliance with applicable laws, damage to or loss of data, programs or
|
||||
equipment, and unavailability or interruption of operations. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
|
||||
THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
|
||||
or unenforceable under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this Agreement, and without
|
||||
further action by the parties hereto, such provision shall be reformed to the
|
||||
minimum extent necessary to make such provision valid and enforceable.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
|
||||
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
||||
alleging that the Program itself (excluding combinations of the Program with
|
||||
other software or hardware) infringes such Recipient's patent(s), then such
|
||||
Recipient's rights granted under Section 2(b) shall terminate as of the date
|
||||
such litigation is filed. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
|
||||
shall terminate if it fails to comply with any of the material terms or
|
||||
conditions of this Agreement and does not cure such failure in a reasonable
|
||||
period of time after becoming aware of such noncompliance. If all Recipient's
|
||||
rights under this Agreement terminate, Recipient agrees to cease use and
|
||||
distribution of the Program as soon as reasonably practicable. However,
|
||||
Recipient's obligations under this Agreement and any licenses granted by
|
||||
Recipient relating to the Program shall continue and survive. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
|
||||
copies of this Agreement, but in order to avoid inconsistency the Agreement is
|
||||
copyrighted and may only be modified in the following manner. The Agreement
|
||||
Steward reserves the right to publish new versions (including revisions) of
|
||||
this Agreement from time to time. No one other than the Agreement Steward has
|
||||
the right to modify this Agreement. The Eclipse Foundation is the initial
|
||||
Agreement Steward. The Eclipse Foundation may assign the responsibility to
|
||||
serve as the Agreement Steward to a suitable separate entity. Each new version
|
||||
of the Agreement will be given a distinguishing version number. The Program
|
||||
(including Contributions) may always be distributed subject to the version of
|
||||
the Agreement under which it was received. In addition, after a new version of
|
||||
the Agreement is published, Contributor may elect to distribute the Program
|
||||
(including its Contributions) under the new version. Except as expressly stated
|
||||
in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
|
||||
the intellectual property of any Contributor under this Agreement, whether
|
||||
expressly, by implication, estoppel or otherwise. All rights in the Program not
|
||||
expressly granted under this Agreement are reserved.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
|
||||
State of New York and the intellectual property laws of the United States of
|
||||
America. No party to this Agreement will bring a legal action under this
|
||||
Agreement more than one year after the cause of action arose. Each party waives
|
||||
its rights to a jury trial in any resulting litigation.</span> </p>
|
||||
|
||||
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
8
xCAT-nbroot/mkrpm
Executable file
8
xCAT-nbroot/mkrpm
Executable file
@ -0,0 +1,8 @@
|
||||
cd `dirname $0`
|
||||
tar --exclude .svn -czvf xcat-nbrootoverlay.tar.gz -C overlay/ .
|
||||
cp *.gz /usr/src/redhat/SOURCES
|
||||
cp xcat-core-nbroot.spec /usr/src/redhat/SPECS
|
||||
rm xcat-nbrootoverlay.tar.gz
|
||||
rpmbuild -ba /usr/src/redhat/SPECS/xcat-core-nbroot.spec --target $1
|
||||
cd -
|
||||
|
28
xCAT-nbroot/overlay/bin/bmcsetup
Executable file
28
xCAT-nbroot/overlay/bin/bmcsetup
Executable file
@ -0,0 +1,28 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
modprobe ipmi_si
|
||||
modprobe ipmi_devintf
|
||||
while ! getipmi.awk
|
||||
do
|
||||
echo "Retrying retrieval of IPMI settings from server"
|
||||
done
|
||||
BMCIP=`grep bmcip /tmp/ipmi.data |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
|
||||
BMCGW=`grep gateway /tmp/ipmi.data |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
|
||||
BMCNM=`grep netmask /tmp/ipmi.data |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
|
||||
BMCUS=`grep username /tmp/ipmi.data |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
|
||||
BMCPW=`grep password /tmp/ipmi.data |awk -F\> '{print $2}'|awk -F\< '{print $1}'`
|
||||
ipmitool lan set 1 ipsrc static
|
||||
ipmitool lan set 1 ipaddr $BMCIP
|
||||
ipmitool lan set 1 netmask $BMCNM
|
||||
if [ ! -z "$BMCGW" ]; then
|
||||
ipmitool lan set 1 defgw ipaddr $BMCGW
|
||||
fi
|
||||
ipmitool user disable 1
|
||||
ipmitool user disable 3
|
||||
ipmitool user disable 4
|
||||
ipmitool user enable 2
|
||||
ipmitool user priv 2 4 1
|
||||
ipmitool user set name 2 $BMCUS
|
||||
ipmitool user set password 2 $BMCPW
|
||||
echo "Set up following user table: "
|
||||
ipmitool user list 1
|
||||
|
113
xCAT-nbroot/overlay/bin/dodestiny
Executable file
113
xCAT-nbroot/overlay/bin/dodestiny
Executable file
@ -0,0 +1,113 @@
|
||||
#!/bin/sh
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
for parm in `cat /proc/cmdline`; do
|
||||
key=`echo $parm|awk -F= '{print $1}'`
|
||||
if [ "$key" == "xcatd" ]; then
|
||||
XCATDEST=`echo $parm|awk -F= '{print $2}'`
|
||||
fi
|
||||
done
|
||||
export XCATMASTER=`echo $XCATDEST | awk -F: '{print $1}'`
|
||||
export XCATPORT=`echo $XCATDEST | awk -F: '{print $2}'`
|
||||
|
||||
|
||||
while :; do
|
||||
DESTINY=`grep destiny /tmp/destiny | awk -F'>' '{print $2}'|awk -F'<' '{print $1}'`
|
||||
DEST=`echo $DESTINY|awk -F= '{print $1}'` #No bash, no tricks
|
||||
TARG=`echo $DESTINY|awk -F= '{print $2}'` #No bash, no tricks
|
||||
DESTINY=`echo $DESTINY|awk '{print $1}'` #No bash, no tricks
|
||||
if [ $DESTINY == "standby" ]; then
|
||||
echo "Server notified us of standby condition, please check chain table".
|
||||
echo "Retrying destiny in 15 seconds"
|
||||
usleep 15000000 # something may be transiently wrong, check back in 15 seconds
|
||||
while ! getdestiny.awk; do
|
||||
echo "Retrying destiny retrieval"
|
||||
done
|
||||
exec $0
|
||||
fi
|
||||
if [ $DESTINY == "shell" ]; then
|
||||
echo "Server notified us to stay in shell state, stopping destiny requests"
|
||||
exit
|
||||
fi
|
||||
if [ $DESTINY == "discover" ]; then
|
||||
echo "MAC discovery begins"
|
||||
minixcatd.awk &
|
||||
while [ ! -r /restart ]; do
|
||||
ifconfig -a|grep HWaddr|grep -v sit|awk '{print $1 "|" $5}'
|
||||
MTM="unknown"
|
||||
SERIAL="unknown"
|
||||
if [ -x /bin/vpddecode ]; then
|
||||
MTM=`(/bin/vpddecode|grep Type || echo "unknown unknown: unknown")|awk '{print $3}'`
|
||||
SERIAL=`(/bin/vpddecode|grep "Box Serial" || echo "unknown unknown unknown: unknown")|awk '{print $4}'`
|
||||
fi
|
||||
if [ "$MTM" == "unknown" -a -x /bin/dmidecode ]; then #This gets a bit hackish... iDataplex
|
||||
MTM=`dmidecode |grep -A4 "^System Information"|grep "Product Name"|awk -F'[' '{print $2}'|awk -F']' '{print $1}'`
|
||||
SERIAL=`dmidecode |grep -A4 "^System Information"|grep "Serial Number"|awk -F: '{print $2}'`
|
||||
fi
|
||||
if [ -r /proc/device-tree/model ]; then
|
||||
MTM=`cat /proc/device-tree/model |awk -F, '{print $2}'`
|
||||
fi
|
||||
(
|
||||
echo "<xcatrequest>"
|
||||
echo "<command>findme</command>"
|
||||
echo "<arch>"`uname -m`"</arch>"
|
||||
for i in `ifconfig -a|grep HWaddr|grep -v sit|awk '{print $1 "|" $5}'`; do
|
||||
IFACE=`echo $i|awk -F'|' '{print $1}'`
|
||||
DRIVER=`ethtool -i $IFACE|grep ^driver|awk '{print $2}'`
|
||||
echo "<mac>$DRIVER|$i</mac>"
|
||||
done
|
||||
modprobe ipmi_devintf
|
||||
if modprobe ipmi_si; then
|
||||
echo "<mac>bmc|bmc|"`ipmitool lan print 1|grep ^MAC|awk '{print $4}'`"</mac>"
|
||||
fi
|
||||
rmmod ipmi_si
|
||||
rmmod ipmi_devintf
|
||||
if [ "$MTM" != "unknown" ]; then
|
||||
echo "<mtm>$MTM</mtm>"
|
||||
fi
|
||||
if [ "$SERIAL" != "unknown" ]; then
|
||||
echo "<serial>$SERIAL</serial>"
|
||||
fi
|
||||
echo "</xcatrequest>" )| udpcat.awk $XCATMASTER $XCATPORT
|
||||
usleep 30000000
|
||||
done
|
||||
#Discovery complete, restart requested.
|
||||
exec /bin/restart
|
||||
fi
|
||||
if [ $DESTINY == "reboot" ]; then
|
||||
while ! nextdestiny.awk ; do
|
||||
echo "Retrying next destiny..."
|
||||
done
|
||||
reboot -f
|
||||
fi
|
||||
if [ $DEST == "runcmd" ]; then
|
||||
while ! nextdestiny.awk ; do
|
||||
echo "Retrying next destiny..."
|
||||
done
|
||||
$TARG
|
||||
fi
|
||||
if [ $DESTINY == "install" -o $DESTINY == "netboot" ]; then
|
||||
IMGSERVER=`grep imgserver /tmp/destiny | awk -F'>' '{print $2}'|awk -F'<' '{print $1}'`
|
||||
INITRD=`grep initrd /tmp/destiny | awk -F'>' '{print $2}'|awk -F'<' '{print $1}'`
|
||||
KERNEL=`grep kernel /tmp/destiny | awk -F'>' '{print $2}'|awk -F'<' '{print $1}'`
|
||||
KCMD=`grep kcmdline /tmp/destiny | awk -F'>' '{print $2}'|awk -F'<' '{print $1}'`
|
||||
wget http://$IMGSERVER/tftpboot/$KERNEL -O /tmp/kernel
|
||||
wget http://$IMGSERVER/tftpboot/$INITRD -O /tmp/initrd
|
||||
#START getting ready for kexec
|
||||
for mod in `lsmod|awk '{print $1}'|grep -v Module`; do
|
||||
rmmod $mod
|
||||
done
|
||||
kexec -f --append="$KCMD" --initrd=/tmp/initrd /tmp/kernel
|
||||
reboot -f #If script is here, kexec failed, reboot in case it wasn't a linux kernel and let the boot loader handle it instead
|
||||
fi
|
||||
if [ $DEST == "runimage" ]; then
|
||||
mkdir /tmp/$TARG
|
||||
cd /tmp/$TARG
|
||||
wget $TARG
|
||||
while ! nextdestiny.awk ; do
|
||||
echo "Retrying next destiny..."
|
||||
done
|
||||
tar zxvf $TARG
|
||||
/tmp/$TARG/runme.sh
|
||||
cd -
|
||||
fi
|
||||
done
|
22
xCAT-nbroot/overlay/bin/getdestiny.awk
Executable file
22
xCAT-nbroot/overlay/bin/getdestiny.awk
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/awk -f
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
BEGIN {
|
||||
ns = "/inet/tcp/0/127.0.0.1/301"
|
||||
|
||||
print "<xcatrequest>" |& ns
|
||||
print "<command>getdestiny</command>" |& ns
|
||||
print "</xcatrequest>" |& ns
|
||||
|
||||
while (1) {
|
||||
if ((ns |& getline) > 0) {
|
||||
print $0 > "/tmp/destiny"
|
||||
if ($0 == "</xcatresponse>")
|
||||
break
|
||||
} else { #Timeout
|
||||
close(ns)
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
close(ns)
|
||||
exit 0
|
||||
}
|
22
xCAT-nbroot/overlay/bin/getipmi.awk
Executable file
22
xCAT-nbroot/overlay/bin/getipmi.awk
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/awk -f
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
BEGIN {
|
||||
ns = "/inet/tcp/0/127.0.0.1/301"
|
||||
|
||||
print "<xcatrequest>" |& ns
|
||||
print "<command>getbmcconfig</command>" |& ns
|
||||
print "</xcatrequest>" |& ns
|
||||
|
||||
while (1) {
|
||||
if ((ns |& getline) > 0) {
|
||||
print $0 > "/tmp/ipmi.data"
|
||||
if ($0 == "</xcatresponse>")
|
||||
break
|
||||
} else {
|
||||
close(ns)
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
close(ns)
|
||||
exit 0
|
||||
}
|
20
xCAT-nbroot/overlay/bin/minixcatd.awk
Executable file
20
xCAT-nbroot/overlay/bin/minixcatd.awk
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/awk -f
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
BEGIN {
|
||||
port = 3001
|
||||
listener = "/inet/tcp/" port "/0/0"
|
||||
quit = "no"
|
||||
while (match(quit,"no")) {
|
||||
print quit;
|
||||
while (match(quit,"no") && (listener |& getline) > 0) {
|
||||
if (match($0,"restart")) {
|
||||
print "restarting bootstrap process" |& listener
|
||||
quit="yes"
|
||||
system("touch /restart")
|
||||
system("killall usleep")
|
||||
close(listener)
|
||||
}
|
||||
}
|
||||
close(listener)
|
||||
}
|
||||
}
|
22
xCAT-nbroot/overlay/bin/nextdestiny.awk
Executable file
22
xCAT-nbroot/overlay/bin/nextdestiny.awk
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/awk -f
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
BEGIN {
|
||||
ns = "/inet/tcp/0/127.0.0.1/301"
|
||||
|
||||
print "<xcatrequest>" |& ns
|
||||
print "<command>nextdestiny</command>" |& ns
|
||||
print "</xcatrequest>" |& ns
|
||||
|
||||
while (1) {
|
||||
if ((ns |& getline) > 0) {
|
||||
print $0 > "/tmp/destiny"
|
||||
if ($0 == "</xcatresponse>")
|
||||
break
|
||||
} else {
|
||||
close(ns)
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
close(ns)
|
||||
exit 0
|
||||
}
|
6
xCAT-nbroot/overlay/bin/restart
Executable file
6
xCAT-nbroot/overlay/bin/restart
Executable file
@ -0,0 +1,6 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#Redhcp, do the xcat part again
|
||||
rm /restart
|
||||
killall -12 udhcpc;killall -10 udhcpc
|
||||
sleep 5
|
||||
/etc/init.d/S99xcat
|
12
xCAT-nbroot/overlay/bin/udpcat.awk
Executable file
12
xCAT-nbroot/overlay/bin/udpcat.awk
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/awk -f
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
BEGIN {
|
||||
xcatdport = ARGV[2]
|
||||
xcatdhost = ARGV[1]
|
||||
delete ARGV[1]
|
||||
delete ARGV[2]
|
||||
RS=""
|
||||
}
|
||||
END {
|
||||
print $0 |& "/inet/udp/301/"xcatdhost"/"xcatdport
|
||||
}
|
66
xCAT-nbroot/overlay/etc/init.d/S10autodetect
Executable file
66
xCAT-nbroot/overlay/etc/init.d/S10autodetect
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
nic=0
|
||||
hba=0
|
||||
|
||||
MOD=""
|
||||
|
||||
#Load common usb drivers
|
||||
modprobe ohci-hcd
|
||||
modprobe uhci-hcd
|
||||
modprobe ehci-hcd
|
||||
for i in $(lspci -n | awk '{print $1 "%" $3}')
|
||||
do
|
||||
PCI=$(echo $i | awk -F% '{print $1}')
|
||||
VID="0x0000$(echo $i | awk -F% '{print $2}' |awk -F: '{print $1}')"
|
||||
DID="0x0000$(echo $i | awk -F% '{print $2}' |awk -F: '{print $2}')"
|
||||
if egrep "^[^ ]*[ ]*$VID[ ]*$DID" /lib/modules/*/modules.pcimap >/dev/null
|
||||
then
|
||||
TYPE=$(
|
||||
lspci | \
|
||||
grep "^$PCI " | \
|
||||
awk '{print $2}' | \
|
||||
tr '[A-Z]' '[a-z]'
|
||||
)
|
||||
DESC=$(
|
||||
lspci | \
|
||||
grep "^$PCI " | \
|
||||
awk -F: '{print $3}' | \
|
||||
sed 's/^ *//'
|
||||
)
|
||||
MOD=$(
|
||||
egrep "^[^ ]*[ ]*$VID[ ]*$DID" /lib/modules/*/modules.pcimap | \
|
||||
head -1 | \
|
||||
awk '{print $1}' | \
|
||||
tr -d '"'
|
||||
)
|
||||
case "$TYPE" in
|
||||
ethernet|network)
|
||||
echo "Found ($MOD) $DESC"
|
||||
GOTNIC=1
|
||||
if [ "$MOD" = "gm" ]
|
||||
then
|
||||
echo "alias myri0 $MOD"
|
||||
echo "alias myri0 $MOD" >>/etc/modules.conf
|
||||
echo "alias myri0 $MOD" >>/etc/modprobe.conf
|
||||
else
|
||||
modprobe $MOD
|
||||
udhcpc -i eth$nic -b
|
||||
nic=$(($nic + 1))
|
||||
fi
|
||||
;;
|
||||
scsi|raid)
|
||||
echo "Found ($MOD) $DESC"
|
||||
GOTHBA=1
|
||||
modprobe $MOD
|
||||
modprobe sd_mod
|
||||
modprobe scsi_mod
|
||||
hba=$(($hba + 1))
|
||||
;;
|
||||
*)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
|
19
xCAT-nbroot/overlay/etc/init.d/S11stunnel
Executable file
19
xCAT-nbroot/overlay/etc/init.d/S11stunnel
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#Stunnel init for xcat:
|
||||
XCATDEST=""
|
||||
for parm in `cat /proc/cmdline`; do
|
||||
key=`echo $parm|awk -F= '{print $1}'`
|
||||
if [ "$key" == "xcatd" ]; then
|
||||
XCATDEST=`echo $parm|awk -F= '{print $2}'`
|
||||
fi
|
||||
done
|
||||
mkdir -p /etc/stunnel
|
||||
echo 'client=yes' > /etc/stunnel/stunnel.conf
|
||||
echo 'foreground=yes' >> /etc/stunnel/stunnel.conf
|
||||
echo 'verify=0' >> /etc/stunnel/stunnel.conf
|
||||
echo '[xcatds]' >> /etc/stunnel/stunnel.conf
|
||||
echo 'accept=301' >> /etc/stunnel/stunnel.conf
|
||||
echo 'connect='$XCATDEST >> /etc/stunnel/stunnel.conf
|
||||
mkdir -p /usr/var/run/stunnel
|
||||
stunnel &
|
2
xCAT-nbroot/overlay/etc/init.d/S40network
Normal file
2
xCAT-nbroot/overlay/etc/init.d/S40network
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exit
|
9
xCAT-nbroot/overlay/etc/init.d/S99xcat
Executable file
9
xCAT-nbroot/overlay/etc/init.d/S99xcat
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
(
|
||||
while ! /bin/getdestiny.awk
|
||||
do
|
||||
echo "Retrying destiny retrieval"
|
||||
done
|
||||
/bin/dodestiny
|
||||
) &
|
54
xCAT-nbroot/overlay/etc/inittab
Normal file
54
xCAT-nbroot/overlay/etc/inittab
Normal file
@ -0,0 +1,54 @@
|
||||
# /etc/inittab
|
||||
#
|
||||
# Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
|
||||
#
|
||||
# Note: BusyBox init doesn't support runlevels. The runlevels field is
|
||||
# completely ignored by BusyBox init. If you want runlevels, use
|
||||
# sysvinit.
|
||||
#
|
||||
# Format for each entry: <id>:<runlevels>:<action>:<process>
|
||||
#
|
||||
# id == tty to run on, or empty for /dev/console
|
||||
# runlevels == ignored
|
||||
# action == one of sysinit, respawn, askfirst, wait, and once
|
||||
# process == program to run
|
||||
|
||||
# Startup the system
|
||||
::sysinit:/bin/mount -t proc none /proc
|
||||
::sysinit:/bin/mount -t sysfs none /sys
|
||||
::sysinit:/bin/mount -t tmpfs -o size=64k,mode=0755 none /dev
|
||||
::sysinit:/bin/mkdir /dev/pts
|
||||
::sysinit:/bin/mount -t devpts devpts /dev/pts
|
||||
::sysinit:/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
|
||||
::sysinit:/sbin/mdev -s
|
||||
::sysinit:/bin/mount -o remount,rw /
|
||||
::sysinit:/bin/mount -a
|
||||
::sysinit:/bin/hostname -F /etc/hostname
|
||||
::sysinit:/sbin/ifconfig lo 127.0.0.1 up
|
||||
::sysinit:/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo
|
||||
# now run any rc scripts
|
||||
::sysinit:/etc/init.d/rcS
|
||||
|
||||
# Set up a couple of getty's
|
||||
#console::respawn:/sbin/getty 19200 console
|
||||
tty1::respawn:/sbin/getty 38400 tty1
|
||||
tty2::respawn:/sbin/getty 38400 tty2
|
||||
|
||||
# Put a getty on the serial port
|
||||
#ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100
|
||||
|
||||
# Logging junk
|
||||
null::sysinit:/bin/touch /var/log/messages
|
||||
#null::respawn:/sbin/syslogd -n
|
||||
#null::respawn:/sbin/klogd -n
|
||||
#tty3::respawn:/usr/bin/tail -f /var/log/messages
|
||||
|
||||
# Stuff to do for the 3-finger salute
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
|
||||
# Stuff to do before rebooting
|
||||
null::shutdown:/usr/bin/killall klogd
|
||||
null::shutdown:/usr/bin/killall syslogd
|
||||
null::shutdown:/bin/umount -a -r
|
||||
null::shutdown:/sbin/swapoff -a
|
||||
|
0
xCAT-nbroot/overlay/etc/profile
Normal file
0
xCAT-nbroot/overlay/etc/profile
Normal file
26
xCAT-nbroot/overlay/usr/share/udhcpc/default.script
Executable file
26
xCAT-nbroot/overlay/usr/share/udhcpc/default.script
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
case $1 in
|
||||
deconfig)
|
||||
/sbin/ifconfig $interface up
|
||||
/sbin/ifconfig $interface 0.0.0.0
|
||||
;;
|
||||
bound|renew)
|
||||
/sbin/ifconfig $interface $ip netmask $subnet
|
||||
if [ -n "$router" ] ; then
|
||||
echo "deleting routers"
|
||||
while route del default gw 0.0.0.0 dev $interface ; do
|
||||
:
|
||||
done
|
||||
|
||||
for i in $router ; do
|
||||
route add default gw $i dev $interface
|
||||
done
|
||||
fi
|
||||
echo -n > /etc/resolv.conf
|
||||
[ -n "$domain" ] && echo search $domain >> /etc/resolv.conf
|
||||
for i in $dns ; do
|
||||
echo adding dns $i
|
||||
echo nameserver $i >> /etc/resolv.conf
|
||||
done
|
||||
;;
|
||||
esac
|
56
xCAT-nbroot/xcat-core-nbroot.spec
Normal file
56
xCAT-nbroot/xcat-core-nbroot.spec
Normal file
@ -0,0 +1,56 @@
|
||||
%define epoch 0
|
||||
%define version 2.0
|
||||
%ifarch i386 i586 i686
|
||||
%define tarch x86
|
||||
%endif
|
||||
%ifarch x86_64
|
||||
%define tarch x86_64
|
||||
%endif
|
||||
%ifarch ppc ppc64
|
||||
%define tarch ppc64
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
%define name xCAT-nbroot-core-%{tarch}
|
||||
Release: snap%(date +"%Y%m%d%H%M")
|
||||
AutoReq: false
|
||||
AutoProv: false
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Name: %{name}
|
||||
#Epoch: %{epoch}
|
||||
Version: %{version}
|
||||
Group: System/Utilities
|
||||
License: EPL
|
||||
Vendor: IBM Corp.
|
||||
Summary: xCAT-nbroot-coreprovides opensource components of the netboot image
|
||||
URL: http://xcat.org
|
||||
Source1: xcat-nbrootoverlay.tar.gz
|
||||
|
||||
Buildroot: %{_localstatedir}/tmp/xCAT-nbroot-core
|
||||
Packager: IBM Corp.
|
||||
|
||||
%Description
|
||||
xcat-nbroot-core provides the xCAT scripts for the mini-root environment
|
||||
All files included are as they were downloadable on 4/7/2007
|
||||
%Prep
|
||||
|
||||
|
||||
%Build
|
||||
|
||||
%Install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/xcat/netboot/%{tarch}/nbroot
|
||||
cd $RPM_BUILD_ROOT/usr/share/xcat/netboot/%{tarch}/nbroot
|
||||
tar zxvf %{SOURCE1}
|
||||
cd -
|
||||
|
||||
|
||||
|
||||
%Files
|
||||
%defattr(-,root,root)
|
||||
%doc LICENSE.html
|
||||
/
|
326
xCAT-server-2.0/LICENSE.html
Normal file
326
xCAT-server-2.0/LICENSE.html
Normal file
@ -0,0 +1,326 @@
|
||||
<html xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||||
<meta name=ProgId content=Word.Document>
|
||||
<meta name=Generator content="Microsoft Word 9">
|
||||
<meta name=Originator content="Microsoft Word 9">
|
||||
<title>Eclipse Public License - Version 1.0</title>
|
||||
<!--[if gte mso 9]><xml>
|
||||
<o:DocumentProperties>
|
||||
<o:Revision>2</o:Revision>
|
||||
<o:TotalTime>3</o:TotalTime>
|
||||
<o:Created>2004-03-05T23:03:00Z</o:Created>
|
||||
<o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
|
||||
<o:Pages>4</o:Pages>
|
||||
<o:Words>1626</o:Words>
|
||||
<o:Characters>9270</o:Characters>
|
||||
<o:Lines>77</o:Lines>
|
||||
<o:Paragraphs>18</o:Paragraphs>
|
||||
<o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
|
||||
<o:Version>9.4402</o:Version>
|
||||
</o:DocumentProperties>
|
||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||
<w:WordDocument>
|
||||
<w:TrackRevisions/>
|
||||
</w:WordDocument>
|
||||
</xml><![endif]-->
|
||||
<style>
|
||||
<!--
|
||||
/* Font Definitions */
|
||||
@font-face
|
||||
{font-family:Tahoma;
|
||||
panose-1:2 11 6 4 3 5 4 4 2 4;
|
||||
mso-font-charset:0;
|
||||
mso-generic-font-family:swiss;
|
||||
mso-font-pitch:variable;
|
||||
mso-font-signature:553679495 -2147483648 8 0 66047 0;}
|
||||
/* Style Definitions */
|
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||||
{mso-style-parent:"";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p
|
||||
{margin-right:0in;
|
||||
mso-margin-top-alt:auto;
|
||||
mso-margin-bottom-alt:auto;
|
||||
margin-left:0in;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p.BalloonText, li.BalloonText, div.BalloonText
|
||||
{mso-style-name:"Balloon Text";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:8.0pt;
|
||||
font-family:Tahoma;
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
@page Section1
|
||||
{size:8.5in 11.0in;
|
||||
margin:1.0in 1.25in 1.0in 1.25in;
|
||||
mso-header-margin:.5in;
|
||||
mso-footer-margin:.5in;
|
||||
mso-paper-source:0;}
|
||||
div.Section1
|
||||
{page:Section1;}
|
||||
-->
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body lang=EN-US style='tab-interval:.5in'>
|
||||
|
||||
<div class=Section1>
|
||||
|
||||
<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
|
||||
</p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
|
||||
THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
|
||||
REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
|
||||
OF THIS AGREEMENT.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
in the case of the initial Contributor, the initial code and documentation
|
||||
distributed under this Agreement, and<br clear=left>
|
||||
b) in the case of each subsequent Contributor:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
changes to the Program, and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
additions to the Program;</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
|
||||
such changes and/or additions to the Program originate from and are distributed
|
||||
by that particular Contributor. A Contribution 'originates' from a Contributor
|
||||
if it was added to the Program by such Contributor itself or anyone acting on
|
||||
such Contributor's behalf. Contributions do not include additions to the
|
||||
Program which: (i) are separate modules of software distributed in conjunction
|
||||
with the Program under their own license agreement, and (ii) are not derivative
|
||||
works of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Contributor" means any person or
|
||||
entity that distributes the Program.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
|
||||
claims licensable by a Contributor which are necessarily infringed by the use
|
||||
or sale of its Contribution alone or when combined with the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Program" means the Contributions
|
||||
distributed in accordance with this Agreement.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Recipient" means anyone who
|
||||
receives the Program under this Agreement, including all Contributors.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants Recipient
|
||||
a non-exclusive, worldwide, royalty-free copyright license to<span
|
||||
style='color:red'> </span>reproduce, prepare derivative works of, publicly
|
||||
display, publicly perform, distribute and sublicense the Contribution of such
|
||||
Contributor, if any, and such derivative works, in source code and object code
|
||||
form.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
|
||||
patent license under Licensed Patents to make, use, sell, offer to sell, import
|
||||
and otherwise transfer the Contribution of such Contributor, if any, in source
|
||||
code and object code form. This patent license shall apply to the combination
|
||||
of the Contribution and the Program if, at the time the Contribution is added
|
||||
by the Contributor, such addition of the Contribution causes such combination
|
||||
to be covered by the Licensed Patents. The patent license shall not apply to
|
||||
any other combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder. </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
|
||||
Recipient understands that although each Contributor grants the licenses to its
|
||||
Contributions set forth herein, no assurances are provided by any Contributor
|
||||
that the Program does not infringe the patent or other intellectual property
|
||||
rights of any other entity. Each Contributor disclaims any liability to Recipient
|
||||
for claims brought by any other entity based on infringement of intellectual
|
||||
property rights or otherwise. As a condition to exercising the rights and
|
||||
licenses granted hereunder, each Recipient hereby assumes sole responsibility
|
||||
to secure any other intellectual property rights needed, if any. For example,
|
||||
if a third party patent license is required to allow Recipient to distribute
|
||||
the Program, it is Recipient's responsibility to acquire that license before
|
||||
distributing the Program.</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
|
||||
Each Contributor represents that to its knowledge it has sufficient copyright
|
||||
rights in its Contribution, if any, to grant the copyright license set forth in
|
||||
this Agreement. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
|
||||
Program in object code form under its own license agreement, provided that:</span>
|
||||
</p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it complies with the terms and conditions of this Agreement; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
|
||||
its license agreement:</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
|
||||
effectively disclaims on behalf of all Contributors all warranties and
|
||||
conditions, express and implied, including warranties or conditions of title
|
||||
and non-infringement, and implied warranties or conditions of merchantability
|
||||
and fitness for a particular purpose; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
|
||||
effectively excludes on behalf of all Contributors all liability for damages,
|
||||
including direct, indirect, special, incidental and consequential damages, such
|
||||
as lost profits; </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
|
||||
states that any provisions which differ from this Agreement are offered by that
|
||||
Contributor alone and not by any other party; and</span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
|
||||
states that source code for the Program is available from such Contributor, and
|
||||
informs licensees how to obtain it in a reasonable manner on or through a
|
||||
medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>When the Program is made available in source
|
||||
code form:</span> </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
|
||||
it must be made available under this Agreement; and </span></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
|
||||
copy of this Agreement must be included with each copy of the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
|
||||
copyright notices contained within the Program. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
|
||||
originator of its Contribution, if any, in a manner that reasonably allows
|
||||
subsequent Recipients to identify the originator of the Contribution. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Commercial distributors of software may
|
||||
accept certain responsibilities with respect to end users, business partners
|
||||
and the like. While this license is intended to facilitate the commercial use
|
||||
of the Program, the Contributor who includes the Program in a commercial
|
||||
product offering should do so in a manner which does not create potential
|
||||
liability for other Contributors. Therefore, if a Contributor includes the
|
||||
Program in a commercial product offering, such Contributor ("Commercial
|
||||
Contributor") hereby agrees to defend and indemnify every other
|
||||
Contributor ("Indemnified Contributor") against any losses, damages and
|
||||
costs (collectively "Losses") arising from claims, lawsuits and other
|
||||
legal actions brought by a third party against the Indemnified Contributor to
|
||||
the extent caused by the acts or omissions of such Commercial Contributor in
|
||||
connection with its distribution of the Program in a commercial product
|
||||
offering. The obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In order
|
||||
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
|
||||
Contributor in writing of such claim, and b) allow the Commercial Contributor
|
||||
to control, and cooperate with the Commercial Contributor in, the defense and
|
||||
any related settlement negotiations. The Indemnified Contributor may participate
|
||||
in any such claim at its own expense.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>For example, a Contributor might include the
|
||||
Program in a commercial product offering, Product X. That Contributor is then a
|
||||
Commercial Contributor. If that Commercial Contributor then makes performance
|
||||
claims, or offers warranties related to Product X, those performance claims and
|
||||
warranties are such Commercial Contributor's responsibility alone. Under this
|
||||
section, the Commercial Contributor would have to defend claims against the
|
||||
other Contributors related to those performance claims and warranties, and if a
|
||||
court requires any other Contributor to pay any damages as a result, the
|
||||
Commercial Contributor must pay those damages.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
|
||||
WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and distributing the
|
||||
Program and assumes all risks associated with its exercise of rights under this
|
||||
Agreement , including but not limited to the risks and costs of program errors,
|
||||
compliance with applicable laws, damage to or loss of data, programs or
|
||||
equipment, and unavailability or interruption of operations. </span></p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
|
||||
AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
|
||||
THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
|
||||
|
||||
<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
|
||||
or unenforceable under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this Agreement, and without
|
||||
further action by the parties hereto, such provision shall be reformed to the
|
||||
minimum extent necessary to make such provision valid and enforceable.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
|
||||
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
||||
alleging that the Program itself (excluding combinations of the Program with
|
||||
other software or hardware) infringes such Recipient's patent(s), then such
|
||||
Recipient's rights granted under Section 2(b) shall terminate as of the date
|
||||
such litigation is filed. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
|
||||
shall terminate if it fails to comply with any of the material terms or
|
||||
conditions of this Agreement and does not cure such failure in a reasonable
|
||||
period of time after becoming aware of such noncompliance. If all Recipient's
|
||||
rights under this Agreement terminate, Recipient agrees to cease use and
|
||||
distribution of the Program as soon as reasonably practicable. However,
|
||||
Recipient's obligations under this Agreement and any licenses granted by
|
||||
Recipient relating to the Program shall continue and survive. </span></p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
|
||||
copies of this Agreement, but in order to avoid inconsistency the Agreement is
|
||||
copyrighted and may only be modified in the following manner. The Agreement
|
||||
Steward reserves the right to publish new versions (including revisions) of
|
||||
this Agreement from time to time. No one other than the Agreement Steward has
|
||||
the right to modify this Agreement. The Eclipse Foundation is the initial
|
||||
Agreement Steward. The Eclipse Foundation may assign the responsibility to
|
||||
serve as the Agreement Steward to a suitable separate entity. Each new version
|
||||
of the Agreement will be given a distinguishing version number. The Program
|
||||
(including Contributions) may always be distributed subject to the version of
|
||||
the Agreement under which it was received. In addition, after a new version of
|
||||
the Agreement is published, Contributor may elect to distribute the Program
|
||||
(including its Contributions) under the new version. Except as expressly stated
|
||||
in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
|
||||
the intellectual property of any Contributor under this Agreement, whether
|
||||
expressly, by implication, estoppel or otherwise. All rights in the Program not
|
||||
expressly granted under this Agreement are reserved.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
|
||||
State of New York and the intellectual property laws of the United States of
|
||||
America. No party to this Agreement will bring a legal action under this
|
||||
Agreement more than one year after the cause of action arose. Each party waives
|
||||
its rights to a jury trial in any resulting litigation.</span> </p>
|
||||
|
||||
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
8
xCAT-server-2.0/README
Normal file
8
xCAT-server-2.0/README
Normal file
@ -0,0 +1,8 @@
|
||||
This is the README for xCAT - Extreme Cluster Administration Toolkit,
|
||||
Version 2.0 alpha release. xCAT is a toolkit for the deployment and administration of clusters.
|
||||
xCAT 2.0 is offered OSS under a EPL license.
|
||||
|
||||
See http://www.eclipse.org/legal/epl-v10.html for license details.
|
||||
|
||||
The xCAT 2.0 code and documentation can be downloaded from http://xcat.org.
|
||||
For support, go to http://xcat.org for instructions on joining the mailing list.
|
98
xCAT-server-2.0/etc/init.d/xcatd
Executable file
98
xCAT-server-2.0/etc/init.d/xcatd
Executable file
@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
# chkconfig: 345 85 60
|
||||
# description: xCAT management service
|
||||
# processname: xcatd
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: xcatd
|
||||
# Default-Start: 3 4 5
|
||||
# Default-stop: 0 1 2 6
|
||||
# Short-Description: xCATd
|
||||
# Description: xCAT management service
|
||||
### END INIT INFO
|
||||
|
||||
|
||||
MStatus()
|
||||
{
|
||||
ps ax|grep -v grep|grep xcatd: >& /dev/null
|
||||
if [ "$?" = "0" ]; then
|
||||
RVAL=0
|
||||
echo "xCAT service is running"
|
||||
else
|
||||
RVAL=3
|
||||
echo "xCAT service is not running"
|
||||
fi
|
||||
return $RVAL
|
||||
}
|
||||
|
||||
if [ -f /lib/lsb/init-functions ]; then
|
||||
. /lib/lsb/init-functions
|
||||
START_DAEMON=start_daemon
|
||||
STATUS=MStatus
|
||||
LOG_SUCCESS=log_success_msg
|
||||
LOG_FAILURE=log_failure_msg
|
||||
LOG_WARNING=log_warning_message
|
||||
elif [ -f /etc/init.d/functions ]; then
|
||||
echo RH
|
||||
. /etc/init.d/functions
|
||||
START_DAEMON=daemon
|
||||
STATUS=status
|
||||
LOG_SUCCESS=success
|
||||
LOG_FAILURE=failure
|
||||
LOG_WARNING=passed
|
||||
else
|
||||
echo "Error, don't know how to start on this platform"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
status)
|
||||
$STATUS
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping xCATd "
|
||||
$STATUS >& /dev/null
|
||||
if [ "$?" != "0" ]; then
|
||||
echo -n "xCATd not running, not stopping "
|
||||
$LOG_WARNING
|
||||
exit 1
|
||||
fi
|
||||
kill -TERM -`cat /var/run/xcatd.pid`
|
||||
let i=0;
|
||||
while $STATUS >& /dev/null && [ $i -lt 15 ]; do
|
||||
usleep 100000
|
||||
let i=i+1
|
||||
done
|
||||
$STATUS >& /dev/null
|
||||
if [ "$?" == "0" ]; then
|
||||
kill -KILL -`cat /var/run/xcatd.pid`
|
||||
fi
|
||||
usleep 100000
|
||||
$STATUS >& /dev/null
|
||||
if [ "$?" == "0" ]; then
|
||||
$LOG_FAILURE
|
||||
exit 1
|
||||
fi
|
||||
$LOG_SUCCESS
|
||||
rm /var/run/xcatd.pid
|
||||
;;
|
||||
start)
|
||||
$STATUS >& /dev/null
|
||||
if [ "$?" == "0" ]; then
|
||||
echo -n "xCATd already running "
|
||||
$LOG_WARNING
|
||||
exit
|
||||
fi
|
||||
echo -n "Starting xCATd "
|
||||
xcatd -p /var/run/xcatd.pid && $LOG_SUCCESS || $LOG_FAILURE
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
|
202
xCAT-server-2.0/etc/xcat/postscripts.rules
Normal file
202
xCAT-server-2.0/etc/xcat/postscripts.rules
Normal file
@ -0,0 +1,202 @@
|
||||
# Post Install Scripts
|
||||
#
|
||||
# The Post Install Scripts table is a rules-based system for determining
|
||||
# which install scripts and in what order to execute them.
|
||||
#
|
||||
# Rules and actions are formatted:
|
||||
#
|
||||
# RULE {
|
||||
# script [args]
|
||||
# script [args]
|
||||
# script [args]
|
||||
# ...
|
||||
# }
|
||||
#
|
||||
# Rules are defined as VAR=REGEX. Where VAR may be any exported
|
||||
# environmental variable, ALL, or NODERANGE (special, see below).
|
||||
#
|
||||
# Regular expressions (REGEX or regex) are a powerful way to define a match.
|
||||
# The perl regex engine is used to parse the rules. Please do not confuse
|
||||
# regex with shell expansion characters.
|
||||
#
|
||||
# e.g. compute* does NOT match anything starting with 'compute' as bash
|
||||
# would. compute.* is the correct regex for a that match. man perlre for
|
||||
# regex docs. (BTW, regex compute* matches 'comput' with 0 or more 'e's at
|
||||
# the end.)
|
||||
#
|
||||
# There is no need to place beginning and end markers (^$) in your regex.
|
||||
# They are added automatically.
|
||||
#
|
||||
# Actions are defined as: script [optional args]
|
||||
#
|
||||
# A special action/script "STOP" will stop processing all rules and exit.
|
||||
#
|
||||
# Scripts are run top-down multiples rules can match.
|
||||
#
|
||||
# Nesting with () and operators and, or, and not are supported.
|
||||
#
|
||||
# The following VARs are exported by xCAT:
|
||||
#
|
||||
# OSVER=(rh62|rh70|rh71|rh72|rh73|rh80|suse81|sles8)
|
||||
# OSVER is the OS that has just been installed. OSVER may be defined by
|
||||
# regex. (e.g. rh.* is "anything starting with rh")
|
||||
#
|
||||
# ARCH=(x86|ia64)
|
||||
# ARCH is the hardware architecture (uname -m). ARCH may be defined by
|
||||
# regex.
|
||||
#
|
||||
# NODERANGE=(e.g. node1-node10)
|
||||
# NODERANGE follows the xCAT noderange format as defined by noderange.5
|
||||
# (man noderange). Regex is supported as part of noderange, however it
|
||||
# must be prefixed with a '@', e.g. (@node.* is "anything starting with
|
||||
# node").
|
||||
#
|
||||
# ALL (Apply to all)
|
||||
#
|
||||
# TABLE:TABLENAME:KEY:FIELD=
|
||||
#
|
||||
# The last rule is special and is determined at runtime.
|
||||
#
|
||||
# TABLENAME is the name of an xCAT table located in $XCATROOT/etc. You
|
||||
# may create your own tables.
|
||||
#
|
||||
# KEY is the first field of any xCAT table. $NODE is a
|
||||
# special value for key, usually the key is a fixed name, however many xCAT
|
||||
# tables start with a node or resource group name.
|
||||
#
|
||||
# FIELD is a numeric value for fields associated with KEY. The first field
|
||||
# is 1. Special names are available (e.g. $nodehm_eth0) and are defined in
|
||||
# $XCATROOT/lib/functions. Any environmental variable can be used.
|
||||
#
|
||||
# e.g.:
|
||||
#
|
||||
# TABLE:nodehm.tab:$NODENAME:$nodehm_eth0=e1000
|
||||
#
|
||||
# Would only execute scripts where eth0 was defined as e1000 in nodehm.tab
|
||||
# for any node.
|
||||
#
|
||||
# The script $XCATROOT/bin/postage is the master post installation script
|
||||
# that parses this table and runs the scripts. You can use the script
|
||||
# $XCATROOT/bin/postrules NODENAME ARCH OSVER to parse this table to test
|
||||
# your rules.
|
||||
#
|
||||
# e.g. postrules node1 x86 rh73
|
||||
#
|
||||
|
||||
|
||||
# Setup syslog
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
syslog
|
||||
}
|
||||
|
||||
# update/add packages
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
updaterpms nodeps
|
||||
otherrpms
|
||||
forcerpms
|
||||
}
|
||||
|
||||
# setup NFS mounts
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
nfsmounts
|
||||
}
|
||||
|
||||
# sync clock
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
syncclock
|
||||
setupntp
|
||||
}
|
||||
|
||||
# Setup PAM
|
||||
TABLE:noderes:$NODE:access=Y and
|
||||
(OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.*) {
|
||||
setuppam
|
||||
}
|
||||
|
||||
# Setup PBS
|
||||
TABLE:noderes:$NODE:pbs=Y and
|
||||
(OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.*) {
|
||||
openpbs
|
||||
}
|
||||
|
||||
# Setup paths
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
setuppaths
|
||||
}
|
||||
|
||||
# Setup services
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
setupservices
|
||||
}
|
||||
|
||||
# Setup rsh/ssh.
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
remoteshell
|
||||
}
|
||||
|
||||
# Enable sysctl
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
enablesysreq
|
||||
}
|
||||
|
||||
# Enable debug
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
enabledebug
|
||||
}
|
||||
|
||||
# Setup Myrinet MX
|
||||
TABLE:noderes:$NODE:install_roll=Y {
|
||||
setupstage
|
||||
}
|
||||
|
||||
# Re setup syslog, RPM updates may have hosed it.
|
||||
OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
resyslog
|
||||
}
|
||||
|
||||
|
||||
ALL {
|
||||
serialconsole
|
||||
}
|
||||
|
||||
#
|
||||
# Start custom section
|
||||
#
|
||||
# Here is a good place to put custom code
|
||||
#
|
||||
|
||||
#
|
||||
# End custom section
|
||||
#
|
||||
|
||||
# Sync dirs
|
||||
OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
syncdirs
|
||||
}
|
||||
|
||||
# Unmount /post.
|
||||
ALL {
|
||||
umountpost
|
||||
}
|
||||
|
||||
# Update remote boot flag. rsh/ssh must be setup first
|
||||
# unless xcatd is used. To use rsh or ssh, pass as
|
||||
# option to updateflag else pass xcatd
|
||||
#
|
||||
#2nd arg can be Master IP for multiple master IP support.
|
||||
#
|
||||
ALL {
|
||||
updateflag.awk $MASTER
|
||||
}
|
||||
|
||||
# hardcode networking
|
||||
#OSVER=sl[34].* or OSVER=centos.* or OSVER=rh.* or OSVER=sles.* or OSVER=suse.* {
|
||||
# hardnis
|
||||
# hardmodopts options e1000 RxIntDelay=0,0 TxIntDelay=0,0 RxAbsIntDelay=0,0 TxAbsIntDelay=0,0 InterruptThrottleRate=0,0
|
||||
#}
|
||||
|
||||
# SuSE needs an extra reboot.
|
||||
OSVER=sles.* or OSVER=suse.* {
|
||||
reboot
|
||||
}
|
||||
|
458
xCAT-server-2.0/usr/lib/xcat/dsh/Context/XCAT.pm
Normal file
458
xCAT-server-2.0/usr/lib/xcat/dsh/Context/XCAT.pm
Normal file
@ -0,0 +1,458 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package XCAT;
|
||||
use base DSHContext;
|
||||
use Socket;
|
||||
use xCAT::Utils;
|
||||
use xCAT::MsgUtils;
|
||||
|
||||
# Define remote shell globals from xCAT
|
||||
|
||||
our $XCAT_RSH_CMD;
|
||||
our $XCAT_RCP_CMD;
|
||||
|
||||
#
|
||||
# get the remote command settings
|
||||
#
|
||||
|
||||
XCAT->get_xcat_remote_cmds;
|
||||
|
||||
# Global Data structures for xCAT context
|
||||
|
||||
our @xcat_node_list = ();
|
||||
our %xcat_nodegroup_table = ();
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
context_defaults
|
||||
|
||||
Assign default properties for the xCAT context. A default
|
||||
property for a context will be used if the property is
|
||||
not user configured in any other way.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
A reference to a hash table with the configured
|
||||
default properties for the xCAT context
|
||||
|
||||
Globals:
|
||||
$XCAT_RSH_CMD
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
$default_properties = XCAT->config_defaults;
|
||||
|
||||
Comments:
|
||||
$defaults hash table contents:
|
||||
|
||||
$defaults{'NodeRemoteShell'} - default remote shell to use for node targets
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub context_defaults
|
||||
{
|
||||
my %defaults = ();
|
||||
|
||||
$defaults{'NodeRemoteShell'} = $XCAT_RSH_CMD;
|
||||
|
||||
return \%defaults;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
context_properties
|
||||
|
||||
Configure the user specified context properties for the xCAT context.
|
||||
These properties are configured by the user through environment
|
||||
variables or external configuration files.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
A reference to a hash table of user-configured properties for
|
||||
the xCAT context.
|
||||
|
||||
Globals:
|
||||
None
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
$properties = XCAT->config_properties
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub context_properties
|
||||
{
|
||||
my %properties = ();
|
||||
|
||||
$properties{'RemoteShell'} = $XCAT_RSH_CMD;
|
||||
$properties{'RemoteCopyCmd'} = $XCAT_RCP_CMD;
|
||||
|
||||
return \%properties;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
all_devices
|
||||
|
||||
Comments: devices are nodes in the XCAT context. Use node flags
|
||||
and not device flags.
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub all_devices
|
||||
{
|
||||
my ($class, $resolved_targets) = @_;
|
||||
|
||||
xCAT::MsgUtils->message(
|
||||
"E",
|
||||
" Nodes and Devices are considered nodes in xCAT.\n The -A flag is not supported. Use the all group in XCAT to dsh to all node/devices.\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
all_nodes
|
||||
|
||||
Returns an array of all node names in the xCAT context
|
||||
Note in xCAT everything is a node including devices
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
An array of node/device names
|
||||
|
||||
Globals:
|
||||
@xcat_node_list
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
@nodes = XCAT->get_xcat_node_list;
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub all_nodes
|
||||
{
|
||||
scalar(@xcat_node_list) || XCAT->get_xcat_node_list;
|
||||
return @xcat_node_list;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
all_nodegroups
|
||||
|
||||
Returns an array of all node group names in the xCAT context
|
||||
Note in xCAT everything is a node including devices
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
An array of node/device group names
|
||||
|
||||
Globals:
|
||||
%xcat_nodegroup_table
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
@nodegroups = XCAT->all_nodegroups;
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub all_nodegroups
|
||||
{
|
||||
scalar(%xcat_nodegroup_table) || XCAT->get_xcat_nodegroup_table;
|
||||
return keys(%xcat_nodegroup_table);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
nodegroup_members
|
||||
|
||||
Given a node/device group in the xCAT context, this routine expands the
|
||||
membership of the group and returns a list of its members.
|
||||
|
||||
Arguments:
|
||||
$nodegroup - node group name
|
||||
|
||||
Returns:
|
||||
An array of node group members
|
||||
|
||||
Globals:
|
||||
$nodegroup_path
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
$members = XCAT->nodegroup_members('MyGroup1');
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub nodegroup_members
|
||||
{
|
||||
my ($class, $nodegroup) = @_;
|
||||
my %node_list = ();
|
||||
scalar(%xcat_nodegroup_table) || XCAT->get_xcat_nodegroup_table;
|
||||
!defined($xcat_nodegroup_table{$nodegroup}) && return undef;
|
||||
|
||||
my @nodes = split /,/, $xcat_nodegroup_table{$nodegroup};
|
||||
|
||||
foreach my $node (@nodes)
|
||||
{
|
||||
$node_list{$node}++;
|
||||
}
|
||||
|
||||
my @members = keys(%node_list);
|
||||
return \@members;
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
resolve_node
|
||||
|
||||
Within the xCAT context, resolve the name of a given node and
|
||||
augment the supplied property hash table with xCAT node information.
|
||||
|
||||
Arguments:
|
||||
$target_properties - basic properties hash table reference for a node
|
||||
|
||||
Returns:
|
||||
1 if resolution was successful
|
||||
undef otherwise
|
||||
|
||||
Globals:
|
||||
$XCAT_RSH_CMD
|
||||
$XCAT_RCP_CMD
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
XCAT->resolve_node($target_properties);
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub resolve_node
|
||||
{
|
||||
my ($class, $target_properties) = @_;
|
||||
|
||||
$$target_properties{'remote-shell'} = $XCAT_RSH_CMD;
|
||||
$$target_properties{'remote-copy'} = $XCAT_RCP_CMD;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
get_xcat_remote_cmds
|
||||
|
||||
Using xCAT native commands, store the remote command settings for
|
||||
the remote shell and remote copy commands as defined in xCAT
|
||||
site.tab file.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
Globals:
|
||||
$XCAT_RSH_CMD
|
||||
$XCAT_RCP_CMD
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
XCAT->get_xcat_remote_cmds
|
||||
|
||||
Comments:
|
||||
Internal routine only
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub get_xcat_remote_cmds
|
||||
{
|
||||
$XCAT_RSH_CMD = "/usr/bin/ssh"; # default
|
||||
$XCAT_RCP_CMD = "/usr/bin/scp"; #default
|
||||
my @remote_shell = xCAT::Utils->get_site_attribute("rsh");
|
||||
if ($remote_shell[0])
|
||||
{
|
||||
$XCAT_RSH_CMD = $remote_shell[0];
|
||||
}
|
||||
my @remote_copy = xCAT::Utils->get_site_attribute("rcp");
|
||||
if ($remote_copy[0])
|
||||
{
|
||||
$XCAT_RCP_CMD = $remote_copy[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
get_xcat_node_list
|
||||
|
||||
Using xCAT native commands, this routine builds a cached list of
|
||||
node/device names defined in the xCAT context
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
Globals:
|
||||
%xcat_node_list
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
XCAT->get_xcat_node_list
|
||||
|
||||
Comments:
|
||||
Internal routine only
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub get_xcat_node_list
|
||||
{
|
||||
@xcat_node_list = xCAT::Utils->get_node_list;
|
||||
chomp(@xcat_node_list);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
get_xcat_nodegroup_table
|
||||
|
||||
Using xCAT native commands, this routine builds a cached list of
|
||||
node groups and their members defined in the xCAT context
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
Globals:
|
||||
%xcat_nodegroup_table
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
XCAT->get_xcat_nodegroup_table
|
||||
|
||||
Comments:
|
||||
Internal routine only
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub get_xcat_nodegroup_table
|
||||
{
|
||||
$node_list = "";
|
||||
my @nodegroups = xCAT::Utils->list_all_node_groups;
|
||||
for my $group (@nodegroups)
|
||||
{
|
||||
chomp($group);
|
||||
my @nodes = `nodels $group`;
|
||||
while (@nodes)
|
||||
{
|
||||
my $nodename = shift @nodes;
|
||||
chomp($nodename);
|
||||
$node_list .= $nodename;
|
||||
$node_list .= ",";
|
||||
}
|
||||
chop($node_list);
|
||||
$xcat_nodegroup_table{$group} = $node_list;
|
||||
$node_list = "";
|
||||
}
|
||||
}
|
||||
|
||||
sub query_node
|
||||
{
|
||||
my ($class, $node, $flag) = @_;
|
||||
my @xcat_nodes = all_nodes();
|
||||
|
||||
$~ = "NODES";
|
||||
if ($flag)
|
||||
{
|
||||
if (grep(/^$node$/, @xcat_nodes))
|
||||
{
|
||||
print("$node : Valid\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
print("$node : Invalid\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print("$node : Invalid\n");
|
||||
}
|
||||
}
|
||||
|
||||
sub query_group
|
||||
{
|
||||
|
||||
my ($class, $group) = @_;
|
||||
my @xcat_groups = all_nodegroups();
|
||||
|
||||
$~ = "GROUPS";
|
||||
if (grep(/^$group$/, @xcat_groups))
|
||||
{
|
||||
print("$group : Valid\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
print("$group : Invalid\n");
|
||||
}
|
||||
}
|
||||
|
||||
1; #end
|
49
xCAT-server-2.0/usr/lib/xcat/monitoring/samples/mycode.pm
Normal file
49
xCAT-server-2.0/usr/lib/xcat/monitoring/samples/mycode.pm
Normal file
@ -0,0 +1,49 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_monitoring::mycode;
|
||||
1;
|
||||
|
||||
# This subroutine get called when new nodes are added into the cluster
|
||||
# or nodes are removed from the cluster.
|
||||
#
|
||||
sub processTableChanges {
|
||||
my $action=shift;
|
||||
if ($action =~ /xCAT_monitoring::mycode/){
|
||||
$action=shift;
|
||||
}
|
||||
my $tablename=shift;
|
||||
my $old_data=shift;
|
||||
my $new_data=shift;
|
||||
|
||||
my @nodenames=();
|
||||
if ($action eq "a") { #nodes added in the cluster
|
||||
if ($new_data) {
|
||||
push(@nodenames, $new_data->{node});
|
||||
$noderange=join(',', @nodenames);
|
||||
open(FILE, ">>/var/log/mycode.log") or dir ("cannot open the file\n");
|
||||
print (FILE "new nodes in the cluster are: $noderange\n");
|
||||
close(FILE);
|
||||
}
|
||||
}
|
||||
elsif ($action eq "d") { #nodes removed from the cluster
|
||||
#find out the index of "node" column
|
||||
if ($old_data->[0]) {
|
||||
$colnames=$old_data->[0];
|
||||
my $i;
|
||||
for ($i=0; $i<@$colnames; ++$i) {
|
||||
if ($colnames->[$i] eq "node") {last;}
|
||||
}
|
||||
|
||||
for (my $j=1; $j<@$old_data; ++$j) {
|
||||
push(@nodenames, $old_data->[$j]->[$i]);
|
||||
}
|
||||
|
||||
if (@nodenames > 0) {
|
||||
$noderange=join(',', @nodenames);
|
||||
open(FILE, ">>/var/log/mycode.log") or dir ("cannot open the file\n");
|
||||
print (FILE "nodes leaving the cluster are: $noderange\n");
|
||||
close(FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
1145
xCAT-server-2.0/usr/lib/xcat/plugins/DBobjectdefs.pm
Normal file
1145
xCAT-server-2.0/usr/lib/xcat/plugins/DBobjectdefs.pm
Normal file
File diff suppressed because it is too large
Load Diff
1013
xCAT-server-2.0/usr/lib/xcat/plugins/bind.pm
Executable file
1013
xCAT-server-2.0/usr/lib/xcat/plugins/bind.pm
Executable file
File diff suppressed because it is too large
Load Diff
757
xCAT-server-2.0/usr/lib/xcat/plugins/blade.pm
Normal file
757
xCAT-server-2.0/usr/lib/xcat/plugins/blade.pm
Normal file
@ -0,0 +1,757 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::blade;
|
||||
#use Net::SNMP qw(:snmp INTEGER);
|
||||
use xCAT::Table;
|
||||
use IO::Socket;
|
||||
use SNMP;
|
||||
use strict;
|
||||
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use POSIX "WNOHANG";
|
||||
use Storable qw(freeze thaw);
|
||||
use IO::Select;
|
||||
use IO::Handle;
|
||||
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
findme => 'blade',
|
||||
rpower => 'nodehm:power,mgt',
|
||||
rvitals => 'nodehm:vitals,mgt',
|
||||
rinv => 'nodehm:inv,mgt',
|
||||
rbeacon => 'nodehm:beacon,mgt',
|
||||
rbootseq => 'nodehm:bootseq,mgt',
|
||||
reventlog => 'nodehm:eventlog,mgt',
|
||||
};
|
||||
}
|
||||
my %usage = (
|
||||
"rpower" => "Usage: rpower <noderange> [on|off|reset|stat|boot]",
|
||||
"rbeacon" => "Usage: rbeacon <noderange> [on|off|stat]",
|
||||
"rvitals" => "Usage: rvitals <noderange> [all|temp|voltage|fanspeed|power|leds]",
|
||||
"reventlog" => "Usage: reventlog <noderange> [all|clear|<number of entries to retrieve>]",
|
||||
"rinv" => "Usage: rinv <noderange> [all|model|serial|vpd|mprom|deviceid|uuid]",
|
||||
"rbootseq" => "Usage: rbootseq <noderange> [hd0|hd1|hd2|hd3|net|iscsi|usbflash|floppy|none],...",
|
||||
);
|
||||
my %macmap; #Store responses from rinv for discovery
|
||||
my $mmprimoid = '1.3.6.1.4.1.2.3.51.2.22.5.1.1.4';#mmPrimary
|
||||
my $beaconoid = '1.3.6.1.4.1.2.3.51.2.2.8.2.1.1.11'; #ledBladeIdentity
|
||||
my $powerstatoid = '1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4';#bladePowerState
|
||||
my $powerchangeoid = '1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7';#powerOnOffBlade
|
||||
my $powerresetoid = '1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.8';#restartBlade
|
||||
my $mpresetoid = '1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.9'; #restartBladeSMP
|
||||
my $bladexistsoid = '1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.3'; #bladeExists
|
||||
my $bladeserialoid = '1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.6'; #bladeHardwareVpdSerialNumber
|
||||
my $blademtmoid = '1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.7'; #bladeHardwareVpdMachineType
|
||||
my $bladempveroid = '1.3.6.1.4.1.2.3.51.2.2.21.5.3.1.7'; #bladeSysMgmtProcVpdRevision
|
||||
my $bladempaveroid = '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.4';#mmMainApplVpdRevisonNumber
|
||||
my $bladempabuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.3';#mmMainApplVpdBuildId
|
||||
my $bladempadateoid = '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.6';#mmMainApplVpdBuildDate
|
||||
my $bladempbuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.3.1.6'; #bladeSysMgmtProcVpdBuildId
|
||||
my $bladebiosveroid = '1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.7'; #bladeBiosVpdRevision
|
||||
my $bladebiosbuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.6'; #bladeBiosVpdBuildId
|
||||
my $bladebiosdateoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.8'; #bladeBiosVpdDate
|
||||
my $bladediagveroid = '1.3.6.1.4.1.2.3.51.2.2.21.5.2.1.7'; #bladeDiagsVpdRevision
|
||||
my $bladediagbuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.2.1.6'; #bladeDiagsVpdBuildId
|
||||
my $bladediagdateoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.2.1.8';#bladeDiagsVpdDate
|
||||
my $eventlogoid = '1.3.6.1.4.1.2.3.51.2.3.4.2.1.2';#readEventLogString
|
||||
my $clearlogoid = '.1.3.6.1.4.1.2.3.51.2.3.4.3';#clearEventLog
|
||||
my @macoids = (
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.2', #bladeMACAddress1Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.3', #bladeMACAddress2Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.4', #bladeMACAddress3Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.5', #bladeMACAddress4Vpd
|
||||
);
|
||||
my @dcmacoids = (
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.10', #bladeDaughterCard1MACAddress1Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.11', #bladeDaughterCard1MACAddress2Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.12', #bladeDaughterCard1MACAddress3Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.13', #bladeDaughterCard1MACAddress4Vpd
|
||||
);
|
||||
my @hsdcmacoids = (
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.100', #bladeHSDaughterCard1MACAddress1Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.101', #bladeHSDaughterCard1MACAddress2Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.102', #bladeHSDaughterCard1MACAddress3Vpd
|
||||
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.103', #bladeHSDaughterCard1MACAddress4Vpd
|
||||
);
|
||||
my @bootseqoids = (
|
||||
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.7', #bootSequence1
|
||||
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.8', #bootSequence2
|
||||
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.9', #bootSequence3
|
||||
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.10', #bootSequence4
|
||||
);
|
||||
my %bootdevices = (
|
||||
0 => 'none',
|
||||
1 => 'floppy',
|
||||
2 => 'cdrom',
|
||||
3 => 'hd0',
|
||||
4 => 'hd1',
|
||||
5 => 'hd2',
|
||||
6 => 'hd3',
|
||||
7 => 'net',
|
||||
8 => 'iscsi',
|
||||
9 => 'iscsicrit',
|
||||
10 => 'hd4',
|
||||
11 => 'usbflash'
|
||||
);
|
||||
my %bootnumbers = (
|
||||
'none' => 0,
|
||||
'f' => 1,
|
||||
'floppy' => 1,
|
||||
'c' => 2,
|
||||
'cd' => 2,
|
||||
'dvd' => 2,
|
||||
'cdrom' => 2,
|
||||
'dvdrom' => 2,
|
||||
'h' => 3, #in absence of an index, presuming hd0 intended
|
||||
'hd' => 3,
|
||||
'hardisk' => 3,
|
||||
'hd0' => 3,
|
||||
'harddisk0' => 3,
|
||||
'hd1' => 4,
|
||||
'harddisk1' => 4,
|
||||
'hd2' => 5,
|
||||
'harddisk2' => 5,
|
||||
'hd3' => 6,
|
||||
'harddisk3' => 6,
|
||||
'n' => 7,
|
||||
'network' => 7,
|
||||
'net' => 7,
|
||||
'iscsi' => 8,
|
||||
'iscsicrit' => 9,
|
||||
'hd4' => 10,
|
||||
'harddisk4' => 10,
|
||||
'usbflash' => 11,
|
||||
'flash' => 11,
|
||||
'usb' => 11
|
||||
);
|
||||
|
||||
my $session;
|
||||
my $slot;
|
||||
my $didchassis = 0;
|
||||
my @eventlog_array = ();
|
||||
my $activemm;
|
||||
my %mpahash;
|
||||
my $mpa;
|
||||
my $allinchassis=0;
|
||||
|
||||
sub fillresps {
|
||||
my $response = shift;
|
||||
my $mac = $response->{node}->[0]->{data}->[0]->{contents}->[0];
|
||||
my $node = $response->{node}->[0]->{name}->[0];
|
||||
$macmap{$mac} = $node;
|
||||
#$macmap{$response->{node}->[0]->{data}->{contents}->[0]}=$response->{node}->[0]->{name};
|
||||
}
|
||||
sub isallchassis {
|
||||
my $bladesinchassis = 0;
|
||||
if ($allinchassis) {
|
||||
return 1;
|
||||
}
|
||||
foreach (1..14) {
|
||||
my $tmp = $session->get([$bladexistsoid.".$_"]);
|
||||
if ($tmp eq 1) { $bladesinchassis++ }
|
||||
}
|
||||
my $count = keys %{$mpahash{$mpa}->{nodes}};
|
||||
if ($count >= $bladesinchassis) { $allinchassis++; return 1 }; #commands that affect entire are okayed, i.e eventlog clear
|
||||
return 0;
|
||||
}
|
||||
sub resetmp {
|
||||
my $data;
|
||||
my $stat;
|
||||
my $rc;
|
||||
$data = $session->set($mpresetoid.".$slot", 1);
|
||||
#if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($data->{$mpresetoid.".$slot"} == 1) {
|
||||
return (0, "mpreset");
|
||||
} else {
|
||||
return (1,"error");
|
||||
}
|
||||
}
|
||||
|
||||
sub walkelog {
|
||||
my $session = shift;
|
||||
my $oid = shift;
|
||||
unless ($oid =~ /^\./) {
|
||||
$oid = '.'.$oid;
|
||||
}
|
||||
my $retmap = undef;
|
||||
my $current = 1;
|
||||
my @bindlist;
|
||||
my $varbind;
|
||||
do {
|
||||
foreach ($current..$current+31) { #Attempt to retrive 32 ents at a time, seems to be working...
|
||||
push @bindlist,[$oid,$_];
|
||||
}
|
||||
$current+=32;
|
||||
$varbind = new SNMP::VarList(
|
||||
@bindlist
|
||||
);
|
||||
$session->get($varbind);
|
||||
foreach(@$varbind) {
|
||||
unless (${_}->[2]) {last;}
|
||||
if( ${_}->[2] =~ /NOSUCHINSTANCE/) {last;}
|
||||
$retmap->{$_->[1]}=$_->[2];
|
||||
}
|
||||
} while ($varbind->[31] and $varbind->[31]->[2] != 'NOSUCHINSTANCE' and ($current < 600));
|
||||
|
||||
return $retmap;
|
||||
print "Count was $current\n";
|
||||
#print Dumper($varbind->[60]->[2]);
|
||||
print "\n\n";
|
||||
return undef;
|
||||
my $count=0;
|
||||
while ($varbind->[0] =~ /^$oid\.?(.*)/) {
|
||||
$count++;
|
||||
if ($1) {
|
||||
$retmap->{$1.".".$varbind->[1]}=$varbind->[2]; #If $1 is set, means key should
|
||||
} else {
|
||||
$retmap->{$varbind->[1]}=$varbind->[2]; #If $1 is set, means key should
|
||||
}
|
||||
$session->getnext($varbind);
|
||||
}
|
||||
return $retmap;
|
||||
}
|
||||
|
||||
sub eventlog { #Tried various optimizations, but MM seems not to do bulk-request
|
||||
#TODO: retrieval of non blade events, what should be syntax?
|
||||
#TODO: try retrieving 5 at a time, then 1 at a time when that stops working
|
||||
my $cmd=shift;
|
||||
my $data;
|
||||
my @output;
|
||||
my $oid = $eventlogoid;
|
||||
if ($cmd eq 'all') {
|
||||
$cmd=65535; #no MM has this many logs possible, should be a good number
|
||||
}
|
||||
if ($cmd =~ /^(\d+)$/) {
|
||||
my $requestednumber=$1;
|
||||
unless (@eventlog_array) {
|
||||
#my $varbind=new SNMP::Varbind([$oid,0]);
|
||||
#while ($data=$session->getnext($varbind)) {
|
||||
# print Dumper($data);
|
||||
# if ($session->{ErrorStr}) { printf $session->{ErrorStr}."\n"; }
|
||||
# foreach (keys %$data) {
|
||||
# $oid=$_;
|
||||
# }
|
||||
# unless (oid_base_match($eventlogoid,$oid)) {
|
||||
# last;
|
||||
# }
|
||||
my $logents = walkelog($session,$oid);
|
||||
foreach (sort {$a <=> $b} (keys %$logents)) {
|
||||
push @eventlog_array,$logents->{$_}."\n";
|
||||
}
|
||||
#push @eventlog_array,$data->{$oid}; #TODO: filter against slot number, check for $allchassis for non-blade
|
||||
#}
|
||||
}
|
||||
my $numentries=0;
|
||||
#my $allchassis = isallchassis;
|
||||
foreach (@eventlog_array) {
|
||||
m/Severity:(\S+)\s+Source:(\S+)\s+Name:\S*\s+Date:(\S+)\s+Time:(\S+)\s+Text:(.+)/;
|
||||
my $sev=$1;
|
||||
my $source=$2;
|
||||
my $date=$3;
|
||||
my $time=$4;
|
||||
my $text=$5;
|
||||
my $matchstring;
|
||||
if ($slot > 0) {
|
||||
$matchstring=sprintf("BLADE_%02d",$slot);
|
||||
} else {
|
||||
$matchstring="^(?!BLADE).*";
|
||||
}
|
||||
if ($source =~ m/$matchstring$/i) { #MM guys changed their minds on capitalization
|
||||
$numentries++;
|
||||
unshift @output,"$sev:$date $time $text"; #unshift to get it in a sane order
|
||||
}
|
||||
if ($numentries >= $requestednumber) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
return (0,@output);
|
||||
}
|
||||
my $data;
|
||||
if ($cmd eq "clear") {
|
||||
unless (isallchassis) {
|
||||
return (1,"Cannot clear eventlogs except for entire chassis");
|
||||
}
|
||||
if ($didchassis) { return 0, "eventlog cleared" }
|
||||
my $varbind = new SNMP::Varbind([$clearlogoid,0,1,'INTEGER']);
|
||||
$data = $session->set($varbind);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$didchassis=1;
|
||||
if ($varbind->[2] eq 1) {
|
||||
return 0, "eventlog cleared";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub bootseq {
|
||||
my @args=@_;
|
||||
my $data;
|
||||
my @order=();
|
||||
if ($args[0] eq "list" or $args[0] eq "stat") {
|
||||
foreach my $oid (@bootseqoids) {
|
||||
$data=$session->get([$oid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1, $session->{ErrorStr}); }
|
||||
push @order,$bootdevices{$data};
|
||||
}
|
||||
return (0,join(',',@order));
|
||||
} else {
|
||||
foreach (@args) {
|
||||
my @neworder=(split /,/,$_);
|
||||
push @order,@neworder;
|
||||
}
|
||||
my $number=@order;
|
||||
if ($number > 4) {
|
||||
return (1,"Only four boot sequence entries allowed");
|
||||
}
|
||||
my $nonespecified=0;
|
||||
foreach (@order) {
|
||||
unless (defined($bootnumbers{$_})) { return (1,"Unsupported device $_"); }
|
||||
unless ($bootnumbers{$_}) { $nonespecified = 1; }
|
||||
if ($nonespecified and $bootnumbers{$_}) { return (1,"Error: cannot specify 'none' before a device"); }
|
||||
}
|
||||
unless ($bootnumbers{$order[0]}) {
|
||||
return (1,"Error: cannot specify 'none' as first device");
|
||||
}
|
||||
foreach (3,2,1,0) {
|
||||
my $param = $bootnumbers{$order[$_]};
|
||||
unless ($param) {
|
||||
$param = 0;
|
||||
my $varbind = new SNMP::Varbind([$bootseqoids[$_],$slot,$param,'INTEGER']);
|
||||
$data = $session->set($varbind);
|
||||
#$session->set($bootseqoids[$_].".$slot",$param);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
}
|
||||
}
|
||||
foreach (0,1,2,3) {
|
||||
my $param = $bootnumbers{$order[$_]};
|
||||
if ($param) {
|
||||
my $varbind = new SNMP::Varbind([$bootseqoids[$_],$slot,$param,'INTEGER']);
|
||||
$data = $session->set($varbind);
|
||||
#$session->set($bootseqoids[$_].".$slot",$param);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
}
|
||||
}
|
||||
return bootseq('list');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub inv {
|
||||
my @invitems;
|
||||
my $data;
|
||||
my @output;
|
||||
foreach (@_) {
|
||||
push @invitems,split( /,/,$_);
|
||||
}
|
||||
my $item;
|
||||
while (my $item = shift @invitems) {
|
||||
if ($item =~ /^all/) {
|
||||
push @invitems,(qw(mtm serial mac firm));
|
||||
next;
|
||||
}
|
||||
if ($item =~ /^firm/) {
|
||||
push @invitems,(qw(bios diag mprom mparom));
|
||||
next;
|
||||
}
|
||||
if ($item =~ /^bios/) {
|
||||
my $biosver;
|
||||
my $biosbuild;
|
||||
my $biosdate;
|
||||
$biosver=$session->get([$bladebiosveroid.".$slot"]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$biosbuild=$session->get([$bladebiosbuildidoid.".$slot"]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$biosdate=$session->get([$bladebiosdateoid.".$slot"]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
push @output,"BIOS: $biosver ($biosbuild $biosdate)";
|
||||
}
|
||||
if ($item =~ /^diag/) {
|
||||
my $diagver;
|
||||
my $diagdate;
|
||||
my $diagbuild;
|
||||
$data=$session->get([$bladediagveroid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$diagver = $data;
|
||||
$data=$session->get([$bladediagbuildidoid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$diagbuild = $data;
|
||||
$data=$session->get([$bladediagdateoid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$diagdate = $data;
|
||||
push @output,"Diagnostics: $diagver ($diagbuild $diagdate)";
|
||||
}
|
||||
if ($item =~ /^[sm]prom/) {
|
||||
my $spver;
|
||||
my $spbuild;
|
||||
$data=$session->get([$bladempveroid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$spver=$data;
|
||||
$data=$session->get([$bladempbuildidoid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$spbuild=$data;
|
||||
push @output,"BMC/Mgt processor: $spver ($spbuild)";
|
||||
}
|
||||
if ($item =~ /^mparom/) {
|
||||
my $mpabuild;
|
||||
my $mpaver;
|
||||
my $mpadate;
|
||||
$data=$session->get([$bladempaveroid,$activemm]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$mpaver=$data;
|
||||
$data=$session->get([$bladempabuildidoid,$activemm]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$mpabuild=$data;
|
||||
$data=$session->get([$bladempadateoid,$activemm]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
$mpadate=$data;
|
||||
push @output,"Management Module firmware: $mpaver ($mpabuild $mpadate)";
|
||||
}
|
||||
if ($item =~ /^model/ or $item =~ /^mtm/) {
|
||||
$data=$session->get([$blademtmoid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
push @output,"Machine Type/Model: ".$data;
|
||||
}
|
||||
if ($item =~ /^serial/) {
|
||||
$data=$session->get([$bladeserialoid,$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
push @output,"Serial Number: ".$data;
|
||||
}
|
||||
|
||||
if ($item =~ /^mac/) {
|
||||
foreach (0..3) {
|
||||
$data=$session->get([$macoids[$_],$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($data =~ /:/) {
|
||||
push @output,"MAC Address ".($_+1).": ".$data;
|
||||
}
|
||||
}
|
||||
foreach (0..3) {
|
||||
my $oid=$hsdcmacoids[$_].".$slot";
|
||||
$data=$session->get([$hsdcmacoids[$_],$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($data =~ /:/) {
|
||||
push @output,"HS Daughter card MAC Address ".($_+1).": ".$data;
|
||||
}
|
||||
}
|
||||
foreach (0..3) {
|
||||
$data=$session->get([$dcmacoids[$_],$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($data =~ /:/) {
|
||||
push @output,"Daughter card 1 MAC Address ".($_+1).": ".$data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0,@output);
|
||||
}
|
||||
sub power {
|
||||
my $subcommand = shift;
|
||||
my $data;
|
||||
my $stat;
|
||||
if ($subcommand eq "stat") {
|
||||
$data = $session->get([$powerstatoid.".".$slot]);
|
||||
if ($data == 1) {
|
||||
$stat = "on";
|
||||
} elsif ( $data == 0) {
|
||||
$stat = "off";
|
||||
} else {
|
||||
$stat= "error";
|
||||
}
|
||||
} elsif ($subcommand eq "off") {
|
||||
$data = $session->set(new SNMP::Varbind([".".$powerchangeoid,$slot,0,'INTEGER']));
|
||||
unless ($data) { return (1,$session->{ErrorStr}); }
|
||||
$stat = "off";
|
||||
} elsif ($subcommand eq "on") {
|
||||
$data = $session->set(new SNMP::Varbind([".".$powerchangeoid,$slot,1,'INTEGER']));
|
||||
unless ($data) { return (1,$session->{ErrorStr}); }
|
||||
$stat = ($data ? "on" : "off");
|
||||
} elsif ($subcommand eq "reset") {
|
||||
$data = $session->set(new SNMP::Varbind([".".$powerresetoid,$slot ,1,'INTEGER']));
|
||||
unless ($data) { return (1,$session->{ErrorStr}); }
|
||||
$stat = "reset";
|
||||
}
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($stat) { return (0,$stat); }
|
||||
}
|
||||
|
||||
|
||||
sub beacon {
|
||||
my $subcommand = shift;
|
||||
my $data;
|
||||
if ($subcommand eq "stat") {
|
||||
} elsif ($subcommand eq "on") {
|
||||
$data = $session->set(new SNMP::Varbind([$beaconoid,$slot , 1,'INTEGER']));
|
||||
} elsif ($subcommand eq "off") {
|
||||
$data = $session->set(new SNMP::Varbind([$beaconoid,$slot , 0,'INTEGER']));
|
||||
} elsif ($subcommand eq "blink") {
|
||||
$data = $session->set(new SNMP::Varbind([$beaconoid,$slot , 2,'INTEGER']));
|
||||
} else {
|
||||
return (1,"$subcommand unsupported");
|
||||
}
|
||||
my $stat = $session->get([$beaconoid.".".$slot]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
if ($stat==0) {
|
||||
return (0,"off");
|
||||
} elsif ($stat==1) {
|
||||
return (0,"on");
|
||||
} elsif ($stat==2) {
|
||||
return (0,"blink");
|
||||
} elsif ($stat==3) {
|
||||
return (0,"unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
sub bladecmd {
|
||||
$mpa = shift;
|
||||
$slot = shift;
|
||||
#my $user = shift;
|
||||
#my $pass = shift;
|
||||
my $command = shift;
|
||||
my @args = @_;
|
||||
my $error;
|
||||
|
||||
|
||||
if ($slot > 0) {
|
||||
my $tmp = $session->get([$bladexistsoid.".$slot"]);
|
||||
if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
|
||||
unless ($tmp eq 1) { return (1,"Target bay empty"); }
|
||||
}
|
||||
if ($command eq "rbeacon") {
|
||||
return beacon(@args);
|
||||
} elsif ($command eq "rpower") {
|
||||
return power(@args);
|
||||
} elsif ($command =~ /r[ms]preset/) {
|
||||
return resetmp(@args);
|
||||
} elsif ($command eq "rbootseq") {
|
||||
return bootseq(@args);
|
||||
} elsif ($command eq "rinv") {
|
||||
return inv(@args);
|
||||
} elsif ($command eq "reventlog") {
|
||||
return eventlog(@args);
|
||||
}
|
||||
|
||||
return (1,"$command not a supported command by blade method");
|
||||
}
|
||||
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $noderange = $request->{node};
|
||||
my $command = $request->{command}->[0];
|
||||
my @exargs;
|
||||
unless ($noderange or $command eq "findme") {
|
||||
if ($usage{$command}) {
|
||||
$callback->({data=>$usage{$command}});
|
||||
$request = {};
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ref($request->{arg})) {
|
||||
@exargs = @{$request->{arg}};
|
||||
} else {
|
||||
@exargs = ($request->{arg});
|
||||
}
|
||||
my $bladeuser = 'USERID';
|
||||
my $bladepass = 'PASSW0RD';
|
||||
my $blademaxp = 64;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
my $mpatab = xCAT::Table->new('mpa');
|
||||
my $mptab = xCAT::Table->new('mp');
|
||||
my $tmp;
|
||||
if ($sitetab) {
|
||||
($tmp)=$sitetab->getAttribs({'key'=>'blademaxp'},'value');
|
||||
if (defined($tmp)) { $blademaxp=$tmp->{value}; }
|
||||
}
|
||||
my $passtab = xCAT::Table->new('passwd');
|
||||
if ($passtab) {
|
||||
($tmp)=$passtab->getAttribs({'key'=>'blade'},'username','password');
|
||||
if (defined($tmp)) {
|
||||
$bladeuser = $tmp->{username};
|
||||
$bladepass = $tmp->{password};
|
||||
}
|
||||
}
|
||||
if ($request->{command}->[0] eq "findme") {
|
||||
my $mptab = xCAT::Table->new("mp");
|
||||
unless ($mptab) { return 2; }
|
||||
my @bladents = $mptab->getAllNodeAttribs([qw(node)]);
|
||||
my @blades;
|
||||
foreach (@bladents) {
|
||||
push @blades,$_->{node};
|
||||
}
|
||||
my %invreq;
|
||||
$invreq{node} = \@blades;
|
||||
$invreq{arg} = ['mac'];
|
||||
$invreq{command} = ['rinv'];
|
||||
my $mac;
|
||||
my $ip = $request->{'!xcat_clientip'};
|
||||
my $arptable = `/sbin/arp -n`;
|
||||
my @arpents = split /\n/,$arptable;
|
||||
foreach (@arpents) {
|
||||
if (m/^($ip)\s+\S+\s+(\S+)\s/) {
|
||||
$mac=$2;
|
||||
last;
|
||||
}
|
||||
}
|
||||
unless ($mac) { return };
|
||||
|
||||
unless ($macmap{$mac}) {
|
||||
process_request(\%invreq,\&fillresps);
|
||||
}
|
||||
unless ($macmap{$mac}) {
|
||||
return 1; #failure
|
||||
}
|
||||
my $mactab = xCAT::Table->new('mac',-create=>1);
|
||||
$mactab->setNodeAttribs($macmap{$mac},{mac=>$mac});
|
||||
$mactab->close();
|
||||
my %request = (
|
||||
command => ['makedhcp'],
|
||||
node => [$macmap{$mac}]
|
||||
);
|
||||
$doreq->(\%request);
|
||||
$request->{command}=['discovered'];
|
||||
$request->{noderange} = [$macmap{$mac}];
|
||||
$doreq->($request);
|
||||
%{$request}=(); #Clear request. it is done
|
||||
undef $mactab;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
my $children = 0;
|
||||
$SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) { $children--; } };
|
||||
my $inputs = new IO::Select;;
|
||||
foreach (@$noderange) {
|
||||
my $node=$_;
|
||||
my $user=$bladeuser;
|
||||
my $pass=$bladepass;
|
||||
my $nodeid;
|
||||
my $mpa;
|
||||
my $ent;
|
||||
if (defined($mptab)) {
|
||||
$ent=$mptab->getNodeAttribs($node,['mpa','id']);
|
||||
if (defined($ent->{mpa})) { $mpa=$ent->{mpa}; }
|
||||
if (defined($ent->{id})) { $nodeid = $ent->{id}; }
|
||||
}
|
||||
if (defined($mpatab)) {
|
||||
($ent)=$mpatab->getAttribs({'mpa'=>$mpa},'username','password');
|
||||
if (defined($ent->{password})) { $pass = $ent->{password}; }
|
||||
if (defined($ent->{username})) { $user = $ent->{username}; }
|
||||
}
|
||||
$mpahash{$mpa}->{nodes}->{$node}=$nodeid;
|
||||
$mpahash{$mpa}->{username} = $user;
|
||||
$mpahash{$mpa}->{password} = $pass;
|
||||
}
|
||||
my $sub_fds = new IO::Select;
|
||||
foreach $mpa (sort (keys %mpahash)) {
|
||||
while ($children > $blademaxp) { sleep (0.1); }
|
||||
$children++;
|
||||
my $cfd;
|
||||
my $pfd;
|
||||
pipe $cfd, $pfd;
|
||||
$cfd->autoflush(1);
|
||||
$pfd->autoflush(1);
|
||||
my $cpid = fork;
|
||||
unless (defined($cpid)) { die "Fork error"; }
|
||||
unless ($cpid) {
|
||||
close($cfd);
|
||||
dompa($pfd,$mpa,\%mpahash,$command,-args=>@exargs);
|
||||
exit(0);
|
||||
}
|
||||
close ($pfd);
|
||||
$sub_fds->add($cfd);
|
||||
}
|
||||
while ($children > 0) {
|
||||
forward_data($callback,$sub_fds);
|
||||
}
|
||||
while (forward_data($callback,$sub_fds)) {}
|
||||
}
|
||||
|
||||
sub forward_data {
|
||||
my $callback = shift;
|
||||
my $fds = shift;
|
||||
my @ready_fds = $fds->can_read(1);
|
||||
my $rfh;
|
||||
my $rc = @ready_fds;
|
||||
foreach $rfh (@ready_fds) {
|
||||
my $data;
|
||||
if ($data = <$rfh>) {
|
||||
while ($data !~ /ENDOFFREEZE6sK4ci/) {
|
||||
$data .= <$rfh>;
|
||||
}
|
||||
my $responses=thaw($data);
|
||||
foreach (@$responses) {
|
||||
$callback->($_);
|
||||
}
|
||||
} else {
|
||||
$fds->remove($rfh);
|
||||
close($rfh);
|
||||
}
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
sub dompa {
|
||||
my $out = shift;
|
||||
$mpa = shift;
|
||||
my $mpahash = shift;
|
||||
my $command=shift;
|
||||
my %namedargs=@_;
|
||||
my @exargs=$namedargs{-args};
|
||||
my $node;
|
||||
$session = new SNMP::Session(
|
||||
DestHost => $mpa,
|
||||
Version => '3',
|
||||
SecName => $mpahash->{$mpa}->{username},
|
||||
AuthProto => 'SHA',
|
||||
AuthPass => $mpahash->{$mpa}->{password},
|
||||
PrivProto => 'DES',
|
||||
SecLevel => 'authPriv',
|
||||
UseNumeric => 1,
|
||||
Retries => 2, # Give up sooner to make commands go smoother
|
||||
Timeout=>1200000, #Beacon, for one, takes a bit over a second to return
|
||||
PrivPass => $mpahash->{$mpa}->{password});
|
||||
if ($session->{ErrorStr}) { return 1,$session->{ErrorStr}; }
|
||||
my $tmp = $session->get([$mmprimoid.".1"]);
|
||||
if ($session->{ErrorStr}) { print $session->{ErrorStr}; }
|
||||
$activemm = ($tmp ? 1 : 2);
|
||||
my @outhashes;
|
||||
if ($command eq "reventlog" and isallchassis) {
|
||||
#Add a dummy node for eventlog to get non-blade events
|
||||
$mpahash{$mpa}->{nodes}->{$mpa}=-1;
|
||||
}
|
||||
foreach $node (sort (keys %{$mpahash->{$mpa}->{nodes}})) {
|
||||
my ($rc,@output) = bladecmd($mpa,$mpahash->{$mpa}->{nodes}->{$node},$command,@exargs);
|
||||
my @output_hashes;
|
||||
foreach(@output) {
|
||||
my %output;
|
||||
(my $desc,my $text) = split (/:/,$_,2);
|
||||
unless ($text) {
|
||||
$text=$desc;
|
||||
} else {
|
||||
$desc =~ s/^\s+//;
|
||||
$desc =~ s/\s+$//;
|
||||
if ($desc) {
|
||||
$output{node}->[0]->{data}->[0]->{desc}->[0]=$desc;
|
||||
}
|
||||
}
|
||||
$text =~ s/^\s+//;
|
||||
$text =~ s/\s+$//;
|
||||
$output{node}->[0]->{name}->[0]=$node;
|
||||
$output{node}->[0]->{data}->[0]->{contents}->[0]=$text;
|
||||
print $out freeze([\%output]);
|
||||
print $out "\nENDOFFREEZE6sK4ci\n";
|
||||
}
|
||||
}
|
||||
#my $msgtoparent=freeze(\@outhashes); # = XMLout(\%output,RootName => 'xcatresponse');
|
||||
#print $out $msgtoparent; #$node.": $_\n";
|
||||
}
|
||||
|
||||
1;
|
||||
|
102
xCAT-server-2.0/usr/lib/xcat/plugins/bmcconfig.pm
Normal file
102
xCAT-server-2.0/usr/lib/xcat/plugins/bmcconfig.pm
Normal file
@ -0,0 +1,102 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::bmcconfig;
|
||||
use Data::Dumper;
|
||||
use xCAT::Table;
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
getbmcconfig => 'bmcconfig',
|
||||
};
|
||||
}
|
||||
|
||||
sub genpassword {
|
||||
my $length = shift;
|
||||
my $password='';
|
||||
my $characters= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
|
||||
srand; #have to reseed, rand is not rand otherwise
|
||||
while (length($password) < $length) {
|
||||
$password .= substr($characters,int(rand 63),1);
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
sub net_parms {
|
||||
my $ip = shift;
|
||||
if ($ip =~ /[A-Za-z]/) {
|
||||
my $addr = (gethostbyname($ip))[4];
|
||||
my @bytes = unpack("C4",$addr);
|
||||
$ip = join(".",@bytes);
|
||||
}
|
||||
my $nettab = xCAT::Table->new('networks');
|
||||
unless ($nettab) { return undef };
|
||||
my @nets = $nettab->getAllAttribs('net','mask','gateway');
|
||||
foreach (@nets) {
|
||||
my $net = $_->{'net'};
|
||||
my $mask =$_->{'mask'};
|
||||
my $gw = $_->{'gateway'};
|
||||
$ip =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||
my $ipnum = ($1<<24)+($2<<16)+($3<<8)+$4;
|
||||
$mask =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||
my $masknum = ($1<<24)+($2<<16)+($3<<8)+$4;
|
||||
$net =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||
my $netnum = ($1<<24)+($2<<16)+($3<<8)+$4;
|
||||
if (($ipnum & $masknum)==$netnum) {
|
||||
return ($ip,$mask,$gw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $node = $request->{'!xcat_clienthost'}->[0];
|
||||
my $sitetable = xCAT::Table->new('site');
|
||||
my $ipmitable = xCAT::Table->new('ipmi');
|
||||
my $passtable = xCAT::Table->new('passwd');
|
||||
my $tmphash;
|
||||
my $username = 'USERID';
|
||||
my $gennedpassword=0;
|
||||
my $bmc;
|
||||
my $password = 'PASSW0RD';
|
||||
if ($passtable) { $tmphash=$passtable->getAttribs({key=>'ipmi'},'username','password'); }
|
||||
#Check for generics, can grab for both user and pass with a query
|
||||
#since they cannot be in disparate records in passwd tab
|
||||
if ($tmphash->{username}) {
|
||||
$username=$tmphash->{username};
|
||||
}
|
||||
if ($tmphash->{password}) { #It came for free with the last query
|
||||
$password=$tmphash->{password};
|
||||
}
|
||||
$tmphash=($sitetable->getAttribs({key=>'genpasswords'},'value'))[0];
|
||||
if ($tmphash->{value} eq "1" or $tmphash->{value} =~ /y(es)?/i) {
|
||||
$password = genpassword(8);
|
||||
$gennedpassword=1;
|
||||
} else {
|
||||
$tmphash=$ipmitable->getNodeAttribs($node,['password']);
|
||||
if ($tmphash->{password}) {
|
||||
$password = $tmphash->{password};
|
||||
}
|
||||
}
|
||||
$tmphash=$ipmitable->getNodeAttribs($node,['bmc','username']);
|
||||
if ($tmphash->{bmc} ) {
|
||||
$bmc=$tmphash->{bmc};
|
||||
}
|
||||
if ($tmphash->{username}) {
|
||||
$username = $tmphash->{username};
|
||||
}
|
||||
(my $ip,my $mask,my $gw) = net_parms($bmc);
|
||||
my $response={bmcip=>$ip,netmask=>$mask,gateway=>$gw,username=>$username,password=>$password};
|
||||
$callback->($response);
|
||||
if ($gennedpassword) { # save generated password
|
||||
$ipmitable->setNodeAttribs($node,{password=>$password});
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
207
xCAT-server-2.0/usr/lib/xcat/plugins/centos.pm
Normal file
207
xCAT-server-2.0/usr/lib/xcat/plugins/centos.pm
Normal file
@ -0,0 +1,207 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::centos;
|
||||
use Storable qw(dclone);
|
||||
use Sys::Syslog;
|
||||
use xCAT::Table;
|
||||
use xCAT::Template;
|
||||
use xCAT::Postage;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
|
||||
my %distnames = (
|
||||
"1176234647.982657" => "centos5",
|
||||
"1156364963.862322" => "centos4.4",
|
||||
"1178480581.024704" => "centos4.5"
|
||||
);
|
||||
my %numdiscs = (
|
||||
"1156364963.862322" => 4,
|
||||
"1178480581.024704" => 3
|
||||
);
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
copycd => "centos",
|
||||
mkinstall => "nodetype:os=centos.*"
|
||||
}
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $distname = undef;
|
||||
my $arch = undef;
|
||||
my $path = undef;
|
||||
if ($request->{command}->[0] eq 'copycd') {
|
||||
return copycd($request,$callback,$doreq);
|
||||
} elsif ($request->{command}->[0] eq 'mkinstall') {
|
||||
return mkinstall($request,$callback,$doreq);
|
||||
}
|
||||
}
|
||||
|
||||
sub mkinstall {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my @nodes = @{$request->{node}};
|
||||
my $node;
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
my %doneimgs;
|
||||
foreach $node (@nodes) {
|
||||
my $osinst;
|
||||
my $ent = $ostab->getNodeAttribs($node,['profile','os','arch']);
|
||||
unless ($ent->{os} and $ent->{arch} and $ent->{profile}) {
|
||||
$callback->({error=>["No profile defined in nodetype for $node"],errorcode=>[1]});
|
||||
next; #No profile
|
||||
}
|
||||
my $os = $ent->{os};
|
||||
my $arch = $ent->{arch};
|
||||
my $profile = $ent->{profile};
|
||||
unless (-r "/usr/share/xcat/install/centos/".$ent->{profile}.".tmpl") {
|
||||
$callback->({error=>["No kickstart template exists for ".$ent->{profile}],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
#Call the Template class to do substitution to produce a kickstart file in the autoinst dir
|
||||
xCAT::Template->subvars("/usr/share/xcat/install/centos/".$ent->{profile}.".tmpl","/install/autoinst/".$node,$node);
|
||||
mkpath "/install/postscripts/";
|
||||
xCAT::Postage->writescript($node,"/install/postscripts/".$node);
|
||||
if (-r "/install/$os/$arch/images/pxeboot/vmlinuz"
|
||||
and -r "/install/$os/$arch/images/pxeboot/initrd.img") {
|
||||
#TODO: driver slipstream, targetted for network.
|
||||
unless ($doneimgs{"$os|$arch"}) {
|
||||
mkpath("/tftpboot/xcat/$os/$arch");
|
||||
copy("/install/$os/$arch/images/pxeboot/vmlinuz","/tftpboot/xcat/$os/$arch/");
|
||||
copy("/install/$os/$arch/images/pxeboot/initrd.img","/tftpboot/xcat/$os/$arch/");
|
||||
$doneimgs{"$os|$arch"}=1;
|
||||
}
|
||||
#We have a shot...
|
||||
my $restab = xCAT::Table->new('noderes');
|
||||
my $hmtab = xCAT::Table->new('nodehm');
|
||||
my $ent = $restab->getNodeAttribs($node,['nfsserver','serialport','primarynic','installnic']);
|
||||
my $sent = $hmtab->getNodeAttribs($node,['serialspeed','serialflow']);
|
||||
unless ($ent and $ent->{nfsserver}) {
|
||||
$callback->({error=>["No noderes.nfsserver defined for ".$ent->{profile}],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
my $kcmdline="nofb utf8 ks=http://".$ent->{nfsserver}."/install/autoinst/".$node;
|
||||
if ($ent->{installnic}) {
|
||||
$kcmdline.=" ksdevice=".$ent->{installnic};
|
||||
} elsif ($ent->{primarynic}) {
|
||||
$kcmdline.=" ksdevice=".$ent->{primarynic};
|
||||
} else {
|
||||
$kcmdline .= " ksdevice=eth0";
|
||||
}
|
||||
|
||||
#TODO: dd=<url> for driver disks
|
||||
if (defined($ent->{serialport})) {
|
||||
unless ($sent->{serialspeed}) {
|
||||
$callback->({error=>["serialport defined, but no serialspeed for $node in nodehm table"],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
$kcmdline.=" console=ttyS".$ent->{serialport}.",".$sent->{serialspeed};
|
||||
if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/) {
|
||||
$kcmdline .= "n8r";
|
||||
}
|
||||
}
|
||||
$kcmdline .= " noipv6";
|
||||
|
||||
$restab->setNodeAttribs($node,{
|
||||
kernel=>"xcat/$os/$arch/vmlinuz",
|
||||
initrd=>"xcat/$os/$arch/initrd.img",
|
||||
kcmdline=>$kcmdline
|
||||
});
|
||||
} else {
|
||||
$callback->({error=>["Unable to find kernel and initrd for $os and $arch in install source /install/$os/$arch"],errorcode=>[1]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub copycd {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $installroot;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
if ($sitetab) {
|
||||
(my $ref) = $sitetab->getAttribs({key=>installdir},value);
|
||||
print Dumper($ref);
|
||||
if ($ref and $ref->{value}) {
|
||||
$installroot = $ref->{value};
|
||||
}
|
||||
}
|
||||
|
||||
@ARGV= @{$request->{arg}};
|
||||
GetOptions(
|
||||
'n=s' => \$distname,
|
||||
'a=s' => \$arch,
|
||||
'p=s' => \$path
|
||||
);
|
||||
unless ($path) {
|
||||
#this plugin needs $path...
|
||||
return;
|
||||
}
|
||||
if ($distname and $distname !~ /^centos/) {
|
||||
#If they say to call it something other than CentOS, give up?
|
||||
return;
|
||||
}
|
||||
unless (-r $path."/.discinfo") {
|
||||
return;
|
||||
}
|
||||
my $dinfo;
|
||||
open($dinfo,$path."/.discinfo");
|
||||
my $did = <$dinfo>;
|
||||
chomp($did);
|
||||
my $desc = <$dinfo>;
|
||||
chomp($desc);
|
||||
my $darch = <$dinfo>;
|
||||
chomp($darch);
|
||||
if ($darch and $darch =~ /i.86/) {
|
||||
$darch = "x86";
|
||||
}
|
||||
close($dinfo);
|
||||
if ($distnames{$did}) {
|
||||
unless ($distname) {
|
||||
$distname = $distnames{$did};
|
||||
}
|
||||
} elsif ($desc =~ /^Final$/) {
|
||||
unless ($distname) {
|
||||
$distname = "centos5";
|
||||
}
|
||||
} elsif ($desc =~ /^CentOS-4 .*/) {
|
||||
unless ($distname) {
|
||||
$distname = "centos4";
|
||||
}
|
||||
}
|
||||
|
||||
unless ($distname) {
|
||||
return; #Do nothing, not ours..
|
||||
}
|
||||
if ($darch) {
|
||||
unless ($arch) {
|
||||
$arch = $darch;
|
||||
}
|
||||
if ($arch and $arch ne $darch) {
|
||||
$callback->({error=>"Requested CentOS architecture $arch, but media is $darch"});
|
||||
return;
|
||||
}
|
||||
}
|
||||
%{$request} = (); #clear request we've got it.
|
||||
|
||||
$callback->({data=>"Copying media to $installroot/$distname/$arch/"});
|
||||
my $omask=umask 0022;
|
||||
mkpath("$installroot/$distname/$arch");
|
||||
umask $omask;
|
||||
my $rc = system("cd $path; find . | nice -n 20 cpio -dump $installroot/$distname/$arch");
|
||||
chmod 0755,"$installroot/$distname/$arch";
|
||||
if ($rc != 0) {
|
||||
$callback->({error=>"Media copy operation failed, status $rc"});
|
||||
} else {
|
||||
$callback->({data=>"Media copy operation successful"});
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
206
xCAT-server-2.0/usr/lib/xcat/plugins/conserver.pm
Normal file
206
xCAT-server-2.0/usr/lib/xcat/plugins/conserver.pm
Normal file
@ -0,0 +1,206 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#TODO: delete entries not being refreshed if no noderange
|
||||
package xCAT_plugin::conserver;
|
||||
use xCAT::Table;
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
my @cservers = qw(mrv cyclades);
|
||||
my %termservers; #list of noted termservers
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
makeconservercf => "conserver"
|
||||
}
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $req = shift;
|
||||
my $cb = shift;
|
||||
if ($req->{command}->[0] eq "makeconservercf") {
|
||||
makeconservercf($req,$cb);
|
||||
}
|
||||
}
|
||||
|
||||
sub docfheaders {
|
||||
# Put in standard headers common to all conserver.cf files
|
||||
my $content = shift;
|
||||
my $numlines = @$content;
|
||||
my @meat = grep(!/^#/,@$content);
|
||||
unless (grep(/^default full/,@meat)) {
|
||||
push @$content,"default full { rw *; }\n";
|
||||
}
|
||||
unless (grep(/^default cyclades/,@meat)) {
|
||||
push @$content,"default cyclades { type host; portbase 7000; portinc 1; }\n"
|
||||
}
|
||||
unless (grep(/^default mrv/,@meat)) {
|
||||
push @$content,"default mrv { type host; portbase 2000; portinc 100; }\n"
|
||||
}
|
||||
unless (grep(/^access \*/,@meat)) {
|
||||
#TODO: something intelligent, allowing other hosts in
|
||||
#push @$content,"#xCAT BEGIN ACCESS\n";
|
||||
push @$content,"access * {\n";
|
||||
push @$content," trusted 127.0.0.1;\n";
|
||||
push @$content,"}\n";
|
||||
#push @$content,"#xCAT END ACCESS\n";
|
||||
}
|
||||
unless (grep(/^default \*/,@meat)) {
|
||||
push @$content,"default * {\n";
|
||||
push @$content," logfile /var/log/consoles/&;\n";
|
||||
push @$content," timestamp 1hab;\n";
|
||||
push @$content," include full;\n";
|
||||
push @$content," master localhost;\n";
|
||||
push @$content,"}\n";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
sub makeconservercf {
|
||||
my $req = shift;
|
||||
%termservers = (); #clear hash of existing entries
|
||||
my $cb = shift;
|
||||
my $nodes = $req->{node};
|
||||
my $cfile;
|
||||
my @filecontent;
|
||||
open $cfile,'/etc/conserver.cf';
|
||||
while (<$cfile>) {
|
||||
push @filecontent,$_;
|
||||
}
|
||||
close $cfile;
|
||||
docfheaders(\@filecontent);
|
||||
my $hmtab = xCAT::Table->new('nodehm');
|
||||
my @cfgents = $hmtab->getAllNodeAttribs(['mgt','cons']);
|
||||
#cfgents should now have all the nodes, so we can fill in our hashes one at a time.
|
||||
foreach (@cfgents) {
|
||||
unless ($_->{cons}) {$_->{cons} = $_->{mgt};} #populate with fallback
|
||||
my $cmeth=$_->{cons};
|
||||
if (grep(/^$cmeth$/,@cservers)) { #terminal server, more attribs needed
|
||||
my $node = $_->{node};
|
||||
my $tent = $hmtab->getNodeAttribs($node,["termserver","termport"]);
|
||||
$_->{termserver} = $tent->{termserver};
|
||||
$termservers{$tent->{termserver}} = 1;
|
||||
$_->{termport}= $tent->{termport};
|
||||
}
|
||||
}
|
||||
if (($nodes and @$nodes > 0) or $req->{noderange}->[0]) {
|
||||
foreach (@$nodes) {
|
||||
my $node = $_;
|
||||
foreach (@cfgents) {
|
||||
if ($_->{node} eq $node) {
|
||||
if ($_->{termserver} and $termservers{$_->{termserver}}) {
|
||||
dotsent($_,\@filecontent);
|
||||
delete $termservers{$_->{termserver}}; #prevent needless cycles being burned
|
||||
}
|
||||
donodeent($_,\@filecontent);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { #no nodes specified, do em all up
|
||||
zapcfg(\@filecontent); # strip all xCAT configured stuff from config
|
||||
foreach (@cfgents) {
|
||||
if ($_->{termserver} and $termservers{$_->{termserver}}) {
|
||||
dotsent($_,\@filecontent);
|
||||
delete $termservers{$_->{termserver}}; #prevent needless cycles being burned
|
||||
}
|
||||
donodeent($_,\@filecontent);
|
||||
}
|
||||
}
|
||||
open $cfile,'>','/etc/conserver.cf';
|
||||
foreach (@filecontent) {
|
||||
print $cfile $_;
|
||||
}
|
||||
close $cfile;
|
||||
}
|
||||
|
||||
sub dotsent {
|
||||
my $cfgent = shift;
|
||||
my $tserv = $cfgent->{termserver};
|
||||
my $content = shift;
|
||||
my $idx = 0;
|
||||
my $toidx = -1;
|
||||
my $skip = 0;
|
||||
my $skipnext = 0;
|
||||
while ($idx < $#$content) { # Go through and delete that which would match my entry
|
||||
if ($content->[$idx] =~ /^#xCAT BEGIN $tserv TS/) {
|
||||
$toidx=$idx; #TODO put it back right where I found it
|
||||
$skip = 1;
|
||||
$skipnext=1;
|
||||
} elsif ($content->[$idx] =~ /^#xCAT END $tserv TS/) {
|
||||
$skipnext = 0;
|
||||
}
|
||||
if ($skip) {
|
||||
splice (@$content,$idx,1);
|
||||
} else {
|
||||
$idx++;
|
||||
}
|
||||
$skip = $skipnext;
|
||||
}
|
||||
push @$content,"#xCAT BEGIN $tserv TS\n";
|
||||
push @$content,"default $tserv {\n";
|
||||
push @$content," include ".$cfgent->{cons}.";\n";
|
||||
push @$content," host $tserv;\n";
|
||||
push @$content,"}\n";
|
||||
push @$content,"#xCAT END $tserv TS\n";
|
||||
}
|
||||
sub donodeent {
|
||||
my $cfgent = shift;
|
||||
my $node = $cfgent->{node};
|
||||
my $content = shift;
|
||||
my $idx=0;
|
||||
my $toidx=-1;
|
||||
my $skip = 0;
|
||||
my $skipnext = 0;
|
||||
while ($idx < $#$content) { # Go through and delete that which would match my entry
|
||||
if ($content->[$idx] =~ /^#xCAT BEGIN $node CONS/) {
|
||||
$toidx=$idx; #TODO put it back right where I found it
|
||||
$skip = 1;
|
||||
$skipnext=1;
|
||||
} elsif ($content->[$idx] =~ /^#xCAT END $node CONS/) {
|
||||
$skipnext = 0;
|
||||
}
|
||||
if ($skip) {
|
||||
splice (@$content,$idx,1);
|
||||
} else {
|
||||
$idx++;
|
||||
}
|
||||
$skip = $skipnext;
|
||||
}
|
||||
push @$content,"#xCAT BEGIN $node CONS\n";
|
||||
push @$content,"console $node {\n";
|
||||
#if ($cfgent->{cons}
|
||||
my $cmeth=$cfgent->{cons};
|
||||
print $cmeth."\n";
|
||||
if (grep(/^$cmeth$/,@cservers)) {
|
||||
push @$content," include ".$cfgent->{termserver}.";\n";
|
||||
push @$content," port ".$cfgent->{termport}.";\n";
|
||||
} else { #a script method...
|
||||
push @$content," type exec;\n";
|
||||
push @$content," exec /usr/share/xcat/cons/".$cmeth." ".$node.";\n"
|
||||
}
|
||||
push @$content,"}\n";
|
||||
push @$content,"#xCAT END $node CONS\n";
|
||||
}
|
||||
|
||||
sub zapcfg {
|
||||
my $content = shift;
|
||||
my $idx=0;
|
||||
my $toidx=-1;
|
||||
my $skip = 0;
|
||||
my $skipnext = 0;
|
||||
while ($idx <= $#$content) { # Go through and delete that which would match my entry
|
||||
if ($content->[$idx] =~ /^#xCAT BEGIN/) {
|
||||
$toidx=$idx; #TODO put it back right where I found it
|
||||
$skip = 1;
|
||||
$skipnext=1;
|
||||
} elsif ($content->[$idx] =~ /^#xCAT END/) {
|
||||
$skipnext = 0;
|
||||
}
|
||||
if ($skip) {
|
||||
splice (@$content,$idx,1);
|
||||
} else {
|
||||
$idx++;
|
||||
}
|
||||
$skip = $skipnext;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
70
xCAT-server-2.0/usr/lib/xcat/plugins/copycds.pm
Normal file
70
xCAT-server-2.0/usr/lib/xcat/plugins/copycds.pm
Normal file
@ -0,0 +1,70 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::copycds;
|
||||
use Storable qw(dclone);
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
my $processed = 0;
|
||||
my $callback;
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
copycds => "copycds",
|
||||
}
|
||||
}
|
||||
|
||||
sub take_answer {
|
||||
#TODO: Intelligently filter and decide things
|
||||
my $resp = shift;
|
||||
$callback->($resp);
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
$callback = shift;
|
||||
my $doreq = shift;
|
||||
my $distname = undef;
|
||||
my $arch = undef;
|
||||
|
||||
@ARGV = @{$request->{arg}};
|
||||
GetOptions(
|
||||
'n|name|osver=s' => \$distname,
|
||||
'a|arch=s' => \$arch
|
||||
);
|
||||
if ($arch and $arch =~ /i.86/) {
|
||||
$arch = x86;
|
||||
}
|
||||
my @args = @ARGV; #copy ARGV
|
||||
unless ($#args >= 0) {
|
||||
$callback->({error=>"copycds needs at least one full path to ISO currently."});
|
||||
return;
|
||||
}
|
||||
foreach (@args) {
|
||||
unless (-r $_ and -f $_) {
|
||||
$callback->({error=>"copycds currently only understands FULL path to iso files, $_ not processed"});
|
||||
return;
|
||||
}
|
||||
mkdir "/mnt/xcat";
|
||||
if (system("mount -o loop $_ /mnt/xcat")) {
|
||||
$callback->({error=>"copycds was unable to examine $_ as an install image"});
|
||||
return;
|
||||
}
|
||||
my $newreq = dclone($request);
|
||||
$newreq->{command}= [ 'copycd' ]; #Note the singular, it's different
|
||||
$newreq->{arg} = ["-p","/mnt/xcat"];
|
||||
if ($distname) {
|
||||
push @{$newreq->{arg}},("-n",$distname);
|
||||
}
|
||||
if ($arch) {
|
||||
push @{$newreq->{arg}},("-a",$arch);
|
||||
}
|
||||
$doreq->($newreq,\&take_answer);
|
||||
|
||||
system("umount /mnt/xcat");
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
239
xCAT-server-2.0/usr/lib/xcat/plugins/destiny.pm
Normal file
239
xCAT-server-2.0/usr/lib/xcat/plugins/destiny.pm
Normal file
@ -0,0 +1,239 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::destiny;
|
||||
use xCAT::NodeRange;
|
||||
use Data::Dumper;
|
||||
use Sys::Syslog;
|
||||
use strict;
|
||||
|
||||
my $request;
|
||||
my $callback;
|
||||
my $subreq;
|
||||
my $errored = 0;
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
setdestiny => "destiny",
|
||||
getdestiny => "destiny",
|
||||
nextdestiny => "destiny"
|
||||
}
|
||||
}
|
||||
sub process_request {
|
||||
$request = shift;
|
||||
$callback = shift;
|
||||
$subreq = shift;
|
||||
if ($request->{command}->[0] eq 'getdestiny') {
|
||||
getdestiny();
|
||||
}
|
||||
if ($request->{command}->[0] eq 'nextdestiny') {
|
||||
nextdestiny($request);
|
||||
}
|
||||
if ($request->{command}->[0] eq 'setdestiny') {
|
||||
setdestiny($request);
|
||||
}
|
||||
}
|
||||
|
||||
sub relay_response {
|
||||
my $resp = shift;
|
||||
$callback->($resp);
|
||||
if ($resp and $resp->{errorcode} and $resp->{errorcode}->[0]) {
|
||||
$errored = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub setdestiny {
|
||||
my $req=shift;
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
my @nodes=@{$req->{node}};
|
||||
my $state = $req->{arg}->[0];
|
||||
if ($state eq "next") {
|
||||
return nextdestiny();
|
||||
} elsif ($state =~ /^install$/ or $state eq "install") {
|
||||
my $nodetype = xCAT::Table->new('nodetype');
|
||||
foreach (@{$req->{node}}) {
|
||||
my $ntent = $nodetype->getNodeAttribs($_,[qw(os arch profile)]);
|
||||
if ($ntent and $ntent->{os}) {
|
||||
$state = "install ".$ntent->{os};
|
||||
}
|
||||
if ($ntent and $ntent->{arch}) {
|
||||
$state .= "-".$ntent->{arch};
|
||||
}
|
||||
if ($ntent and $ntent->{profile}) {
|
||||
$state .= "-".$ntent->{profile};
|
||||
}
|
||||
$chaintab->setNodeAttribs($_,{currchain=>"boot"});
|
||||
}
|
||||
$subreq->({command=>["mkinstall"],
|
||||
node=>$req->{node}}, \&relay_response);
|
||||
if ($errored) { return; }
|
||||
} elsif ($state eq "shell" or $state eq "standby" or $state =~ /^runcmd/) {
|
||||
my $noderes=xCAT::Table->new('noderes');
|
||||
my $nodetype = xCAT::Table->new('nodetype');
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
(my $portent) = $sitetab->getAttribs({key=>'xcatdport'},'value');
|
||||
(my $mastent) = $sitetab->getAttribs({key=>'master'},'value');
|
||||
foreach (@nodes) {
|
||||
my $ent = $nodetype->getNodeAttribs($_,[qw(arch)]);
|
||||
unless ($ent and $ent->{arch}) {
|
||||
$callback->({error=>["No archictecture defined in nodetype table for $_"],errorcode=>[1]});
|
||||
return;
|
||||
}
|
||||
my $arch = $ent->{arch};
|
||||
my $ent = $noderes->getNodeAttribs($_,[qw(xcatmaster)]);
|
||||
my $master;
|
||||
if ($mastent and $mastent->{value}) {
|
||||
$master = $mastent->{value};
|
||||
}
|
||||
if ($ent and $ent->{xcatmaster}) {
|
||||
$master = $ent->{xcatmaster};
|
||||
}
|
||||
unless ($master) {
|
||||
$callback->({error=>["No master in site table nor noderes table for $_"],errorcode=>[1]});
|
||||
return;
|
||||
}
|
||||
my $xcatdport="3001";
|
||||
if ($portent and $portent->{value}) {
|
||||
$xcatdport = $portent->{value};
|
||||
}
|
||||
$noderes->setNodeAttribs($_,{kernel => "xcat/nbk.$arch",
|
||||
initrd => "xcat/nbfs.$arch.gz",
|
||||
kcmdline => "xcatd=$master:$xcatdport"});
|
||||
}
|
||||
$nodetype->close;
|
||||
} elsif (!($state eq "boot")) {
|
||||
$callback->({error=>["Unknown state $state requested"],errorcode=>[1]});
|
||||
return;
|
||||
}
|
||||
foreach (@nodes) {
|
||||
$chaintab->setNodeAttribs($_,{currstate=>$state});
|
||||
}
|
||||
return getdestiny();
|
||||
}
|
||||
|
||||
|
||||
sub nextdestiny {
|
||||
my @nodes;
|
||||
if ($request and $request->{node}) {
|
||||
if (ref($request->{node})) {
|
||||
@nodes = @{$request->{node}};
|
||||
} else {
|
||||
@nodes = ($request->{node});
|
||||
}
|
||||
#TODO: service third party getdestiny..
|
||||
} else { #client asking to move along its own chain
|
||||
#TODO: SECURITY with this, any one on a node could advance the chain, for node, need to think of some strategy to deal with...
|
||||
unless ($request->{'!xcat_clienthost'}->[0]) {
|
||||
#ERROR? malformed request
|
||||
return; #nothing to do here...
|
||||
}
|
||||
my $node = $request->{'!xcat_clienthost'}->[0];
|
||||
($node) = noderange($node);
|
||||
unless ($node) {
|
||||
#not a node, don't trust it
|
||||
return;
|
||||
}
|
||||
@nodes=($node);
|
||||
}
|
||||
|
||||
my $node;
|
||||
foreach $node (@nodes) {
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
unless($chaintab) {
|
||||
syslog("local1|err","ERROR: $node requested destiny update, no chain table");
|
||||
return; #nothing to do...
|
||||
}
|
||||
my $ref = $chaintab->getNodeAttribs($node,[qw(currstate currchain chain)]);
|
||||
unless ($ref->{chain}) {
|
||||
syslog ("currchain local1|err","ERROR: node requested destiny update, no path in chain.currchain");
|
||||
$chaintab->close;
|
||||
return; #Can't possibly do anything intelligent..
|
||||
}
|
||||
unless ($ref->{currchain}) { #If no current chain, copy the default
|
||||
$ref->{currchain} = $ref->{chain};
|
||||
}
|
||||
my @chain = split /[,:;]/,$ref->{currchain};
|
||||
|
||||
$ref->{currstate} = shift @chain;
|
||||
$ref->{currchain}=join(',',@chain);
|
||||
unless ($ref->{currchain}) { #If we've gone off the end of the chain, have currchain stick
|
||||
$ref->{currchain} = $ref->{currstate};
|
||||
}
|
||||
$chaintab->setNodeAttribs($node,$ref); #$ref is in a state to commit back to db
|
||||
$chaintab->close;
|
||||
my %requ;
|
||||
$requ{node}=[$node];
|
||||
$requ{arg}=[$ref->{currstate}];
|
||||
setdestiny(\%requ);
|
||||
getdestiny();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub getdestiny {
|
||||
my @args;
|
||||
my @nodes;
|
||||
if ($request->{node}) {
|
||||
if (ref($request->{node})) {
|
||||
@nodes = @{$request->{node}};
|
||||
} else {
|
||||
@nodes = ($request->{node});
|
||||
}
|
||||
} else { # a client asking for it's own destiny.
|
||||
unless ($request->{'!xcat_clienthost'}->[0]) {
|
||||
$callback->({destiny=>[ 'discover' ]});
|
||||
return;
|
||||
}
|
||||
my ($node) = noderange($request->{'!xcat_clienthost'}->[0]);
|
||||
unless ($node) { # it had a valid hostname, but isn't a node
|
||||
$callback->({destiny=>[ 'discover' ]});
|
||||
return;
|
||||
}
|
||||
@nodes=($node);
|
||||
}
|
||||
my $node;
|
||||
foreach $node (@nodes) {
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
unless ($chaintab) { #Without destiny, have the node wait with ssh hopefully open at least
|
||||
$callback->({node=>[{name=>[$node],data=>['standby'],destiny=>[ 'standby' ]}]});
|
||||
return;
|
||||
}
|
||||
my $ref = $chaintab->getNodeAttribs($node,[qw(currstate chain)]);
|
||||
unless ($ref) {
|
||||
$callback->({node=>[{name=>[$node],data=>['standby'],destiny=>[ 'standby' ]}]});
|
||||
return;
|
||||
}
|
||||
unless ($ref->{currstate}) { #Has a record, but not yet in a state...
|
||||
my @chain = split /,/,$ref->{chain};
|
||||
$ref->{currstate} = shift @chain;
|
||||
$chaintab->setNodeAttribs($node,{currstate=>$ref->{currstate}});
|
||||
}
|
||||
my $noderestab = xCAT::Table->new('noderes'); #In case client decides to download images, get data out to it
|
||||
my %response;
|
||||
$response{name}=[$node];
|
||||
$response{data}=[$ref->{currstate}];
|
||||
$response{destiny}=[$ref->{currstate}];
|
||||
my $sitetab= xCAT::Table->new('site');
|
||||
my $nrent = $noderestab->getNodeAttribs($node,[qw(tftpserver kernel initrd kcmdline xcatmaster)]);
|
||||
(my $sent) = $sitetab->getAttribs({key=>'master'},'value');
|
||||
if (defined $nrent->{kernel}) {
|
||||
$response{kernel}=$nrent->{kernel};
|
||||
}
|
||||
if (defined $nrent->{initrd}) {
|
||||
$response{initrd}=$nrent->{initrd};
|
||||
}
|
||||
if (defined $nrent->{kcmdline}) {
|
||||
$response{kcmdline}=$nrent->{kcmdline};
|
||||
}
|
||||
if (defined $nrent->{tftpserver}) {
|
||||
$response{imgserver}=$nrent->{tftpserver};
|
||||
} elsif (defined $nrent->{xcatmaster}) {
|
||||
$response{imgserver}=$nrent->{xcatmaster};
|
||||
} elsif (defined($sent->{value})) {
|
||||
$response{imgserver}=$sent->{value};
|
||||
}
|
||||
|
||||
$callback->({node=>[\%response]});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
333
xCAT-server-2.0/usr/lib/xcat/plugins/dhcp.pm
Normal file
333
xCAT-server-2.0/usr/lib/xcat/plugins/dhcp.pm
Normal file
@ -0,0 +1,333 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::dhcp;
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
use MIME::Base64;
|
||||
use Socket;
|
||||
use Sys::Syslog;
|
||||
use IPC::Open2;
|
||||
|
||||
my @dhcpconf; #Hold DHCP config file contents to be written back.
|
||||
my @nrn; # To hold output of netstat -rn to be consulted throughout process
|
||||
my $domain;
|
||||
my $omshell;
|
||||
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
makedhcp => "dhcp",
|
||||
}
|
||||
}
|
||||
|
||||
sub delnode {
|
||||
my $node = shift;
|
||||
my $inetn = inet_aton($node);
|
||||
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set name = \"$node\"\n"; #Find and destroy conflict name
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
if ($inetn) {
|
||||
my $ip = inet_ntoa(inet_aton($node));;
|
||||
unless ($ip) { return; }
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set ip-address = $ip\n"; #find and destroy ip conflict
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub addnode {
|
||||
#Use omshell to add the node.
|
||||
#the process used is blind typing commands that should work
|
||||
#it tries to delet any conflicting entries matched by name and
|
||||
#hardware address and ip address before creating a brand now one
|
||||
#unfortunate side effect: dhcpd.leases can look ugly over time, when
|
||||
#doing updates would keep it cleaner, good news, dhcpd restart cleans
|
||||
#up the lease file the way we would want anyway.
|
||||
my $node = shift;
|
||||
my $ent;
|
||||
my $mactab = xCAT::Table->new('mac');
|
||||
unless ($mactab) { return; } #TODO: report error sanely
|
||||
$ent = $mactab->getNodeAttribs($node,[qw(mac interface)]);
|
||||
unless ($ent and $ent->{mac}) {
|
||||
return; #TODO: sane error
|
||||
}
|
||||
my $inetn = inet_aton($node);
|
||||
unless ($inetn) {
|
||||
syslog("local1|err","xCAT DHCP plugin unable to resolve IP for $node");
|
||||
return;
|
||||
}
|
||||
my $ip = inet_ntoa(inet_aton($node));;
|
||||
print "Setting $node ($ip) to ".$ent->{mac}."\n";
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set name = \"$node\"\n"; #Find and destroy conflict name
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set ip-address = $ip\n"; #find and destroy ip conflict
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set hardware-address = ".$ent->{mac}."\n"; #find and destroy mac conflict
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set name = \"$node\"\n";
|
||||
print $omshell "set hardware-address = ".$ent->{mac}."\n";
|
||||
print $omshell "set hardware-type = 1\n";
|
||||
print $omshell "set ip-address = $ip\n";
|
||||
print $omshell "create\n";
|
||||
unless (grep /#definition for host $node/,@dhcpconf) {
|
||||
push @dhcpconf,"#definition for host $node can be found in the dhcpd.leases file\n";
|
||||
}
|
||||
}
|
||||
sub process_request {
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
my %activenics;
|
||||
my $querynics=1;
|
||||
if ($sitetab) {
|
||||
my $href;
|
||||
($href) = $sitetab->getAttribs({key=>'dhcpinterfaces'},'value');
|
||||
unless ($href and $href->{value}) { #LEGACY: singular keyname for old style site value
|
||||
($href) = $sitetab->getAttribs({key=>'dhcpinterface'},'value');
|
||||
}
|
||||
if ($href and $href->{value}) {
|
||||
foreach (split /[,\s]+/,$href->{value}) {
|
||||
$activenics{$_} = 1;
|
||||
$querynics=0;
|
||||
}
|
||||
}
|
||||
($href) = $sitetab->getAttribs({key=>'domain'},'value');
|
||||
unless ($href and $href->{value}) {
|
||||
$callback->({error=>["No domain defined in site tabe"],errorcode=>[1]});
|
||||
return;
|
||||
}
|
||||
$domain = $href->{value};
|
||||
}
|
||||
|
||||
@dhcpconf = ();
|
||||
unless ($req->{arg} or $req->{node}) {
|
||||
$callback->({data=>["Usage: makedhcp <-n> <noderange>"]});
|
||||
return;
|
||||
}
|
||||
if (grep /-n/,@{$req->{arg}}) {
|
||||
if (-e "/etc/dhcpd.conf") {
|
||||
my $bakname = "/etc/dhcpd.conf.xcatbak";
|
||||
while (-e $bakname) { #look for unused backup name..
|
||||
$bakname .= "~";
|
||||
}
|
||||
rename("/etc/dhcpd.conf",$bakname);
|
||||
}
|
||||
} else {
|
||||
open($rconf,"/etc/dhcpd.conf"); # Read file into memory
|
||||
if ($rconf) {
|
||||
while (<$rconf>) {
|
||||
push @dhcpconf,$_;
|
||||
}
|
||||
close($rconf);
|
||||
}
|
||||
unless ($dhcpconf[0] =~ /^#xCAT/) { #Discard file if not xCAT originated, like 1.x did
|
||||
@dhcpconf = ();
|
||||
}
|
||||
}
|
||||
@nrn = split /\n/,`/bin/netstat -rn`;
|
||||
splice @nrn,0,2; #get rid of header
|
||||
if ($querynics) { #Use netstat to determine activenics only when no site ent.
|
||||
foreach (@nrn) {
|
||||
my @ent = split /\s+/;
|
||||
if ($ent[7] =~ m/(ipoib|ib|vlan|bond|eth|myri|man|wlan)/) { #Mask out many types of interfaces, like xCAT 1.x
|
||||
$activenics{$ent[7]} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
unless ($dhcpconf[0]) { #populate an empty config with some starter data...
|
||||
newconfig();
|
||||
}
|
||||
foreach (keys %activenics) {
|
||||
addnic($_);
|
||||
}
|
||||
if ($req->{node}) {
|
||||
my $passtab = xCAT::Table->new('passwd');
|
||||
my $ent;
|
||||
($ent) = $passtab->getAttribs({key=>"omapi"},qw(username password));
|
||||
unless ($ent->{username} and $ent->{password}) { return; } # TODO sane err
|
||||
#Have nodes to update
|
||||
#open2($omshellout,$omshell,"/usr/bin/omshell");
|
||||
open($omshell,"|/usr/bin/omshell > /dev/null");
|
||||
|
||||
print $omshell "key ".$ent->{username}." \"".$ent->{password}."\"\n";
|
||||
print $omshell "connect\n";
|
||||
foreach(@{$req->{node}}) {
|
||||
if (grep /^-d$/,@{$req->{arg}}) {
|
||||
delnode $_;
|
||||
} else {
|
||||
addnode $_;
|
||||
}
|
||||
}
|
||||
close($omshell);
|
||||
}
|
||||
foreach (@nrn) {
|
||||
my @line = split /\s+/;
|
||||
if ($activenics{$line[7]}) {
|
||||
addnet($line[0],$line[2]);
|
||||
}
|
||||
}
|
||||
writeout();
|
||||
}
|
||||
|
||||
sub addnet {
|
||||
my $net = shift;
|
||||
my $mask = shift;
|
||||
my $nic;
|
||||
unless (grep /\} # $net\/$mask subnet_end/,@dhcpconf) {
|
||||
foreach (@nrn) { # search for relevant NIC
|
||||
my @ent = split /\s+/;
|
||||
if ($ent[0] eq $net and $ent[2] eq $mask) {
|
||||
$nic=$ent[7];
|
||||
}
|
||||
}
|
||||
print "Need to add $net $mask under $nic\n";
|
||||
my $idx=0;
|
||||
while ($idx <= $#dhcpconf) {
|
||||
if ($dhcpconf[$idx] =~ /\} # $nic nic_end\n/) {
|
||||
last;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
unless ($dhcpconf[$idx] =~ /\} # $nic nic_end\n/) {
|
||||
return 1; #TODO: this is an error condition
|
||||
}
|
||||
# if here, means we found the idx before which to insert
|
||||
my $nettab = xCAT::Table->new("networks");
|
||||
my $nameservers;
|
||||
my $gateway;
|
||||
my $tftp;
|
||||
my $range;
|
||||
if ($nettab) {
|
||||
my ($ent) = $nettab->getAttribs({net=>$net,mask=>$mask},qw(tftpserver nameservers gateway dynamicrange));
|
||||
if ($ent and $ent->{nameservers}) {
|
||||
$nameservers = $ent->{nameservers};
|
||||
}
|
||||
if ($ent and $ent->{tftpserver}) {
|
||||
$tftp = $ent->{tftpserver};
|
||||
}
|
||||
if ($ent and $ent->{gateway}) {
|
||||
$gateway = $ent->{gateway};
|
||||
}
|
||||
if ($ent and $ent->{dynamicrange}) {
|
||||
$range = $ent->{dynamicrange};
|
||||
$range =~ s/[,-]/ /g;
|
||||
}
|
||||
}
|
||||
my @netent;
|
||||
@netent = (
|
||||
" subnet $net netmask $mask {\n",
|
||||
" max-lease-time 43200;\n",
|
||||
" min-lease-time 43200;\n",
|
||||
" default-lease-time 43200;\n"
|
||||
);
|
||||
if ($gateway) {
|
||||
push @netent," option routers $gateway;\n";
|
||||
}
|
||||
if ($tftp) {
|
||||
push @netent," next-server $tftp;\n";
|
||||
}
|
||||
push @netent," option domain-name \"$domain\";\n";
|
||||
if ($nameservers) {
|
||||
push @netent," option domain-name-servers $nameservers;\n";
|
||||
}
|
||||
push @netent," if option client-architecture = 00:00 { #x86\n";
|
||||
push @netent," filename \"pxelinux.0\";\n";
|
||||
push @netent," } else if option client-architecture = 00:02 { #ia64\n ";
|
||||
push @netent," filename \"elilo.efi\";\n";
|
||||
push @netent," } else if substring(filename,0,1) = null { #otherwise, provide yaboot if the client isn't specific\n ";
|
||||
push @netent," filename \"yaboot\";\n";
|
||||
push @netent," }\n";
|
||||
if ($range) { push @netent," range dynamic-bootp $range;\n" };
|
||||
push @netent," } # $net\/$mask subnet_end\n";
|
||||
splice(@dhcpconf,$idx,0,@netent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sub addnic {
|
||||
my $nic = shift;
|
||||
my $firstindex=0;
|
||||
my $lastindex=0;
|
||||
unless (grep /} # $nic nic_end/,@dhcpconf) { #add a section if not there
|
||||
print "Adding NIC $nic\n";
|
||||
push @dhcpconf,"shared-network $nic {\n";
|
||||
push @dhcpconf,"\} # $nic nic_end\n";
|
||||
}
|
||||
#return; #Don't touch it, it should already be fine..
|
||||
#my $idx=0;
|
||||
#while ($idx <= $#dhcpconf) {
|
||||
# if ($dhcpconf[$idx] =~ /^shared-network $nic {/) {
|
||||
# $firstindex = $idx; # found the first place to chop...
|
||||
# } elsif ($dhcpconf[$idx] =~ /} # $nic network_end/) {
|
||||
# $lastindex=$idx;
|
||||
# }
|
||||
# $idx++;
|
||||
#}
|
||||
#print Dumper(\@dhcpconf);
|
||||
#if ($firstindex and $lastindex) {
|
||||
# splice @dhcpconf,$firstindex,($lastindex-$firstindex+1);
|
||||
#}
|
||||
#print Dumper(\@dhcpconf);
|
||||
}
|
||||
|
||||
|
||||
sub writeout {
|
||||
my $targ;
|
||||
open($targ,'>',"/etc/dhcpd.conf");
|
||||
foreach (@dhcpconf) {
|
||||
print $targ $_;
|
||||
}
|
||||
close($targ)
|
||||
}
|
||||
|
||||
sub newconfig {
|
||||
# This function puts a standard header in and enough to make omapi work.
|
||||
my $passtab = xCAT::Table->new('passwd',-create=>1);
|
||||
push @dhcpconf,"#xCAT generated dhcp configuration\n";
|
||||
push @dhcpconf,"\n";
|
||||
push @dhcpconf,"authoritative;\n";
|
||||
push @dhcpconf,"ddns-update-style none;\n";
|
||||
push @dhcpconf,"option client-architecture code 93 = unsigned integer 16;\n";
|
||||
push @dhcpconf,"\n";
|
||||
push @dhcpconf,"omapi-port 7911;\n"; #Enable omapi...
|
||||
push @dhcpconf,"key xcat_key {\n";
|
||||
push @dhcpconf," algorithm hmac-md5;\n";
|
||||
my $secret = encode_base64(genpassword(32)); #Random from set of 62^32
|
||||
chomp $secret;
|
||||
$passtab->setAttribs({key=>omapi},{username=>'xcat_key',password=>$secret});
|
||||
push @dhcpconf," secret \"".$secret."\";\n";
|
||||
push @dhcpconf,"};\n";
|
||||
push @dhcpconf,"omapi-key xcat_key;\n";
|
||||
}
|
||||
|
||||
sub genpassword {
|
||||
#Generate a pseudo-random password of specified length
|
||||
my $length = shift;
|
||||
my $password='';
|
||||
my $characters= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
|
||||
srand; #have to reseed, rand is not rand otherwise
|
||||
while (length($password) < $length) {
|
||||
$password .= substr($characters,int(rand 63),1);
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
|
||||
1;
|
88
xCAT-server-2.0/usr/lib/xcat/plugins/hosts.pm
Normal file
88
xCAT-server-2.0/usr/lib/xcat/plugins/hosts.pm
Normal file
@ -0,0 +1,88 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::hosts;
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
|
||||
my @hosts; #Hold /etc/hosts data to be written back
|
||||
|
||||
|
||||
my %usage=(
|
||||
makehosts => "Usage: makehosts [-n] <noderange>",
|
||||
);
|
||||
sub handled_commands {
|
||||
return {
|
||||
makehosts => "hosts",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub addnode {
|
||||
my $node = shift;
|
||||
my $ip = shift;
|
||||
my $othernames = shift;
|
||||
my $idx=0;
|
||||
my $foundone=0;
|
||||
|
||||
while ($idx <= $#hosts) {
|
||||
if ($hosts[$idx] =~ /^${ip}\s/ or $hosts[$idx] =~ /^\d+\.\d+\.\d+\.\d+\s+${node}\s/) {
|
||||
#TODO: if foundone, delete a dupe
|
||||
$hosts[$idx] = "$ip $node $othernames\n";
|
||||
$foundone=1;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
if ($foundone) { return;}
|
||||
push @hosts,"$ip $node $othernames\n";
|
||||
}
|
||||
sub process_request {
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
my $hoststab = xCAT::Table->new('hosts');
|
||||
@hosts = ();
|
||||
if (grep /-h/,@{$req->{arg}}) {
|
||||
$callback->({data=>$usage{makehosts}});
|
||||
return;
|
||||
}
|
||||
if (grep /-n/,@{$req->{arg}}) {
|
||||
if (-e "/etc/hosts") {
|
||||
my $bakname = "/etc/hosts.xcatbak";
|
||||
while (-e $bakname) { #look for unused backup name..
|
||||
$bakname .= "~";
|
||||
}
|
||||
rename("/etc/hosts",$bakname);
|
||||
}
|
||||
} else {
|
||||
open($rconf,"/etc/hosts"); # Read file into memory
|
||||
if ($rconf) {
|
||||
while (<$rconf>) {
|
||||
push @hosts,$_;
|
||||
}
|
||||
close($rconf);
|
||||
}
|
||||
}
|
||||
|
||||
if ($req->{node}) {
|
||||
foreach(@{$req->{node}}) {
|
||||
my $ref = $hoststab->getNodeAttribs($_,[qw(ip node hostnames)]);
|
||||
addnode $ref->{node},$ref->{ip},$ref->{hostnames};
|
||||
}
|
||||
} else {
|
||||
my @hostents = $hoststab->getAllNodeAttribs(['ip','node','hostnames']);
|
||||
foreach (@hostents) {
|
||||
addnode $_->{node},$_->{ip},$_->{hostnames};
|
||||
}
|
||||
}
|
||||
writeout();
|
||||
}
|
||||
|
||||
|
||||
sub writeout {
|
||||
my $targ;
|
||||
open($targ,'>',"/etc/hosts");
|
||||
foreach (@hosts) {
|
||||
print $targ $_;
|
||||
}
|
||||
close($targ)
|
||||
}
|
||||
|
||||
1;
|
4447
xCAT-server-2.0/usr/lib/xcat/plugins/ipmi.pm
Normal file
4447
xCAT-server-2.0/usr/lib/xcat/plugins/ipmi.pm
Normal file
File diff suppressed because it is too large
Load Diff
82
xCAT-server-2.0/usr/lib/xcat/plugins/networks.pm
Normal file
82
xCAT-server-2.0/usr/lib/xcat/plugins/networks.pm
Normal file
@ -0,0 +1,82 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::networks;
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
use Sys::Syslog;
|
||||
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
makenetworks => "networks",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub process_request {
|
||||
my $nettab = xCAT::Table->new('networks',-create=>1,-autocommit=>0);
|
||||
my @rtable = split /\n/,`/bin/netstat -rn`;
|
||||
open($rconf,"/etc/resolv.conf");
|
||||
my @nameservers;
|
||||
if ($rconf) {
|
||||
my @rcont;
|
||||
while (<$rconf>) {
|
||||
push @rcont,$_;
|
||||
}
|
||||
close($rconf);
|
||||
foreach (grep /nameserver/,@rcont) {
|
||||
my $line = $_;
|
||||
my @pair;
|
||||
$line =~ s/#.*//;
|
||||
@pair = split(/\s+/,$line);
|
||||
push @nameservers,$pair[1];
|
||||
}
|
||||
}
|
||||
splice @rtable,0,2;
|
||||
foreach (@rtable) { #should be the lines to think about, do something with U, and something else with UG
|
||||
my $net;
|
||||
my $mask;
|
||||
my $gw;
|
||||
my @ent = split /\s+/,$_;
|
||||
if ($ent[3] eq 'U') {
|
||||
$net = $ent[0];
|
||||
$mask = $ent[2];
|
||||
$nettab->setAttribs({'net'=>$net},{'mask'=>$mask});
|
||||
my $tent = $nettab->getAttribs({'net'=>$net},nameservers);
|
||||
unless ($tent and $tent->{nameservers}) {
|
||||
my $text = join ',',@nameservers;
|
||||
$nettab->setAttribs({'net'=>$net},{nameservers=>$text});
|
||||
}
|
||||
unless ($tent and $tent->{tftpserver}) {
|
||||
my $netdev=$ent[7];
|
||||
my @netlines = split/\n/,`/sbin/ip addr show dev $netdev`;
|
||||
foreach (grep /\s*inet\b/,@netlines) {
|
||||
my @row = split(/\s+/,$_);
|
||||
my $ipaddr = $row[2];
|
||||
$ipaddr =~ s/\/.*//;
|
||||
my @maska=split(/\./,$mask);
|
||||
my @ipa=split(/\./,$ipaddr);
|
||||
my @neta=split(/\./,$net);
|
||||
my $isme=1;
|
||||
foreach (0..3) {
|
||||
my $oct = (0+$maska[$_]) & ($ipa[$_]+0);
|
||||
unless ($oct == $neta[$_]) {
|
||||
$isme=0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($isme) {
|
||||
$nettab->setAttribs({'net'=>$net},{tftpserver=>$ipaddr});
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
$nettab->commit;
|
||||
#Nothing much sane to do for the other fields at the moment?
|
||||
} elsif ($ent[3] eq 'UG') {
|
||||
#TODO: networks through gateway. and how we might care..
|
||||
} else {
|
||||
#TODO: anything to do with such entries?
|
||||
}
|
||||
}
|
||||
}
|
||||
1;
|
65
xCAT-server-2.0/usr/lib/xcat/plugins/nodediscover.pm
Normal file
65
xCAT-server-2.0/usr/lib/xcat/plugins/nodediscover.pm
Normal file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::nodediscover;
|
||||
#use Net::SNMP qw(:snmp INTEGER);
|
||||
use xCAT::Table;
|
||||
use IO::Socket;
|
||||
use SNMP;
|
||||
use strict;
|
||||
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use POSIX "WNOHANG";
|
||||
use Storable qw(freeze thaw);
|
||||
use IO::Select;
|
||||
use IO::Handle;
|
||||
use Sys::Syslog;
|
||||
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
discovered => 'chain:ondiscover',
|
||||
};
|
||||
}
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $node = $request->{node}->[0];
|
||||
my $ip = $request->{'!xcat_clientip'};
|
||||
openlog("xCAT node discovery",'','local0');
|
||||
#First, fill in tables with data fields..
|
||||
if (defined($request->{mtm}) or defined($request->{serial})) {
|
||||
my $vpdtab = xCAT::Table->new("vpd",-create=>1);
|
||||
if ($request->{mtm}->[0]) {
|
||||
$vpdtab->setNodeAttribs($node,{mtm=>$request->{mtm}->[0]});
|
||||
}
|
||||
if ($request->{serial}) {
|
||||
$vpdtab->setNodeAttribs($node,{serial=>$request->{serial}->[0]});
|
||||
}
|
||||
}
|
||||
if (defined($request->{arch})) {
|
||||
my $typetab=xCAT::Table->new("nodetype",-create=>1);
|
||||
$typetab->setNodeAttribs($node,{arch=>$request->{arch}->[0]});
|
||||
}
|
||||
#TODO: mac table? on the one hand, 'the' definitive interface was determined earlier...
|
||||
#Delete the state it was in to make it traverse destiny once agoin
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
if ($chaintab) {
|
||||
$chaintab->setNodeAttribs($node,{currstate=>'',currchain=>''});
|
||||
$chaintab->close();
|
||||
}
|
||||
|
||||
|
||||
#now, notify the node to continue life
|
||||
my $sock = new IO::Socket::INET (
|
||||
PeerAddr => $ip,
|
||||
PeerPort => '3001',
|
||||
Proto => 'tcp'
|
||||
);
|
||||
unless ($sock) { syslog("err","Failed to notify $ip that it's actually $node."); return; } #Give up if the node won't hear of it.
|
||||
print $sock "restart";
|
||||
close($sock);
|
||||
syslog("info","$node has been discovered");
|
||||
}
|
||||
|
||||
1;
|
285
xCAT-server-2.0/usr/lib/xcat/plugins/notification.pm
Normal file
285
xCAT-server-2.0/usr/lib/xcat/plugins/notification.pm
Normal file
@ -0,0 +1,285 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::notification;
|
||||
use xCAT::Table;
|
||||
use xCAT::NotifHandler;
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head1 xCAT_plugin:notification
|
||||
=head2 Package Description
|
||||
xCAT notification plugini module. This mondule allows users to register and
|
||||
unregister for the xCAT database table changes.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 handled_commands
|
||||
It returns a list of commands handled by this plugin.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
a list of commands.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub handled_commands {
|
||||
return {
|
||||
regnotif => "notification",
|
||||
unregnotif => "notification",
|
||||
refnotif => "notification",
|
||||
lsnotif => "notification",
|
||||
enablenotif => "notification",
|
||||
disablenotif => "notification",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 process_request
|
||||
It processes the monitoring control commands.
|
||||
Arguments:
|
||||
request -- a hash table which contains the command name.
|
||||
callback -- a callback pointer to return the response to.
|
||||
args -- a list of arguments that come with the command.
|
||||
Returns:
|
||||
0 for success. The output is returned through the callback pointer.
|
||||
1. for unsuccess. The error messages are returns through the callback pointer.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub process_request {
|
||||
use Getopt::Long;
|
||||
# options can be bundled up like -vV
|
||||
Getopt::Long::Configure("bundling") ;
|
||||
$Getopt::Long::ignorecase=0;
|
||||
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
my $args=$request->{arg};
|
||||
|
||||
if ($command eq "regnotif") {
|
||||
my ($ret, $msg) = regNotification($args, $callback);
|
||||
if ($msg) {
|
||||
my %rsp=();
|
||||
$rsp->{dara}->[0]= $msg;
|
||||
$callback->($rsp);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
elsif ($command eq "unregnotif") {
|
||||
my ($ret, $msg) = unregNotification($args, $callback);
|
||||
if ($msg) {
|
||||
my %rsp=();
|
||||
$rsp->{data}->[0]= $msg;
|
||||
$callback->($rsp);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
else {
|
||||
my %rsp=();
|
||||
$rsp->{data}->[0]= "unsupported command: $command.";
|
||||
$callback->($rsp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 regNotification
|
||||
It registers a notification routine or a command which
|
||||
will be called when there are changes in the data base tables
|
||||
that the routine/command is interested in.
|
||||
Arguments:
|
||||
args - The format of the args is:
|
||||
[-h|--help|-v|--version] or
|
||||
filename tablename[,tablename]... [-o|--operation tableop[,tableop][,tableop]]]
|
||||
where
|
||||
tablename - string. a list of comma seperated names of the tables whose changes
|
||||
will be watched.
|
||||
filename - string. The name of the module (e.g. /usr/lib/xxx.pm) or
|
||||
command (e.g. /usr/bin/xxx) that handles the notification.
|
||||
If it is a perl module, the module must implement the following routine:
|
||||
processTableChanges(action, table_name, old_data, new_data)
|
||||
Refer to notify() subroutine for the meaning of the parameters.
|
||||
If it is a command, the command format should be:
|
||||
command [-d|-a|-u] tablename {[colnames][rowvalues][rowvalues]...} {[colnames][rowvalues]}
|
||||
tableop - it can be 'a' for add, 'd' for delete and 'u' for update.
|
||||
callback - the pointer to the callback function.
|
||||
Returns:
|
||||
none
|
||||
Comments:
|
||||
If the module or the command already exists in the notification table, this subroutine
|
||||
will replace it.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub regNotification {
|
||||
my $args=shift;
|
||||
my $callback=shift;
|
||||
my $VERSION;
|
||||
my $HELP;
|
||||
my $tableops;
|
||||
|
||||
# subroutine to display the usage
|
||||
sub regnotif_usage
|
||||
{
|
||||
my $callbk=shift;
|
||||
if (! $callbk) { return;}
|
||||
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "Usage:";
|
||||
$rsp->{data}->[1]= " regnotif filename tablename[,tablename]... [-o|--operation tableop[,tableop][,tableop]]]";
|
||||
$rsp->{data}->[2]= " where tableop can be 'a' for add, 'd' for delete and 'u' for update";
|
||||
$rsp->{data}->[3]= " regnotif [-h|--help|-v|--version]";
|
||||
$callbk->($rsp);
|
||||
}
|
||||
|
||||
@ARGV=@{$args};
|
||||
# parse the options
|
||||
if(!GetOptions(
|
||||
'o|operation=s' => \$tableops,
|
||||
'h|help' => \$::HELP,
|
||||
'v|version' => \$::VERSION,))
|
||||
{
|
||||
®notif_usage($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
# display the usage if -h or --help is specified
|
||||
if ($::HELP) {
|
||||
®notif_usage($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($::VERSION)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "regnotif version 1.0";
|
||||
if ($callback) {
|
||||
$callback->($rsp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# must specify the file name and table names
|
||||
if (@ARGV < 2)
|
||||
{
|
||||
®notif_usage($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
#table operations must be a,d or u seperated by ','
|
||||
if ($tableops)
|
||||
{
|
||||
if ($tableops !~ m/^(a|d|u)(,(a|d|u)){0,2}$/) {
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "Invalid table operations: $tableops";
|
||||
if ($callback) {
|
||||
$callback->($rsp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tableops="a,d,u";
|
||||
}
|
||||
|
||||
my $fname=shift(@ARGV);
|
||||
my $table_names=shift(@ARGV);
|
||||
|
||||
my $table=xCAT::Table->new("notification", -create => 1,-autocommit => 0);
|
||||
if ($table) {
|
||||
my %key_col = (filename=>$fname);
|
||||
my %tb_cols=(tables=>$table_names, tableops=>$tableops);
|
||||
$table->setAttribs(\%key_col, \%tb_cols);
|
||||
$table->commit;
|
||||
}
|
||||
|
||||
#update notification cache
|
||||
xCAT::NotifHandler::sendNotifSignal();
|
||||
return;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 unregNotification
|
||||
It unregisters a notification routine or a command.
|
||||
Arguments:
|
||||
args - the format of the ares is:
|
||||
[-h|--help|-v|--version] or
|
||||
filename
|
||||
where
|
||||
filename - string. The name of the module or command that handles the notification.
|
||||
callback - the pointer to the callback funtion.
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub unregNotification {
|
||||
my $args=shift;
|
||||
my $callback=shift;
|
||||
my $VERSION;
|
||||
my $HELP;
|
||||
|
||||
# subroutine to display the usage
|
||||
sub unregnotif_usage
|
||||
{
|
||||
my $callbk=shift;
|
||||
if (! $callbk) { return;}
|
||||
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "Usage:";
|
||||
$rsp->{data}->[1]= " unregnotif filename";
|
||||
$rsp->{data}->[2]= " unregnotif [-h|--help|-v|--version]";
|
||||
$callbk->($rsp);
|
||||
}
|
||||
|
||||
@ARGV=@{$args};
|
||||
# parse the options
|
||||
if(!GetOptions(
|
||||
'h|help' => \$::HELP,
|
||||
'v|version' => \$::VERSION,))
|
||||
{
|
||||
&unregnotif_usage($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
# display the usage if -h or --help is specified
|
||||
if ($::HELP) {
|
||||
&unregnotif_usage($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($::VERSION)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "unregnotif version 1.0";
|
||||
if ($callback) {
|
||||
$callback->($rsp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# must specify the node range
|
||||
if (@ARGV < 1) {
|
||||
&unregnotif_usage($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
my $fname=shift(@ARGV);
|
||||
|
||||
my $table=xCAT::Table->new("notification", -create => 1,-autocommit => 0);
|
||||
if ($table) {
|
||||
my %key_col = (filename=>$fname);
|
||||
$table->delEntries(\%key_col);
|
||||
$table->commit;
|
||||
}
|
||||
|
||||
#update notification cache
|
||||
xCAT::NotifHandler::sendNotifSignal();
|
||||
return;
|
||||
}
|
||||
|
172
xCAT-server-2.0/usr/lib/xcat/plugins/pxe.pm
Normal file
172
xCAT-server-2.0/usr/lib/xcat/plugins/pxe.pm
Normal file
@ -0,0 +1,172 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::pxe;
|
||||
use Data::Dumper;
|
||||
use Sys::Syslog;
|
||||
use Socket;
|
||||
|
||||
my $request;
|
||||
my $callback;
|
||||
my $dhcpconf = "/etc/dhcpd.conf";
|
||||
my $tftpdir = "/tftpboot";
|
||||
#my $dhcpver = 3;
|
||||
|
||||
my %usage = (
|
||||
"nodeset" => "Usage: nodeset <noderange> [install|shell|boot|runcmd=bmcsetup]",
|
||||
);
|
||||
sub handled_commands {
|
||||
return {
|
||||
nodeset => "noderes:netboot"
|
||||
}
|
||||
}
|
||||
|
||||
sub check_dhcp {
|
||||
#TODO: omapi magic to do things right
|
||||
my $node = shift;
|
||||
my $dhcpfile;
|
||||
open ($dhcpfile,$dhcpconf);
|
||||
while (<$dhcpfile>) {
|
||||
if (/host $node\b/) {
|
||||
close $dhcpfile;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
close $dhcpfile;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub getstate {
|
||||
my $node = shift;
|
||||
if (check_dhcp($node)) {
|
||||
if (-r $tftpdir . "/pxelinux.cfg/".$node) {
|
||||
my $fhand;
|
||||
open ($fhand,$tftpdir . "/pxelinux.cfg/".$node);
|
||||
my $headline = <$fhand>;
|
||||
close $fhand;
|
||||
$headline =~ s/^#//;
|
||||
chomp($headline);
|
||||
return $headline;
|
||||
} else {
|
||||
return "boot";
|
||||
}
|
||||
} else {
|
||||
return "discover";
|
||||
}
|
||||
}
|
||||
|
||||
sub setstate {
|
||||
=pod
|
||||
|
||||
This function will manipulate the pxelinux.cfg structure to match what the noderes/chain tables indicate the node should be booting.
|
||||
|
||||
=cut
|
||||
my $node = shift;
|
||||
my $restab = xCAT::Table->new('noderes');
|
||||
my $kern = $restab->getNodeAttribs($node,['kernel','initrd','kcmdline']);
|
||||
my $pcfg;
|
||||
open($pcfg,'>',$tftpdir."/pxelinux.cfg/".$node);
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
my $cref=$chaintab->getNodeAttribs($node,['currstate']);
|
||||
if ($cref->{currstate}) {
|
||||
print $pcfg "#".$cref->{currstate}."\n";
|
||||
}
|
||||
print $pcfg "DEFAULT xCAT\n";
|
||||
print $pcfg "LABEL xCAT\n";
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
my $stref = $chaintab->getNodeAttribs($node,['currstate']);
|
||||
if ($stref and $stref->{currstate} eq "boot") {
|
||||
print $pcfg "LOCALBOOT 0\n";
|
||||
close($pcfg);
|
||||
} elsif ($kern and $kern->{kernel}) {
|
||||
#It's time to set pxelinux for this node to boot the kernel..
|
||||
print $pcfg " KERNEL ".$kern->{kernel}."\n";
|
||||
if ($kern->{initrd} or $kern->{kcmdline}) {
|
||||
print $pcfg " APPEND ";
|
||||
}
|
||||
if ($kern and $kern->{initrd}) {
|
||||
print $pcfg "initrd=".$kern->{initrd}." ";
|
||||
}
|
||||
if ($kern and $kern->{kcmdline}) {
|
||||
print $pcfg $kern->{kcmdline}."\n";
|
||||
} else {
|
||||
print $pcfg "\n";
|
||||
}
|
||||
close($pcfg);
|
||||
my $inetn = inet_aton($node);
|
||||
unless ($inetn) {
|
||||
syslog("local1|err","xCAT unable to resolve IP for $node in pxe plugin");
|
||||
return;
|
||||
}
|
||||
} else { #TODO: actually, should possibly default to xCAT image?
|
||||
print $pcfg "LOCALBOOT 0\n";
|
||||
close($pcfg);
|
||||
}
|
||||
my $ip = inet_ntoa(inet_aton($node));;
|
||||
unless ($ip) {
|
||||
syslog("local1|err","xCAT unable to resolve IP in pxe plugin");
|
||||
return;
|
||||
}
|
||||
my @ipa=split(/\./,$ip);
|
||||
my $pname = sprintf("%02X%02X%02X%02X",@ipa);
|
||||
link($tftpdir."/pxelinux.cfg/".$node,$tftpdir."/pxelinux.cfg/".$pname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
my $errored = 0;
|
||||
sub pass_along {
|
||||
my $resp = shift;
|
||||
$callback->($resp);
|
||||
if ($resp and $resp->{errorcode} and $resp->{errorcode}->[0]) {
|
||||
$errored=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub process_request {
|
||||
$request = shift;
|
||||
$callback = shift;
|
||||
my $sub_req = shift;
|
||||
my @args;
|
||||
my @nodes;
|
||||
if (ref($request->{node})) {
|
||||
@nodes = @{$request->{node}};
|
||||
} else {
|
||||
if ($request->{node}) { @nodes = ($request->{node}); }
|
||||
}
|
||||
unless (@nodes) {
|
||||
if ($usage{$request->{command}->[0]}) {
|
||||
$callback->({data=>$usage{$request->{command}->[0]}});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref($request->{arg})) {
|
||||
@args=@{$request->{arg}};
|
||||
} else {
|
||||
@args=($request->{arg});
|
||||
}
|
||||
unless ($args[0] eq 'stat' or $args[0] eq 'enact') {
|
||||
$sub_req->({command=>['setdestiny'],
|
||||
node=>\@nodes,
|
||||
arg=>[$args[0]]},\&pass_along);
|
||||
}
|
||||
if ($errored) { return; }
|
||||
foreach (@nodes) {
|
||||
my %response;
|
||||
$response{node}->[0]->{name}->[0]=$_;
|
||||
if ($args[0] eq 'stat') {
|
||||
$response{node}->[0]->{data}->[0]= getstate($_);
|
||||
$callback->(\%response);
|
||||
} elsif ($args[0] eq 'enact') {
|
||||
setstate($_);
|
||||
} elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate
|
||||
setstate($_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
199
xCAT-server-2.0/usr/lib/xcat/plugins/rhel.pm
Normal file
199
xCAT-server-2.0/usr/lib/xcat/plugins/rhel.pm
Normal file
@ -0,0 +1,199 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::rhel;
|
||||
use Storable qw(dclone);
|
||||
use Sys::Syslog;
|
||||
use xCAT::Table;
|
||||
use xCAT::Template;
|
||||
use xCAT::Postage;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
|
||||
my %discids = (
|
||||
"1170973598.629055" => "rhelc5",
|
||||
"1170978545.752040" => "rhels5"
|
||||
);
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
copycd => "rhel",
|
||||
mkinstall => "nodetype:os=rh.*"
|
||||
}
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $distname = undef;
|
||||
my $arch = undef;
|
||||
my $path = undef;
|
||||
if ($request->{command}->[0] eq 'copycd') {
|
||||
return copycd($request,$callback,$doreq);
|
||||
} elsif ($request->{command}->[0] eq 'mkinstall') {
|
||||
return mkinstall($request,$callback,$doreq);
|
||||
}
|
||||
}
|
||||
|
||||
sub mkinstall {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my @nodes = @{$request->{node}};
|
||||
my $node;
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
my %doneimgs;
|
||||
foreach $node (@nodes) {
|
||||
my $osinst;
|
||||
my $ent = $ostab->getNodeAttribs($node,['profile','os','arch']);
|
||||
unless ($ent->{os} and $ent->{arch} and $ent->{profile}) {
|
||||
$callback->({error=>["No profile defined in nodetype for $node"],errorcode=>[1]});
|
||||
next; #No profile
|
||||
}
|
||||
my $os = $ent->{os};
|
||||
my $arch = $ent->{arch};
|
||||
my $profile = $ent->{profile};
|
||||
unless (-r "/usr/share/xcat/install/rh/".$ent->{profile}.".tmpl") {
|
||||
$callback->({error=>["No kickstart template exists for ".$ent->{profile}],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
#Call the Template class to do substitution to produce a kickstart file in the autoinst dir
|
||||
xCAT::Template->subvars("/usr/share/xcat/install/rh/".$ent->{profile}.".tmpl","/install/autoinst/".$node,$node);
|
||||
mkpath "/install/postscripts/";
|
||||
xCAT::Postage->writescript($node,"/install/postscripts/".$node);
|
||||
if (-r "/install/$os/$arch/images/pxeboot/vmlinuz"
|
||||
and -r "/install/$os/$arch/images/pxeboot/initrd.img") {
|
||||
unless ($doneimgs{"$os|$arch"}) {
|
||||
#TODO: driver slipstream, targetted for network.
|
||||
mkpath("/tftpboot/xcat/$os/$arch");
|
||||
copy("/install/$os/$arch/images/pxeboot/vmlinuz","/tftpboot/xcat/$os/$arch/");
|
||||
copy("/install/$os/$arch/images/pxeboot/initrd.img","/tftpboot/xcat/$os/$arch/");
|
||||
$doneimgs{"$os|$arch"}=1;
|
||||
}
|
||||
#We have a shot...
|
||||
my $restab = xCAT::Table->new('noderes');
|
||||
my $ent = $restab->getNodeAttribs($node,['nfsserver','serialport','primarynic','installnic']);
|
||||
my $hmtab = xCAT::Table->new('nodehm');
|
||||
my $sent = $hmtab->getNodeAttribs($node,['serialspeed','serialflow']);
|
||||
unless ($ent and $ent->{nfsserver}) {
|
||||
$callback->({error=>["No noderes.nfsserver defined for ".$ent->{profile}],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
my $kcmdline="nofb utf8 ks=http://".$ent->{nfsserver}."/install/autoinst/".$node;
|
||||
if ($ent->{installnic}) {
|
||||
$kcmdline.=" ksdevice=".$ent->{installnic};
|
||||
} elsif ($ent->{primarynic}) {
|
||||
$kcmdline.=" ksdevice=".$ent->{primarynic};
|
||||
} else {
|
||||
$kcmdline .= " ksdevice=eth0";
|
||||
}
|
||||
|
||||
#TODO: dd=<url> for driver disks
|
||||
if (defined $ent->{serialport}) {
|
||||
unless ($sent->{serialspeed}) {
|
||||
$callback->({error=>["serialport defined, but no serialspeed for $node in nodehm table"],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
$kcmdline.=" console=ttyS".$ent->{serialport}.",".$sent->{serialspeed};
|
||||
if ($sent->{serialflow} =~ /(ctsrts|cts|hard)/) {
|
||||
$kcmdline .= "n8r";
|
||||
}
|
||||
}
|
||||
$kcmdline .= " noipv6";
|
||||
|
||||
$restab->setNodeAttribs($node,{
|
||||
kernel=>"xcat/$os/$arch/vmlinuz",
|
||||
initrd=>"xcat/$os/$arch/initrd.img",
|
||||
kcmdline=>$kcmdline
|
||||
});
|
||||
} else {
|
||||
$callback->({error=>["Install image not found in /install/$os/$arch"],errorcode=>[1]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub copycd {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $installroot;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
if ($sitetab) {
|
||||
(my $ref) = $sitetab->getAttribs({key=>installdir},value);
|
||||
print Dumper($ref);
|
||||
if ($ref and $ref->{value}) {
|
||||
$installroot = $ref->{value};
|
||||
}
|
||||
}
|
||||
|
||||
@ARGV= @{$request->{arg}};
|
||||
GetOptions(
|
||||
'n=s' => \$distname,
|
||||
'a=s' => \$arch,
|
||||
'p=s' => \$path
|
||||
);
|
||||
unless ($path) {
|
||||
#this plugin needs $path...
|
||||
return;
|
||||
}
|
||||
if ($distname and $distname !~ /^rh/) {
|
||||
#If they say to call it something other than RH, give up?
|
||||
return;
|
||||
}
|
||||
unless (-r $path."/.discinfo") {
|
||||
return;
|
||||
}
|
||||
my $dinfo;
|
||||
open($dinfo,$path."/.discinfo");
|
||||
my $did = <$dinfo>;
|
||||
chomp($did);
|
||||
my $desc = <$dinfo>;
|
||||
chomp($desc);
|
||||
my $darch = <$dinfo>;
|
||||
chomp($darch);
|
||||
if ($darch and $darch =~ /i.86/) {
|
||||
$darch = "x86";
|
||||
}
|
||||
close($dinfo);
|
||||
if ($desc =~ /^Red Hat Enterprise Linux Client 5$/) {
|
||||
unless ($distname) {
|
||||
$distname = "rhelc5";
|
||||
}
|
||||
} elsif ($desc =~ /^Red Hat Enterprise Linux Server 5$/) {
|
||||
unless ($distname) {
|
||||
$distname = "rhels5";
|
||||
}
|
||||
}
|
||||
|
||||
print $desc;
|
||||
unless ($distname) {
|
||||
return; #Do nothing, not ours..
|
||||
}
|
||||
if ($darch) {
|
||||
unless ($arch) {
|
||||
$arch = $darch;
|
||||
}
|
||||
if ($arch and $arch ne $darch) {
|
||||
$callback->({error=>"Requested RedHat architecture $arch, but media is $darch"});
|
||||
return;
|
||||
}
|
||||
}
|
||||
%{$request} = (); #clear request we've got it.
|
||||
|
||||
$callback->({data=>"Copying media to $installroot/$distname/$arch/"});
|
||||
my $omask=umask 0022;
|
||||
mkpath("$installroot/$distname/$arch");
|
||||
umask $omask;
|
||||
my $rc = system("cd $path; find . | cpio -dump $installroot/$distname/$arch");
|
||||
chmod 0755,"$installroot/$distname/$arch";
|
||||
if ($rc != 0) {
|
||||
$callback->({error=>"Media copy operation failed, status $rc"});
|
||||
} else {
|
||||
$callback->({data=>"Media copy operation successful"});
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
213
xCAT-server-2.0/usr/lib/xcat/plugins/sles.pm
Normal file
213
xCAT-server-2.0/usr/lib/xcat/plugins/sles.pm
Normal file
@ -0,0 +1,213 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::sles;
|
||||
use Storable qw(dclone);
|
||||
use Sys::Syslog;
|
||||
use xCAT::Table;
|
||||
use xCAT::Template;
|
||||
use xCAT::Postage;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
copycd => "sles",
|
||||
mkinstall => "nodetype:os=sles.*"
|
||||
}
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $distname = undef;
|
||||
my $arch = undef;
|
||||
my $path = undef;
|
||||
if ($request->{command}->[0] eq 'copycd') {
|
||||
return copycd($request,$callback,$doreq);
|
||||
} elsif ($request->{command}->[0] eq 'mkinstall') {
|
||||
return mkinstall($request,$callback,$doreq);
|
||||
}
|
||||
}
|
||||
|
||||
sub mkinstall {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my @nodes = @{$request->{node}};
|
||||
my $node;
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
my %doneimgs;
|
||||
foreach $node (@nodes) {
|
||||
my $osinst;
|
||||
my $ent = $ostab->getNodeAttribs($node,['profile','os','arch']);
|
||||
unless ($ent->{os} and $ent->{arch} and $ent->{profile}) {
|
||||
$callback->({error=>["No profile defined in nodetype for $node"],errorcode=>[1]});
|
||||
next; #No profile
|
||||
}
|
||||
my $os = $ent->{os};
|
||||
my $arch = $ent->{arch};
|
||||
my $profile = $ent->{profile};
|
||||
unless (-r "/usr/share/xcat/install/sles/".$ent->{profile}.".tmpl") {
|
||||
$callback->({error=>["No AutoYaST template exists for ".$ent->{profile}],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
#Call the Template class to do substitution to produce a kickstart file in the autoinst dir
|
||||
xCAT::Template->subvars("/usr/share/xcat/install/sles/".$ent->{profile}.".tmpl","/install/autoinst/".$node,$node);
|
||||
mkpath "/install/postscripts/";
|
||||
xCAT::Postage->writescript($node,"/install/postscripts/".$node);
|
||||
if (-r "/install/$os/$arch/1/boot/$arch/loader/linux"
|
||||
and -r "/install/$os/$arch/1/boot/$arch/loader/initrd") {
|
||||
#TODO: driver slipstream, targetted for network.
|
||||
unless ($doneimgs{"$os|$arch"}) {
|
||||
mkpath("/tftpboot/xcat/$os/$arch");
|
||||
copy("/install/$os/$arch/1/boot/$arch/loader/linux","/tftpboot/xcat/$os/$arch/");
|
||||
copy("/install/$os/$arch/1/boot/$arch/loader/initrd","/tftpboot/xcat/$os/$arch/");
|
||||
$doneimgs{"$os|$arch"}=1;
|
||||
}
|
||||
#We have a shot...
|
||||
my $restab = xCAT::Table->new('noderes');
|
||||
my $hmtab = xCAT::Table->new('nodehm');
|
||||
my $ent = $restab->getNodeAttribs($node,['nfsserver','serialport','primarynic','installnic']);
|
||||
my $sent = $hmtab->getNodeAttribs($node,['serialspeed','serialflow']);
|
||||
unless ($ent and $ent->{nfsserver}) {
|
||||
$callback->({error=>["No server for $node defined"],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
my $kcmdline="autoyast=http://".$ent->{nfsserver}."/install/autoinst/".$node." install=http://".$ent->{nfsserver}."/install/$os/$arch/1";
|
||||
if ($ent->{installnic}) {
|
||||
$kcmdline.=" netdevice=".$ent->{installnic};
|
||||
} elsif ($ent->{primarynic}) {
|
||||
$kcmdline.=" netdevice=".$ent->{primarynic};
|
||||
} else {
|
||||
$kcmdline .= " netdevice=eth0";
|
||||
}
|
||||
|
||||
#TODO: driver disk handling should in SLES case be a mod of the install source, nothing to see here
|
||||
if (defined $ent->{serialport}) {
|
||||
unless ($sent->{serialspeed}) {
|
||||
$callback->({error=>["serialport defined, but no serialspeed for $node in nodehm table"],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
$kcmdline.=" console=ttyS".$ent->{serialport}.",".$sent->{serialspeed};
|
||||
if ($sent and ($sent->{serialflow} =~ /(ctsrts|cts|hard)/)) {
|
||||
$kcmdline .= "n8r";
|
||||
}
|
||||
}
|
||||
|
||||
$restab->setNodeAttribs($node,{
|
||||
kernel=>"xcat/$os/$arch/linux",
|
||||
initrd=>"xcat/$os/$arch/initrd",
|
||||
kcmdline=>$kcmdline
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub copycd {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $installroot;
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
if ($sitetab) {
|
||||
(my $ref) = $sitetab->getAttribs({key=>installdir},value);
|
||||
print Dumper($ref);
|
||||
if ($ref and $ref->{value}) {
|
||||
$installroot = $ref->{value};
|
||||
}
|
||||
}
|
||||
|
||||
@ARGV= @{$request->{arg}};
|
||||
GetOptions(
|
||||
'n=s' => \$distname,
|
||||
'a=s' => \$arch,
|
||||
'p=s' => \$path
|
||||
);
|
||||
unless ($path) {
|
||||
#this plugin needs $path...
|
||||
return;
|
||||
}
|
||||
if ($distname and $distname !~ /^sles/) {
|
||||
#If they say to call it something other than SLES, give up?
|
||||
return;
|
||||
}
|
||||
unless (-r $path."/content") {
|
||||
return;
|
||||
}
|
||||
my $dinfo;
|
||||
open($dinfo,$path."/content");
|
||||
while (<$dinfo>) {
|
||||
if (m/^DEFAULTBASE\s+(\S+)/) {
|
||||
$darch = $1;
|
||||
chomp($darch);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close($dinfo);
|
||||
unless ($darch) {
|
||||
return;
|
||||
}
|
||||
my $dirh;
|
||||
opendir($dirh,$path);
|
||||
my $discnumber;
|
||||
my $totaldiscnumber;
|
||||
while (my $pname = readdir($dirh)) {
|
||||
if ($pname =~ /media.(\d+)/) {
|
||||
$discnumber=$1;
|
||||
chomp($discnumber);
|
||||
my $mfile;
|
||||
open($mfile,$path."/".$pname."/media");
|
||||
<$mfile>;
|
||||
<$mfile>;
|
||||
$totaldiscnumber=<$mfile>;
|
||||
chomp($totaldiscnumber);
|
||||
close($mfile);
|
||||
open($mfile,$path."/".$pname."/products");
|
||||
my $prod = <$mfile>;
|
||||
close($mfile);
|
||||
if ($prod =~ m/SUSE-Linux-Enterprise-Server/) {
|
||||
my @parts = split /\s+/,$prod;
|
||||
my @subparts = split /-/,$parts[2];
|
||||
$distname="sles".$subparts[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
unless ($distname and $discnumber) {
|
||||
return;
|
||||
}
|
||||
if ($darch and $darch =~ /i.86/) {
|
||||
$darch = "x86";
|
||||
} elsif ($darch and $darch =~ /ppc/) {
|
||||
$darch = "ppc64";
|
||||
}
|
||||
if ($darch) {
|
||||
unless ($arch) {
|
||||
$arch = $darch;
|
||||
}
|
||||
if ($arch and $arch ne $darch) {
|
||||
$callback->({error=>"Requested SLES architecture $arch, but media is $darch"});
|
||||
return;
|
||||
}
|
||||
}
|
||||
%{$request} = (); #clear request we've got it.
|
||||
|
||||
$callback->({data=>"Copying media to $installroot/$distname/$arch/$discnumber"});
|
||||
my $omask=umask 0022;
|
||||
mkpath("$installroot/$distname/$arch/$discnumber");
|
||||
umask $omask;
|
||||
my $rc = system("cd $path; find . | nice -n 20 cpio -dump $installroot/$distname/$arch/$discnumber/");
|
||||
chmod 0755,"$installroot/$distname/$arch";
|
||||
chmod 0755,"$installroot/$distname/$arch/$discnumber";
|
||||
if ($rc != 0) {
|
||||
$callback->({error=>"Media copy operation failed, status $rc"});
|
||||
} else {
|
||||
$callback->({data=>"Media copy operation successful"});
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
53
xCAT-server-2.0/usr/lib/xcat/plugins/switch.pm
Normal file
53
xCAT-server-2.0/usr/lib/xcat/plugins/switch.pm
Normal file
@ -0,0 +1,53 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::switch;
|
||||
use IO::Socket;
|
||||
use Data::Dumper;
|
||||
use xCAT::MacMap;
|
||||
use Sys::Syslog;
|
||||
use Storable;
|
||||
|
||||
my $macmap;
|
||||
sub handled_commands {
|
||||
$macmap = xCAT::MacMap->new();
|
||||
return {
|
||||
findme => 'switch',
|
||||
};
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $req = shift;
|
||||
my $cb = shift;
|
||||
my $doreq = shift;
|
||||
my $ip = $req->{'!xcat_clientip'};
|
||||
my $mac = '';
|
||||
my $arptable = `/sbin/arp -n`;
|
||||
my @arpents = split /\n/,$arptable;
|
||||
foreach (@arpents) {
|
||||
if (m/^($ip)\s+\S+\s+(\S+)\s/) {
|
||||
$mac=$2;
|
||||
last;
|
||||
}
|
||||
}
|
||||
unless ($mac) {
|
||||
return;
|
||||
}
|
||||
my $node = $macmap->find_mac($mac);
|
||||
if ($node) {
|
||||
my $mactab = xCAT::Table->new('mac',-create=>1);
|
||||
$mactab->setNodeAttribs($node,{mac=>$mac});
|
||||
$mactab->close();
|
||||
my %request = (
|
||||
command => ['makedhcp'],
|
||||
node => [$node]
|
||||
);
|
||||
$doreq->(\%request);
|
||||
$req->{command}=['discovered'];
|
||||
$req->{noderange} = [$node];
|
||||
$doreq->($req);
|
||||
%{$req}=();#Clear req structure, it's done..
|
||||
undef $mactab;
|
||||
} else {
|
||||
#Shouldn't complain, might be blade, but how to log total failures?
|
||||
}
|
||||
}
|
||||
1;
|
593
xCAT-server-2.0/usr/lib/xcat/plugins/tabutils.pm
Normal file
593
xCAT-server-2.0/usr/lib/xcat/plugins/tabutils.pm
Normal file
@ -0,0 +1,593 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#####################################################
|
||||
#
|
||||
# xCAT plugin package to handle various commands that work with the
|
||||
# xCAT tables
|
||||
#
|
||||
# Supported commands:
|
||||
# nodeadd
|
||||
# nodels
|
||||
# nodech
|
||||
# tabdump
|
||||
# tabrestore
|
||||
# noderm
|
||||
# To be implemented:
|
||||
# gettab
|
||||
# chtab
|
||||
# tabls
|
||||
# getnodecfg (?? this doesn't seem much different from gettab)
|
||||
# nr
|
||||
# These were xCAT 1.2 commands. Are they still useful in xCAT 1.3?
|
||||
# addattr
|
||||
# delattr
|
||||
# chtype
|
||||
#
|
||||
#####################################################
|
||||
package xCAT_plugin::tabutils;
|
||||
use xCAT::Table;
|
||||
use xCAT::Schema;
|
||||
use Data::Dumper;
|
||||
use xCAT::NodeRange;
|
||||
use xCAT::Schema; #noderm will need to build list of tables..
|
||||
#use Getopt::Long qw(GetOptionsFromArray);
|
||||
|
||||
1;
|
||||
|
||||
#some quick aliases to table/value
|
||||
my %shortnames = (
|
||||
groups => [qw(nodelist groups)],
|
||||
tags => [qw(nodelist groups)],
|
||||
mgt => [qw(nodehm mgt)],
|
||||
switch => [qw(switch switch)],
|
||||
);
|
||||
|
||||
#####################################################
|
||||
# Return list of commands handled by this plugin
|
||||
#####################################################
|
||||
sub handled_commands {
|
||||
return {
|
||||
gettab => "tabutils",
|
||||
tabdump => "tabutils",
|
||||
tabrestore => "tabutils",
|
||||
tabch => "tabutils",
|
||||
nodech => "tabutils",
|
||||
nodeadd => "tabutils",
|
||||
noderm => "tabutils",
|
||||
tabls => "tabutils",
|
||||
nodels => "tabutils",
|
||||
getnodecfg => "tabutils",
|
||||
addattr => "tabutils",
|
||||
delattr => "tabutils",
|
||||
chtype => "tabutils",
|
||||
nr => "tabutils"
|
||||
}
|
||||
}
|
||||
|
||||
my %usage = (
|
||||
nodech => "Usage: nodech <noderange> [table.column=value] [table.column=value] ...",
|
||||
nodeadd => "Usage: nodeadd <noderange> [table.column=value] [table.column=value] ...",
|
||||
noderm => "Usage: noderm <noderange>",
|
||||
tabdump => "Usage: tabdump <tablename>\n where <tablename> is one of the following:\n ".join("\n ",keys %xCAT::Schema::tabspec),
|
||||
tabrestore => "Usage: tabrestore <tablename>.csv",
|
||||
);
|
||||
|
||||
#####################################################
|
||||
# Process the command
|
||||
#####################################################
|
||||
sub gettab {
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
my $keyspec = shift @{$req->{arg}};
|
||||
my @keypairs = split /,/,$keyspec;
|
||||
my %keyhash;
|
||||
foreach (@keypairs) {
|
||||
(my $key, my $value) = split /=/,$_;
|
||||
$keyhash{$key}=$value;
|
||||
}
|
||||
my %tabhash;
|
||||
foreach my $tabvalue (@{$req->{arg}}) {
|
||||
(my $table,my $column) = split /\./,$tabvalue;
|
||||
$tabhash{$table}->{$column} = 1;
|
||||
}
|
||||
foreach my $tabn (keys %tabhash) {
|
||||
my $tab = xCAT::Table->new($tabn);
|
||||
(my $ent) = $tab->getAttribs(\%keyhash,keys %{$tabhash{$tabn}});
|
||||
foreach my $coln (keys %{$tabhash{$tabn}}) {
|
||||
$callback->({data=>["$tabn.$coln:".$ent->{$coln}]});
|
||||
}
|
||||
$tab->close;
|
||||
}
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $nodes = $request->{node};
|
||||
my $command = $request->{command}->[0];
|
||||
my $args = $request->{arg};
|
||||
unless ($args or $nodes or $request->{data}) {
|
||||
if ($usage{$command}) {
|
||||
$callback->({data=>[$usage{$command}]});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($command eq "nodels") {
|
||||
return nodels($nodes,$args,$callback,$request->{noderange}->[0]);
|
||||
} elsif ($command eq "noderm" or $command eq "rmnode") {
|
||||
return noderm($nodes,$args,$callback);
|
||||
} elsif ($command eq "nodeadd" or $command eq "addnode") {
|
||||
return chnode($nodes,$args,$callback,1);
|
||||
} elsif ($command eq "nodech" or $command eq "chnode") {
|
||||
return chnode($nodes,$args,$callback,0);
|
||||
} elsif ($command eq "tabrestore") {
|
||||
return tabrestore($request,$callback);
|
||||
} elsif ($command eq "tabdump") {
|
||||
return tabdump($args,$callback);
|
||||
} elsif ($command eq "gettab") {
|
||||
return gettab($request,$callback);
|
||||
} else {
|
||||
print "$command not implemented yet\n";
|
||||
return (1,"$command not written yet");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub noderm {
|
||||
my $nodes = shift;
|
||||
my $args = shift;
|
||||
my $cb = shift;
|
||||
my @tablist = ("-d");
|
||||
foreach (keys %{xCAT::Schema::tabspec}) {
|
||||
if (grep /^node$/,@{$xCAT::Schema::tabspec{$_}->{cols}}) {
|
||||
push @tablist,$_;
|
||||
}
|
||||
}
|
||||
chnode($nodes,\@tablist,$cb,0);
|
||||
}
|
||||
sub tabrestore {
|
||||
#request->{data} is an array of CSV formatted lines
|
||||
my $request = shift;
|
||||
my $cb = shift;
|
||||
my $table = $request->{table}->[0];
|
||||
my $linenumber = 1;
|
||||
my $tab = xCAT::Table->new($table,-create =>1,-autocommit=>0);
|
||||
unless ($tab) {
|
||||
$cb->({error=>"Unable to open $table"});
|
||||
return;
|
||||
}
|
||||
$tab->delEntries(); #Yes, delete *all* entries
|
||||
my $header = shift @{$request->{data}};
|
||||
$header =~ s/"//g; #Strip " from overzealous CSV apps
|
||||
$header =~ s/^#//;
|
||||
$header =~ s/\s+$//;
|
||||
my @colns = split(/,/,$header);
|
||||
my $line;
|
||||
my $rollback=0;
|
||||
LINE: foreach $line (@{$request->{data}}) {
|
||||
$linenumber++;
|
||||
$line =~ s/\s+$//;
|
||||
my $origline = $line; #save for error reporting
|
||||
my %record;
|
||||
my $col;
|
||||
foreach $col (@colns) {
|
||||
if ($line =~ /^,/ or $line eq "") { #Match empty, or end of line that is empty
|
||||
#TODO: should we detect when there weren't enough CSV fields on a line to match colums?
|
||||
$record{$col}=undef;
|
||||
$line =~ s/^,//;
|
||||
} elsif ($line =~ /^[^,]*"/) { # We have stuff in quotes... pain...
|
||||
#I don't know what I'm doing, so I'll do it a hard way....
|
||||
if ($line !~ /^"/) {
|
||||
$rollback = 1;
|
||||
$cb->({error=>"CSV missing opening \" for record with \" characters on line $linenumber, character ".index($origline,$line).": $origline"});
|
||||
next LINE;
|
||||
}
|
||||
my $offset=1;
|
||||
my $nextchar;
|
||||
my $ent = "";
|
||||
while (not $ent) {
|
||||
$offset = index($line,'"',$offset);
|
||||
$offset++;
|
||||
if ($offset <=0) {
|
||||
#MALFORMED CSV, request rollback, report an error
|
||||
$rollback=1;
|
||||
$cb->({error=>"CSV unmatched \" in record on line $linenumber, character ".index($origline,$line).": $origline"});
|
||||
next LINE;
|
||||
}
|
||||
$nextchar = substr($line,$offset,1);
|
||||
if ($nextchar eq '"') {
|
||||
$offset++;
|
||||
} elsif ($offset eq length($line) or $nextchar eq ',') {
|
||||
$ent = substr($line,0,$offset,'');
|
||||
$line =~ s/^,//;
|
||||
chop $ent;
|
||||
$ent = substr($ent,1);
|
||||
$ent =~ s/""/"/g;
|
||||
$record{$col}=$ent;
|
||||
} else {
|
||||
$cb->({error=>"CSV unescaped \" in record on line $linenumber, character ".index($origline,$line).": $origline"});
|
||||
$rollback=1;
|
||||
next LINE;
|
||||
}
|
||||
}
|
||||
} elsif ($line =~ /^([^,]+)/) { #easiest case, no Text::Balanced needed..
|
||||
$record{$col} = $1;
|
||||
$line =~ s/^([^,]+)(,|$)//;
|
||||
}
|
||||
}
|
||||
if ($line) {
|
||||
$rollback = 1;
|
||||
$cb->({error=>"Too many fields on line $linenumber: $origline | $line"});
|
||||
next LINE;
|
||||
}
|
||||
#TODO: check for error from DB and rollback
|
||||
my @rc =$tab->setAttribs(\%record,\%record);
|
||||
if (not defined($rc[0])) {
|
||||
$rollback = 1;
|
||||
$cb->({error=>"DB error ".$rc[1]. " with line $linenumber: ".$origline});
|
||||
}
|
||||
}
|
||||
if ($rollback) {
|
||||
$tab->rollback();
|
||||
$tab->close;
|
||||
undef $tab;
|
||||
return;
|
||||
} else {
|
||||
$tab->commit; #Made it all the way here, commit
|
||||
}
|
||||
}
|
||||
sub tabdump {
|
||||
#TODO: need to return header for not-yet existing, but schemad tabs
|
||||
#TODO: schema defined column order.
|
||||
my $args = shift;
|
||||
my $cb = shift;
|
||||
my $table="";
|
||||
foreach (@$args) {
|
||||
unless (/^-/) {
|
||||
if ($table) {
|
||||
return 1; #TODO: Error, usage
|
||||
}
|
||||
$table=$_;
|
||||
}
|
||||
}
|
||||
my $tabh = xCAT::Table->new($table);
|
||||
my %rsp;
|
||||
unless ($tabh) {
|
||||
if (defined($xCAT::Schema::tabspec{$table})) {
|
||||
my $header = join ",",@{$xCAT::Schema::tabspec{$table}->{cols}};
|
||||
$header="#".$header;
|
||||
push @{$rsp{data}},$header;
|
||||
$cb->(\%rsp);
|
||||
return;
|
||||
}
|
||||
$cb->({error=>"No such table: $table"});
|
||||
return 1;
|
||||
}
|
||||
my $recs=$tabh->getAllEntries();
|
||||
my $rec;
|
||||
my $firstline = 1;
|
||||
unless (@$recs) {
|
||||
if (defined($xCAT::Schema::tabspec{$table})) {
|
||||
my $header = join ",",@{$xCAT::Schema::tabspec{$table}->{cols}};
|
||||
$header="#".$header;
|
||||
push @{$rsp{data}},$header;
|
||||
$cb->(\%rsp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach $rec (@$recs) {
|
||||
my $line ='';
|
||||
if ($firstline) {
|
||||
$firstline = 0;
|
||||
$line = join ",",@{$tabh->{colnames}};
|
||||
$line = "#".$line;
|
||||
push @{$rsp{data}},$line;
|
||||
$line = '';
|
||||
}
|
||||
foreach (@{$tabh->{colnames}}) {
|
||||
$rec->{$_} =~ s/"/""/g;
|
||||
if (defined $rec->{$_}) {
|
||||
$line = $line . '"' . $rec->{$_} . '",';
|
||||
} else {
|
||||
$line .= ',';
|
||||
}
|
||||
}
|
||||
$line =~ s/,$//;
|
||||
$line = $line . $lineappend;
|
||||
push @{$rsp{data}},$line;
|
||||
}
|
||||
$cb->(\%rsp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub chnode {
|
||||
my $nodes=shift;
|
||||
my $args=shift;
|
||||
my $callback=shift;
|
||||
my $addmode=shift;
|
||||
print $addmode;
|
||||
if ($addmode) {
|
||||
my $idx=0;
|
||||
foreach my $arg (@$args) {
|
||||
unless ($arg =~ /^-/) {
|
||||
$nodes = [noderange($arg,0)];
|
||||
splice(@$args,$idx,1);
|
||||
last;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
unless ($nodes) {
|
||||
$callback->({error=>"No range to add detected\n"});
|
||||
return;
|
||||
}
|
||||
}
|
||||
my $column;
|
||||
my $value;
|
||||
my $temp;
|
||||
my %tables;
|
||||
my $tab;
|
||||
my $deletemode;
|
||||
|
||||
#No GetOptionsFromArray...
|
||||
#GetOptionsFromArray($args,"d|delete" => \$deletemode);
|
||||
#print Dumper($deletemode);
|
||||
foreach (@$args) {
|
||||
if (m/^-/) { #A quick and dirty option parser in lieu of lacking Getoptinos
|
||||
if (m/^--/) {
|
||||
if (m/--delete/) {
|
||||
$deletemode=1;
|
||||
next;
|
||||
} else {
|
||||
$callback->({data=>["ERROR: Malformed argument $_ ignored"]});
|
||||
next;
|
||||
}
|
||||
} else {
|
||||
if (m/^-d$/) {
|
||||
$deletemode=1;
|
||||
next;
|
||||
} else {
|
||||
$callback->({data=>["ERROR: Malformed argument $_ ignored"]});
|
||||
next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($deletemode) {
|
||||
if (m/[=\.]/) {
|
||||
$callback->({data=>["ERROR: . and = not valid in delete mode"]});
|
||||
next;
|
||||
}
|
||||
$tables{$_} = 1;
|
||||
next;
|
||||
}
|
||||
unless (m/=/) {
|
||||
$callback->({data=>["ERROR: Malformed argument $_ ignored"]});
|
||||
next;
|
||||
}
|
||||
($temp,$value)=split('=',$_,2);
|
||||
my $op='=';
|
||||
if ($temp =~ /,$/) {
|
||||
$op=',=';
|
||||
chop($temp);
|
||||
} elsif ($temp =~ /\^$/) {
|
||||
$op='^=';
|
||||
chop($temp);
|
||||
}
|
||||
|
||||
if ($shortnames{$temp}) {
|
||||
($table,$column) = @{$shortnames{$temp}};
|
||||
} else {
|
||||
($table,$column) = split('\.',$temp,2);
|
||||
}
|
||||
$tables{$table}->{$column}=[$value,$op];
|
||||
}
|
||||
foreach $tab (keys %tables) {
|
||||
my $tabhdl = xCAT::Table->new($tab,-create => 1,-autocommit => 0);
|
||||
if ($tabhdl) {
|
||||
foreach (@$nodes) {
|
||||
if ($deletemode) {
|
||||
$tabhdl->delEntries({'node'=>$_});
|
||||
} else {
|
||||
#$tabhdl->setNodeAttribs($_,$tables{$tab});
|
||||
my %uhsh;
|
||||
my $node = $_;
|
||||
foreach (keys %{$tables{$tab}}) {
|
||||
my $op = $tables{$tab}->{$_}->[1];
|
||||
my $val = $tables{$tab}->{$_}->[0];
|
||||
my $key = $_;
|
||||
if ($op eq '=') {
|
||||
$uhsh{$key}=$val;
|
||||
} elsif ($op eq ',=') { #splice assignment
|
||||
my $cent = $tabhdl->getNodeAttribs($node,[$key]);
|
||||
my $curval;
|
||||
if ($cent) { $curval = $cent->{$key}; }
|
||||
if ($curval) {
|
||||
my @vals = split(/,/,$curval);
|
||||
unless (grep /^$val$/,@vals) {
|
||||
@vals=(@vals,$val);
|
||||
my $newval = join(',',@vals);
|
||||
$uhsh{$key}=$newval;
|
||||
}
|
||||
} else {
|
||||
$uhsh{$key}=$val;
|
||||
}
|
||||
} elsif ($op eq '^=') {
|
||||
my $cent = $tabhdl->getNodeAttribs($node,[$key]);
|
||||
my $curval;
|
||||
if ($cent) { $curval = $cent->{$key}; }
|
||||
if ($curval) {
|
||||
my @vals = split(/,/,$curval);
|
||||
if (grep /^$val$/,@vals) { #only bother if there
|
||||
@vals = grep(!/^$val$/,@vals);
|
||||
my $newval = join(',',@vals);
|
||||
$uhsh{$key}=$newval;
|
||||
}
|
||||
} #else, what they asked for is the case alredy
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (keys %uhsh) {
|
||||
$tabhdl->setNodeAttribs($node,\%uhsh);
|
||||
}
|
||||
}
|
||||
}
|
||||
$tabhdl->commit;
|
||||
} else {
|
||||
$callback->({data=>["ERROR: Unable to open table $tab in configuration"]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#####################################################
|
||||
# nodels command
|
||||
#####################################################
|
||||
sub nodels {
|
||||
my $nodes=shift;
|
||||
my $args=shift;
|
||||
my $callback=shift;
|
||||
my $noderange=shift;
|
||||
|
||||
my $VERSION;
|
||||
my $HELP;
|
||||
|
||||
sub nodels_usage {
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "Usage:";
|
||||
$rsp->{data}->[1]= " nodels [-?|-h|--help] ";
|
||||
$rsp->{data}->[2]= " nodels [-v|--version] ";
|
||||
$rsp->{data}->[3]= " nodels [noderange] ";
|
||||
##### xcat 1.2 nodels usage:
|
||||
# $rsp->{data}->[1]= " nodels [noderange] [group|pos|type|rg|install|hm|all]";
|
||||
# $rsp->{data}->[2]= " ";
|
||||
# $rsp->{data}->[3]= " nodels [noderange] hm.{power|reset|cad|vitals|inv|cons}";
|
||||
# $rsp->{data}->[4]= " hm.{bioscons|eventlogs|getmacs|netboot}";
|
||||
# $rsp->{data}->[5]= " hm.{eth0|gcons|serialbios|beacon}";
|
||||
# $rsp->{data}->[6]= " hm.{bootseq|serialbps|all}";
|
||||
# $rsp->{data}->[7]= " ";
|
||||
# $rsp->{data}->[8]= " nodels [noderange] rg.{tftp|nfs_install|install_dir|serial}";
|
||||
# $rsp->{data}->[9]= " rg.{usenis|install_roll|acct|gm|pbs}";
|
||||
# $rsp->{data}->[10]=" rg.{access|gpfs|netdevice|prinic|all}";
|
||||
$callback->($rsp);
|
||||
}
|
||||
|
||||
@ARGV=@{$args};
|
||||
if ( !GetOptions(
|
||||
'h|?|help' => \$HELP,
|
||||
'v|version' => \$VERSION,
|
||||
) ) {
|
||||
&nodels_usage;
|
||||
}
|
||||
|
||||
# Help
|
||||
if ($HELP) {
|
||||
&nodels_usage;
|
||||
return;
|
||||
}
|
||||
|
||||
# Version
|
||||
if ($VERSION) {
|
||||
my %rsp;
|
||||
$rsp->{data}->[0]= "1.3";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
# TODO -- Parse command arguments
|
||||
# my $opt;
|
||||
# my %attrs;
|
||||
# foreach $opt (@ARGV) {
|
||||
# if ($opt =~ /^group/) {
|
||||
# }
|
||||
# }
|
||||
my $argc = @ARGV;
|
||||
|
||||
|
||||
if (@$nodes > 0 or $noderange) { #Make sure that there are zero nodes *and* that a noderange wasn't requested
|
||||
# TODO - gather data for each node
|
||||
# for now just return the flattened list of nodes)
|
||||
my %rsp; #build up fewer requests, be less chatty
|
||||
if ($argc) {
|
||||
my %tables;
|
||||
foreach (@ARGV) {
|
||||
my $table;
|
||||
my $column;
|
||||
my $temp=$_;
|
||||
if ($shortnames{$temp}) {
|
||||
($table,$column) = @{$shortnames{$temp}};
|
||||
} else {
|
||||
($table,$column) = split('\.',$temp,2);
|
||||
}
|
||||
unless (grep /^$column$/,@{$tables{$table}}) {
|
||||
push @{$tables{$table}},[$column,$temp]; #Mark this as something to get
|
||||
}
|
||||
}
|
||||
my $tab;
|
||||
my %noderecs;
|
||||
foreach $tab (keys %tables) {
|
||||
my $tabh = xCAT::Table->new($tab);
|
||||
unless ($tabh) { next; }
|
||||
#print Dumper($tables{$tab});
|
||||
my $node;
|
||||
foreach $node (@$nodes) {
|
||||
my @cols;
|
||||
my %labels;
|
||||
foreach (@{$tables{$tab}}) {
|
||||
push @cols,$_->[0];
|
||||
$labels{$_->[0]}=$_->[1];
|
||||
}
|
||||
my $rec=$tabh->getNodeAttribs($node,\@cols);
|
||||
foreach (keys %$rec) {
|
||||
my %datseg;
|
||||
$datseg{data}->[0]->{desc} = [$labels{$_}];
|
||||
$datseg{data}->[0]->{contents} = [$rec->{$_}];
|
||||
$datseg{name} = [$node]; #{}->{contents} = [$rec->{$_}];
|
||||
push @{$noderecs{$node}},\%datseg;
|
||||
}
|
||||
}
|
||||
#$rsp->{node}->[0]->{data}->[0]->{desc}->[0] = $_;
|
||||
#$rsp->{node}->[0]->{data}->[0]->{contents}->[0] = $_;
|
||||
$tabh->close();
|
||||
undef $tabh;
|
||||
}
|
||||
foreach (sort (keys %noderecs)) {
|
||||
push @{$rsp->{"node"}},@{$noderecs{$_}};
|
||||
}
|
||||
} else {
|
||||
foreach (@$nodes) {
|
||||
my $noderec;
|
||||
$noderec->{name}->[0]=($_);
|
||||
push @{$rsp->{node}},$noderec;
|
||||
}
|
||||
}
|
||||
$callback->($rsp);
|
||||
} else {
|
||||
# no noderange specified on command line, return list of all nodes
|
||||
my $nodelisttab;
|
||||
if ($nodelisttab=xCAT::Table->new("nodelist")) {
|
||||
my @attribs=("node");
|
||||
my @ents=$nodelisttab->getAllAttribs(@attribs);
|
||||
foreach (@ents) {
|
||||
my %rsp;
|
||||
if ($_->{node}) {
|
||||
$rsp->{node}->[0]->{name}->[0]=($_->{node});
|
||||
# $rsp->{node}->[0]->{data}->[0]->{contents}->[0]="$_->{node} node contents";
|
||||
# $rsp->{node}->[0]->{data}->[0]->{desc}->[0]="$_->{node} node desc";
|
||||
$callback->($rsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
162
xCAT-server-2.0/usr/lib/xcat/plugins/xdsh.pm
Normal file
162
xCAT-server-2.0/usr/lib/xcat/plugins/xdsh.pm
Normal file
@ -0,0 +1,162 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head1
|
||||
xCAT plugin package to handle xdsh
|
||||
|
||||
Supported command:
|
||||
xdsh-> dsh
|
||||
xdcp-> dcp
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
package xCAT_plugin::xdsh;
|
||||
use xCAT::Table;
|
||||
|
||||
use xCAT::Utils;
|
||||
|
||||
use xCAT::MsgUtils;
|
||||
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 handled_commands
|
||||
|
||||
Return list of commands handled by this plugin
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
sub handled_commands
|
||||
{
|
||||
return {
|
||||
xdsh => "xdsh",
|
||||
xdcp => "xdsh"
|
||||
};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 process_request
|
||||
|
||||
Process the command
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub process_request
|
||||
{
|
||||
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $nodes = $request->{node};
|
||||
my $command = $request->{command}->[0];
|
||||
my $args = $request->{arg};
|
||||
my %rsp;
|
||||
$::DSH = "/opt/csm/bin/dsh";
|
||||
$::DCP = "/opt/csm/bin/dcp";
|
||||
|
||||
# check that dsh is installed
|
||||
if (!-e $::DSH)
|
||||
{
|
||||
$rsp->{data}->[0] =
|
||||
"dsh is not installed. Cannot process the command\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (($command eq "xdsh") || ($command eq "xdcp"))
|
||||
{
|
||||
return
|
||||
xdsh($nodes, $args, $callback, $command,
|
||||
$request->{noderange}->[0]);
|
||||
}
|
||||
else
|
||||
{ # error
|
||||
$rsp->{data}->[0] =
|
||||
"Unknown command $command. Cannot process the command\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 xdsh
|
||||
|
||||
Builds and runs the dsh or dcp command
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub xdsh
|
||||
{
|
||||
my $nodes = shift;
|
||||
my $args = shift;
|
||||
my $callback = shift;
|
||||
my $command = shift;
|
||||
my $noderange = shift;
|
||||
|
||||
#
|
||||
# set XCAT Context
|
||||
#
|
||||
$ENV{DSH_CONTEXT} = "XCAT";
|
||||
|
||||
#
|
||||
# if nodes, Put nodes in a file so we do
|
||||
# not risk hitting a command line
|
||||
# limit
|
||||
my $node_file;
|
||||
if ($nodes)
|
||||
{
|
||||
$node_file = xCAT::Utils->make_node_list_file($nodes);
|
||||
$ENV{'DSH_LIST'} = $node_file; # export the file for dsh
|
||||
}
|
||||
|
||||
#
|
||||
# call dsh or dcp
|
||||
#
|
||||
|
||||
my $dsh_dcp_command = "";
|
||||
my %rsp;
|
||||
if ($command eq "xdsh")
|
||||
{
|
||||
$dsh_dcp_command = $::DSH;
|
||||
}
|
||||
else
|
||||
{
|
||||
$dsh_dcp_command = $::DCP;
|
||||
}
|
||||
$dsh_dcp_command .= " ";
|
||||
|
||||
foreach my $arg (@$args)
|
||||
{ # add arguments
|
||||
$dsh_dcp_command .= $arg; # last argument must be command to run
|
||||
$dsh_dcp_command .= " ";
|
||||
}
|
||||
$dsh_dcp_command .= "2>&1";
|
||||
my @local_results = `$dsh_dcp_command`; # run the dsh command
|
||||
my $rc = $? >> 8;
|
||||
my $i = 0;
|
||||
chop @local_results;
|
||||
foreach my $line (@local_results)
|
||||
{
|
||||
$rsp->{data}->[$i] = $line;
|
||||
$i++;
|
||||
}
|
||||
|
||||
#$rsp->{data}->[$i] = "Return Code = $rc\n";
|
||||
xCAT::Utils->close_delete_file($::NODE_LIST_FILE, $node_file);
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
|
||||
#xCAT::MsgUtils->message("I", $rsp);
|
||||
#$callback->($rsp);
|
||||
return 0;
|
||||
}
|
||||
|
97
xCAT-server-2.0/usr/lib/xcat/shfunctions
Normal file
97
xCAT-server-2.0/usr/lib/xcat/shfunctions
Normal file
@ -0,0 +1,97 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
export LOCKDIR=/var/lock/xcat
|
||||
|
||||
|
||||
function needhelp
|
||||
{
|
||||
if [ "$#" = "1" ]
|
||||
then
|
||||
for i in $*
|
||||
do
|
||||
test "$i" = "--help" && echo "\nhttp://xcat.org for support." && return 0
|
||||
test "$i" = "-h" && echo "http://xcat.org for support.\n" && return 0
|
||||
test "$i" = "--version" && echo "$VERSION" && exit 0
|
||||
test "$i" = "-v" && echo "$VERSION" && exit 0
|
||||
done
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function getlock
|
||||
{
|
||||
LOCK=$1
|
||||
TIMEOUT=$2
|
||||
let t=0
|
||||
|
||||
mkdir -p $LOCKDIR
|
||||
|
||||
if [ -r $LOCKDIR/$LOCK.pid ]
|
||||
then
|
||||
PID=$(cat $LOCKDIR/$LOCK.pid)
|
||||
while ps -p $PID >/dev/null 2>&1
|
||||
do
|
||||
sleep 1
|
||||
let t=t+1
|
||||
if (($t -gt $TIMEOUT))
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo "$$" > $LOCKDIR/$LOCK.pid
|
||||
return 0
|
||||
}
|
||||
|
||||
function lockstatus
|
||||
{
|
||||
LOCK=$1
|
||||
|
||||
if [ -r $LOCKDIR/$LOCK.pid ]
|
||||
then
|
||||
PID=$(cat $LOCKDIR/$LOCK.pid)
|
||||
if ps -p $PID >/dev/null 2>&1
|
||||
then
|
||||
echo "locked by PID $PID"
|
||||
ps -fp $PID | tail -1
|
||||
else
|
||||
echo "stale lock PID $PID, remove $LOCKDIR/$LOCK.pid"
|
||||
fi
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "nolock"
|
||||
return 0
|
||||
}
|
||||
|
||||
function freelock
|
||||
{
|
||||
LOCK=$1
|
||||
FORCE=$2
|
||||
|
||||
mkdir -p $LOCKDIR
|
||||
|
||||
if [ "$FORCE" = "1" ]
|
||||
then
|
||||
rm -f $LOCKDIR/$LOCK.pid >/dev/null 2>&1
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -r $LOCKDIR/$LOCK.pid ]
|
||||
then
|
||||
PID=$(cat $LOCKDIR/$LOCK.pid)
|
||||
if [ "$PID" = "$$" ]
|
||||
then
|
||||
rm -f $LOCKDIR/$LOCK.pid
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
100
xCAT-server-2.0/usr/sbin/chtab
Executable file
100
xCAT-server-2.0/usr/sbin/chtab
Executable file
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use xCAT::Table;
|
||||
use xCAT::NodeRange;
|
||||
use Getopt::Long;
|
||||
|
||||
use strict;
|
||||
#This or something like this must always be available and not depend on server
|
||||
#Otherwise, can't set things to let server run in the first place
|
||||
|
||||
sub usage {
|
||||
print "Usage:\n";
|
||||
print " To add or update rows for tables:
|
||||
chtab keycolname=keyvalue[,keycolname=keyvalue...] [tablename.colname=newvalue] [tablename.colname=newvalue]...\n";
|
||||
print " To delete rows from tables:
|
||||
chtab -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename]...\n";
|
||||
print " To display usage and other information:
|
||||
chtab [-h|--help|-v|--Version]\n\n";
|
||||
print " -d|--delete Delete the rows from a list of tables.
|
||||
-v|--version Display the version of this command.
|
||||
-h|--help Display this usage information.
|
||||
keycolname=keyvalue a column name-and-value pair that identifies the rows in a table to be changed.
|
||||
tablename.colname=newvalue the new value for the specified row and column of the table.\n";
|
||||
}
|
||||
|
||||
my %tables;
|
||||
|
||||
# options can be bundled up like -vV
|
||||
Getopt::Long::Configure("bundling") ;
|
||||
$Getopt::Long::ignorecase=0;
|
||||
|
||||
# parse the options
|
||||
if(!GetOptions(
|
||||
'd|delete' => \$::DELETE,
|
||||
'h|help' => \$::HELP,
|
||||
'v|version' => \$::VERSION,))
|
||||
{
|
||||
&usage;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
# display the usage if -h or --help is specified
|
||||
if ($::HELP) { &usage; exit(0);}
|
||||
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($::VERSION)
|
||||
{
|
||||
print "chtab version 1.0\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
my $target = shift @ARGV;
|
||||
unless ($target) {
|
||||
usage;
|
||||
exit(1);
|
||||
}
|
||||
my %keyhash;
|
||||
my @keypairs=split(/,/,$target);
|
||||
foreach (@keypairs) {
|
||||
m/(.*)=(.*)/;
|
||||
my $key=$1;
|
||||
my $val=$2;
|
||||
$keyhash{$key}=$val;
|
||||
}
|
||||
|
||||
|
||||
if ($::DELETE) {
|
||||
#delete option is specified
|
||||
my @tables_to_del=@ARGV;
|
||||
for (@tables_to_del) {
|
||||
$tables{$_} = xCAT::Table->new($_,-create => 1,-autocommit => 0);
|
||||
$tables{$_}->delEntries(\%keyhash);
|
||||
$tables{$_}->commit;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#update or create option
|
||||
my %tableupdates;
|
||||
for (@ARGV) {
|
||||
my $temp;
|
||||
my $table;
|
||||
my $column;
|
||||
my $value;
|
||||
($table,$temp) = split('\.',$_,2);
|
||||
($column,$value) = split("=",$temp,2);
|
||||
unless ($tables{$table}) {
|
||||
$tables{$table} = xCAT::Table->new($table,-create => 1,-autocommit => 0);
|
||||
}
|
||||
$tableupdates{$table}{$column}=$value;
|
||||
}
|
||||
|
||||
#commit all the changes
|
||||
foreach (keys %tables) {
|
||||
if (exists($tableupdates{$_})) {
|
||||
$tables{$_}->setAttribs(\%keyhash,\%{$tableupdates{$_}});
|
||||
}
|
||||
$tables{$_}->commit;
|
||||
}
|
||||
}
|
||||
|
57
xCAT-server-2.0/usr/sbin/mknb
Executable file
57
xCAT-server-2.0/usr/sbin/mknb
Executable file
@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: mknb <arch>"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d /usr/share/xcat/netboot/$1 ]; then
|
||||
echo "Unsupported architecture: $1"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -r ~/.ssh/id_rsa.pub ]; then
|
||||
#echo "Need to generate ssh keys"
|
||||
ssh-keygen -t rsa -q -b 2048 -N "" -f ~/.ssh/id_rsa
|
||||
#exit 1
|
||||
fi
|
||||
mkdir -p /tmp/mknb.$$
|
||||
cp -a /usr/share/xcat/netboot/$1/nbroot/* /tmp/mknb.$$/
|
||||
mkdir -p /tmp/mknb.$$/root/.ssh
|
||||
cp ~/.ssh/id_rsa.pub /tmp/mknb.$$/root/.ssh/authorized_keys
|
||||
if [ -f /install/postscripts/hostkeys/ssh_host_key ]; then
|
||||
cp /install/postscripts/hostkeys/ssh_host_key /tmp/mknb.$$/etc/ssh_host_key
|
||||
cp /install/postscripts/hostkeys/ssh_host_rsa_key /tmp/mknb.$$/etc/ssh_host_rsa_key
|
||||
cp /install/postscripts/hostkeys/ssh_host_dsa_key /tmp/mknb.$$/etc/ssh_host_dsa_key
|
||||
fi
|
||||
if [ ! -f /tmp/mknb.$$/etc/ssh_host_key ]; then
|
||||
echo Generating SSH1 RSA Key...
|
||||
/usr/bin/ssh-keygen -t rsa1 -f /tmp/mknb.$$/etc/ssh_host_key -C '' -N ''
|
||||
echo Generating SSH2 RSA Key...
|
||||
/usr/bin/ssh-keygen -t rsa -f /tmp/mknb.$$/etc/ssh_host_rsa_key -C '' -N ''
|
||||
echo Generating SSH2 DSA Key...
|
||||
/usr/bin/ssh-keygen -t dsa -f /tmp/mknb.$$/etc/ssh_host_dsa_key -C '' -N ''
|
||||
fi
|
||||
cd /tmp/mknb.$$
|
||||
echo "Packing nbfs.$1.gz"
|
||||
find . | cpio -o -H newc | gzip -9 > /tftpboot/xcat/nbfs.$1.gz
|
||||
cd -
|
||||
rm -rf /tmp/mknb.$$
|
||||
if [ "$1" = "x86_64" -a ! -f /tftpboot/pxelinux.0 -a -f /usr/lib/syslinux/pxelinux.0 ]; then
|
||||
cp /usr/lib/syslinux/pxelinux.0 /tftpboot/pxelinux.0
|
||||
fi
|
||||
if [ "$1" = "x86_64" -a ! -f /tftpboot/pxelinux.cfg/default ]; then
|
||||
mkdir -p /tftpboot/pxelinux.cfg
|
||||
echo "default xCAT
|
||||
LABEL xCAT
|
||||
KERNEL xcat/nbk.x86_64
|
||||
APPEND initrd=xcat/nbfs.x86_64.gz xcatd="`gettab key=master site.value|awk -F: '{print $2}'`:`gettab key=xcatdport site.value|awk -F: '{print $2}'` > /tftpboot/pxelinux.cfg/default
|
||||
fi
|
||||
if [ "$1" = "ppc64" -a ! -f /tftpboot/etc/yaboot.conf ]; then
|
||||
mkdir -p /tftpboot/etc
|
||||
echo "timeout=5
|
||||
label=xcat
|
||||
image=xcat/nbk.ppc64
|
||||
initrd=xcat/nbfs.ppc64.gz
|
||||
append=\"xcatd="`gettab key=master site.value|awk -F: '{print $2}'`:`gettab key=xcatdport site.value|awk -F: '{print $2}'`\"> /tftpboot/etc/yaboot.conf
|
||||
fi
|
||||
|
||||
|
685
xCAT-server-2.0/usr/sbin/xcatd
Executable file
685
xCAT-server-2.0/usr/sbin/xcatd
Executable file
@ -0,0 +1,685 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
use Socket;
|
||||
use IO::Socket;
|
||||
use IO::Handle;
|
||||
use IO::Select;
|
||||
use IO::Socket::SSL;
|
||||
use IO::Socket::INET;
|
||||
use XML::Simple;
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
use Sys::Syslog;
|
||||
use xCAT::NotifHandler;
|
||||
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
|
||||
use Storable qw(dclone);
|
||||
use POSIX qw(WNOHANG setsid);
|
||||
use strict;
|
||||
my $pidfile;
|
||||
GetOptions(
|
||||
'pidfile|p=s' => \$pidfile
|
||||
);
|
||||
|
||||
my $plugins_dir='/usr/lib/xcat/plugins';
|
||||
my $quit = 0;
|
||||
my $port;
|
||||
my $sport;
|
||||
my $domain;
|
||||
my $xcatdir;
|
||||
my $sitetab=xCAT::Table->new('site');
|
||||
unless ($sitetab) {
|
||||
print ("ERROR: Unable to open basic site table for configuration\n");
|
||||
}
|
||||
my ($tmp) = $sitetab->getAttribs({'key'=>'xcatdport'},'value');
|
||||
unless ($tmp) {
|
||||
die "ERROR:Need xcatdport defined in site table, try chtab key=xcatdport site.value=3001";
|
||||
}
|
||||
$port = $tmp->{value};
|
||||
$sport = $tmp->{value}+1;
|
||||
|
||||
($tmp) = $sitetab->getAttribs({'key'=>'xcatconfdir'},'value');
|
||||
$xcatdir = ($tmp ? $tmp->{value} : "/etc/xcat");
|
||||
|
||||
my $progname;
|
||||
$SIG{PIPE} = sub { die "SIGPIPE $$progname encountered a broken pipe (probably Ctrl-C by client)" };
|
||||
sub daemonize {
|
||||
chdir('/');
|
||||
umask 0;
|
||||
my $pid;
|
||||
defined($pid = fork) or die "Can't fork: $!";
|
||||
if ($pid) {
|
||||
if ($pidfile) {
|
||||
open(PFILE, '>', $pidfile);
|
||||
print PFILE $pid;
|
||||
close (PFILE);
|
||||
} else {
|
||||
printf ("xCATd starting as PID $pid \n");
|
||||
}
|
||||
exit;
|
||||
}
|
||||
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
|
||||
open STDOUT, '>/dev/null';
|
||||
open STDERR, '>/dev/null';
|
||||
$0='xcatd';
|
||||
$progname = \$0;
|
||||
setsid or die "Can't start new session";
|
||||
}
|
||||
|
||||
my %cmd_handlers;
|
||||
sub do_installm_service {
|
||||
#This function servers as a handler for messages from installing nodes
|
||||
my $socket = IO::Socket::INET->new(LocalPort=>$sport,
|
||||
Proto => 'tcp',
|
||||
ReuseAddr => 1,
|
||||
Listen => 64);
|
||||
unless ($socket) {
|
||||
syslog("local1|err","xcatd unable to open install monitor services on $sport");
|
||||
die;
|
||||
}
|
||||
until ($quit) {
|
||||
$SIG{ALRM} = sub { die "XCATTIMEOUT"; };
|
||||
my $conn;
|
||||
next unless $conn = $socket->accept;
|
||||
my $client = gethostbyaddr(inet_aton($conn->peerhost),AF_INET);
|
||||
$client =~ s/\..*//;
|
||||
my $node;
|
||||
($node) = noderange($client); #ensure this is coming from a node IP at least
|
||||
unless ($node) { #Means the source isn't a valid deal...
|
||||
close($conn);
|
||||
next;
|
||||
}
|
||||
eval {
|
||||
alarm(2);
|
||||
print $conn "ready\n";
|
||||
while (my $text = <$conn>) {
|
||||
alarm(0);
|
||||
print $conn "done\n";
|
||||
$text =~ s/\r//g;
|
||||
if ($text =~ /next/) {
|
||||
my %request = (
|
||||
command => [ 'nodeset' ],
|
||||
node => [ $node ],
|
||||
arg => [ 'next' ],
|
||||
);
|
||||
close($conn);
|
||||
my $pid=fork();
|
||||
unless ($pid) { #fork off the nodeset and potential slowness
|
||||
plugin_command(\%request,undef,\&convey_response);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
alarm(2);
|
||||
}
|
||||
alarm(0);
|
||||
};
|
||||
if ($@) {
|
||||
if ($@ =~ /XCATTIMEOUT/) {
|
||||
syslog("local1|err","xcatd installmonitor timed out talking to $node");
|
||||
} else {
|
||||
syslog("local1|err","xcatd: possible BUG encountered by xCAT install monitor service: ".$@);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub do_udp_service { #This function opens up a UDP port
|
||||
#It will do similar to the standard service, except:
|
||||
#-Obviously, unencrypted and messages are not guaranteed
|
||||
#-For that reason, more often than not plugins designed with
|
||||
#-this method will not expect to have a callback
|
||||
#Also, this throttles to handle one message at a time, so no forking either
|
||||
#Explicitly, to handle whatever operations nodes periodically send during discover state
|
||||
#Could be used for heartbeating and such as desired
|
||||
my $socket = IO::Socket::INET->new(LocalPort => $port,
|
||||
Proto => 'udp');
|
||||
openlog("xCAT UDP",'','local1');
|
||||
unless ($socket) {
|
||||
syslog("err","xCAT UDP service unable to open port $port: $!");
|
||||
closelog();
|
||||
die "Unable to start UDP on $port";
|
||||
}
|
||||
my $data;
|
||||
my $part;
|
||||
my $sport;
|
||||
my $client;
|
||||
my $peerhost;
|
||||
until ($quit) {
|
||||
eval { while ($part = $socket->recv($data,1500)) {
|
||||
($sport,$client) = sockaddr_in($part);
|
||||
$peerhost=gethostbyaddr($client,AF_INET)."\n";
|
||||
my $req = eval { XMLin($data, SuppressEmpty=>undef,ForceArray=>1) };
|
||||
if ($req and $req->{command} and ($req->{command}->[0] eq "findme")) {
|
||||
$req->{'!xcat_clienthost'}=gethostbyaddr($client,AF_INET)."\n";
|
||||
$req->{'!xcat_clientip'}=inet_ntoa($client);
|
||||
$req->{'!xcat_clientport'}=$sport;
|
||||
if (defined($cmd_handlers{"findme"})) {
|
||||
plugin_command($req,undef,\&convey_response);
|
||||
}
|
||||
}
|
||||
if ($quit) { last; }
|
||||
}
|
||||
};
|
||||
if ($@) {
|
||||
syslog("local1|err","xcatd: possible BUG encountered by xCAT UDP service: ".$@);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub scan_plugins {
|
||||
my @plugins=glob($plugins_dir."/*.pm");
|
||||
foreach (@plugins) {
|
||||
/.*\/([^\/]*).pm$/;
|
||||
my $modname = $1;
|
||||
require "$_";
|
||||
no strict 'refs';
|
||||
my $cmd_adds=${"xCAT_plugin::".$modname."::"}{handled_commands}->();
|
||||
foreach (keys %$cmd_adds) {
|
||||
my $value = $_;
|
||||
if (defined($cmd_handlers{$_})) {
|
||||
my $add=1;
|
||||
#This next bit of code iterates through the handlers.
|
||||
#If the value doesn't contain an equal, and has an equivalent entry added by
|
||||
# another plugin already, don't add (otherwise would hit the DB multiple times)
|
||||
# a better idea, restructure the cmd_handlers as a multi-level hash
|
||||
# prove out this idea real quick before doing that
|
||||
foreach (@{$cmd_handlers{$_}}) {
|
||||
if (($_->[1] eq $cmd_adds->{$value}) and (($cmd_adds->{$value} !~ /=/) or ($_->[0] eq $modname))) {
|
||||
$add = 0;
|
||||
}
|
||||
}
|
||||
if ($add) { push @{$cmd_handlers{$_}},[$modname,$cmd_adds->{$_}]; }
|
||||
#die "Conflicting handler information from $modname";
|
||||
} else {
|
||||
$cmd_handlers{$_} = [ [$modname,$cmd_adds->{$_}] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scan_plugins;
|
||||
daemonize;
|
||||
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) {} };
|
||||
$SIG{TERM} = $SIG{INT} = sub { printf("Asked to quit...\n"); $quit++ };
|
||||
|
||||
my $pid = fork;
|
||||
defined $pid or die "Unable to fork for UDP/TCP";
|
||||
unless ($pid) {
|
||||
$$progname="xcatd: UDP listener";
|
||||
do_udp_service;
|
||||
exit(0);
|
||||
}
|
||||
$pid = fork;
|
||||
defined $pid or die "Unable to fork installmonitor";
|
||||
unless ($pid) {
|
||||
$$progname="xcatd: install monitor";
|
||||
do_installm_service;
|
||||
exit(0);
|
||||
}
|
||||
$$progname="xcatd: SSL listener";
|
||||
openlog("xCAT SSL","","local1");
|
||||
my $listener = IO::Socket::SSL->new(
|
||||
LocalPort => $port,
|
||||
Listen => 64,
|
||||
Reuse => 1,
|
||||
SSL_key_file=>$xcatdir."/cert/server-key.pem",
|
||||
SSL_cert_file=>$xcatdir."/cert/server-cert.pem",
|
||||
SSL_ca_file=>$xcatdir."/cert/ca.pem",
|
||||
SSL_verify_mode=> 1
|
||||
);
|
||||
|
||||
unless ($listener) {
|
||||
kill $pid;
|
||||
syslog("err","xCAT service unable to open SSL services on $port: $!");
|
||||
closelog();
|
||||
die "ERROR:Unable to start xCAT service on port $port.";
|
||||
}
|
||||
closelog();
|
||||
|
||||
#setup signal in NotifHandler so that the cache can be updated
|
||||
xCAT::NotifHandler::setup($$);
|
||||
|
||||
my $peername;
|
||||
until ($quit) {
|
||||
next unless my $connection=$listener->accept;
|
||||
my $child = fork(); #Yes we fork, IO::Socket::SSL is not threadsafe..
|
||||
|
||||
unless (defined $child) {
|
||||
die "xCATd cannot fork";
|
||||
}
|
||||
|
||||
if ($child == 0) {
|
||||
$listener->close;
|
||||
my $peerhost=undef;
|
||||
my $peer=$connection->peer_certificate("owner");
|
||||
if ($peer) {
|
||||
$peer =~ m/CN=([^\/]*)/;
|
||||
$peername = $1;
|
||||
} else {
|
||||
$peername=undef;
|
||||
}
|
||||
my ($tmp) = $sitetab->getAttribs({'key'=>'domain'},'value');
|
||||
if (defined $tmp->{value}) {
|
||||
$domain = $tmp->{value};
|
||||
}
|
||||
$peerhost = gethostbyaddr(inet_aton($connection->peerhost),AF_INET);
|
||||
$peerhost =~ s/\.$domain\.*$//;
|
||||
$peerhost =~ s/-eth\d*$//;
|
||||
$peerhost =~ s/-myri\d*$//;
|
||||
$peerhost =~ s/-ib\d*$//;
|
||||
#printf('info'.": xcatd: connection from ".($peername ? $peername . "@" . $peerhost : $peerhost)."\n");
|
||||
$$progname="xCATd SSL: Instance for ".($peername ? $peername ."@".$peerhost : $peerhost);
|
||||
service_connection($connection,$peername,$peerhost);
|
||||
exit(0);
|
||||
}
|
||||
$connection->close(SSL_no_shutdown => 1); #Without no shutdown, you can guess what the client ends up thinking..
|
||||
}
|
||||
$listener->close;
|
||||
|
||||
|
||||
my $parent_fd;
|
||||
my %resps;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub plugin_command {
|
||||
my $req = shift;
|
||||
my $sock = shift;
|
||||
my $callback = shift;
|
||||
my %handler_hash;
|
||||
use xCAT::NodeRange;
|
||||
$Main::resps={};
|
||||
my @nodes;
|
||||
if ($req->{node}) {
|
||||
@nodes = @{$req->{node}};
|
||||
} elsif ($req->{noderange}) {
|
||||
@nodes = noderange($req->{noderange}->[0]);
|
||||
if (nodesmissed) {
|
||||
my $rsp = {errorcode=>1,error=>"Invalid nodes in noderange:".join(',',nodesmissed)};
|
||||
if ($sock) {
|
||||
print $sock XMLout($rsp,RootName=>'xcatresponse' ,NoAttr=>1);
|
||||
}
|
||||
return ($rsp);
|
||||
}
|
||||
}
|
||||
if (@nodes) { $req->{node} = \@nodes; }
|
||||
if (defined($cmd_handlers{$req->{command}->[0]})) {
|
||||
my $hdlspec;
|
||||
foreach (@{$cmd_handlers{$req->{command}->[0]}}) {
|
||||
$hdlspec =$_->[1];
|
||||
my $ownmod = $_->[0];
|
||||
if ($hdlspec =~ /:/) { #Specificed a table lookup path for plugin name
|
||||
my $table;
|
||||
my $cols;
|
||||
($table,$cols) = split(/:/,$hdlspec);
|
||||
my @colmns=split(/,/,$cols);
|
||||
my @columns;
|
||||
my $hdlrtable=xCAT::Table->new($table);
|
||||
unless ($hdlrtable) {
|
||||
#TODO: proper error handling
|
||||
}
|
||||
my $node;
|
||||
my $colvals = {};
|
||||
foreach my $colu (@colmns) {
|
||||
if ($colu =~ /=/) { #a value redirect to a pattern/specific name
|
||||
my $coln; my $colv;
|
||||
($coln,$colv) = split(/=/,$colu,2);
|
||||
$colvals->{$coln} = $colv;
|
||||
push (@columns,$coln);
|
||||
} else {
|
||||
push (@columns,$colu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unless (@nodes) { #register the plugin in the event of usage
|
||||
$handler_hash{$ownmod} = 1;
|
||||
}
|
||||
foreach $node (@nodes) {
|
||||
my $attribs = $hdlrtable->getNodeAttribs($node,\@columns);
|
||||
unless (defined($attribs)) { next; } #TODO: This really ought to craft an unsupported response for this request
|
||||
foreach (@columns) {
|
||||
my $col=$_;
|
||||
if (defined($attribs->{$col})) {
|
||||
if ($colvals->{$col}) { #A pattern match style request.
|
||||
if ($attribs->{$col} =~ /$colvals->{$col}/) {
|
||||
$handler_hash{$ownmod}->{$node} = 1;
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
$handler_hash{$attribs->{$col}}->{$node} = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unless (@nodes) {
|
||||
$handler_hash{$hdlspec} = 1;
|
||||
}
|
||||
foreach (@nodes) { #Specified a specific plugin, not a table lookup
|
||||
$handler_hash{$hdlspec}->{$_} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 1; #TODO: error back that request has no known plugin for it
|
||||
}
|
||||
my $children=0;
|
||||
$SIG{CHLD} = sub {while (waitpid(-1, WNOHANG) > 0) { $children--; } };
|
||||
my $check_fds;
|
||||
if ($sock) {
|
||||
$check_fds = new IO::Select;
|
||||
}
|
||||
foreach (keys %handler_hash) {
|
||||
my $modname = $_;
|
||||
if (-r $plugins_dir."/".$modname.".pm") {
|
||||
require $plugins_dir."/".$modname.".pm";
|
||||
$children++;
|
||||
my $pfd; #will be referenced for inter-process messaging.
|
||||
my $child;
|
||||
if ($sock) { #If $sock not passed in, don't fork..
|
||||
socketpair($pfd, $parent_fd,AF_UNIX,SOCK_STREAM,PF_UNSPEC) or die "socketpair: $!";
|
||||
#pipe($pfd,$cfd);
|
||||
$parent_fd->autoflush(1);
|
||||
$pfd->autoflush(1);
|
||||
$child = fork;
|
||||
} else {
|
||||
$child = 0;
|
||||
}
|
||||
unless (defined $child) { die "Fork failed"; }
|
||||
if ($child == 0) {
|
||||
my $oldprogname=$$progname;
|
||||
$$progname=$oldprogname.": $modname instance";
|
||||
if ($sock) { close $pfd; }
|
||||
unless ($handler_hash{$_} == 1) {
|
||||
my @nodes = sort {($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] || $a cmp $b } (keys %{$handler_hash{$_}});
|
||||
$req->{node}=\@nodes;
|
||||
}
|
||||
no strict "refs";
|
||||
${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
|
||||
$$progname=$oldprogname;
|
||||
if ($sock) {
|
||||
close($parent_fd);
|
||||
exit(0);
|
||||
}
|
||||
} else {
|
||||
close $parent_fd;
|
||||
$check_fds->add($pfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
unless ($sock) { return $Main::resps };
|
||||
while ($children > 0) {
|
||||
relay_fds($check_fds,$sock);
|
||||
}
|
||||
#while (relay_fds($check_fds,$sock)) {}
|
||||
my %done;
|
||||
$done{serverdone} = {};
|
||||
if ($req->{transid}) {
|
||||
$done{transid}=$req->{transid}->[0];
|
||||
}
|
||||
if ($sock) { print $sock XMLout(\%done,RootName => 'xcatresponse',NoAttr=>1); }
|
||||
}
|
||||
|
||||
|
||||
sub do_request {
|
||||
my $req = shift;
|
||||
my $second = shift;
|
||||
my $rsphandler = \&build_response;
|
||||
my $sock = undef;
|
||||
if ($second) {
|
||||
if (ref($second) eq "CODE") {
|
||||
$rsphandler = $second;
|
||||
} elsif (ref($second) eq "GLOB") {
|
||||
$sock = $second;
|
||||
}
|
||||
}
|
||||
|
||||
#my $sock = shift; #If no sock, will return a response hash
|
||||
if ($cmd_handlers{$req->{command}->[0]}) {
|
||||
return plugin_command($req,$sock,$rsphandler);
|
||||
} elsif ($req->{command}->[0] eq "noderange" and $req->{noderange}) {
|
||||
my @nodes = noderange($req->{noderange}->[0]);
|
||||
my %resp;
|
||||
if (nodesmissed) {
|
||||
$resp{warning}="Invalid nodes in noderange:".join ',',nodesmissed;
|
||||
}
|
||||
$resp{serverdone} = {};
|
||||
@{$resp{node}}=@nodes;
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
if ($sock) {
|
||||
print $sock XMLout(\%resp,RootName => 'xcatresponse',NoAttr=>1);
|
||||
} else {
|
||||
return (\%resp);
|
||||
}
|
||||
} else {
|
||||
my %resp=(error=>"Unsupported request");
|
||||
$resp{serverdone} = {};
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
if ($sock) {
|
||||
print $sock XMLout(\%resp,RootName => 'xcatresponse',NoAttr=>1);
|
||||
} else {
|
||||
return (\%resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub convey_response {
|
||||
my $resp=shift;
|
||||
#TODO: This is where the following will/may happen:
|
||||
#-Track transaction id
|
||||
#-Save output for deferred commands
|
||||
unless ($parent_fd) {
|
||||
build_response($resp);
|
||||
return;
|
||||
}
|
||||
print $parent_fd XMLout($resp,KeyAttr=>[], NoAttr=>1,RootName=>'xcatresponse');
|
||||
<$parent_fd>; #Block until parent acks data
|
||||
#print "woo";
|
||||
# KeyAttr => [], NoAttr => 1)
|
||||
}
|
||||
|
||||
sub build_response {
|
||||
# Handle responses from do_request calls made directly from a plugin
|
||||
# Merge this response into the full response hash. We'll collect all
|
||||
# the responses and ship it back on the return to the plugin.
|
||||
# Note: Need to create a new "deep clone" copy of each response structure
|
||||
# otherwise the next call will overwrite the reference we pushed on
|
||||
# the response array
|
||||
my $resp = shift;
|
||||
foreach (keys %$resp) {
|
||||
my $subresp = dclone($resp->{$_});
|
||||
push (@{$Main::resps->{$_}}, @{$subresp});
|
||||
}
|
||||
}
|
||||
|
||||
sub service_connection {
|
||||
my $sock = shift;
|
||||
my $peername = shift;
|
||||
my $peerhost = shift;
|
||||
my $peerport = $sock->peerport;
|
||||
my %tables=();
|
||||
#some paranoid measures could reduce a third party abusing stage3 image to attempting to get USER/PASS for BMCs:
|
||||
# -Well, minimally, ignore requests if requesting node is not in spconfig mode (stage3)
|
||||
# -Option to generate a random password per 'getipmi' request. This reduces the exposure to a D.O.S. hopefully
|
||||
#Give only 15 seconds of silence allowed or terminate connection. Using alarm since we are in thread-unsafe world anyway
|
||||
my $timedout = 0;
|
||||
|
||||
$SIG{ALRM} = sub { $timedout = 1; die; };
|
||||
eval {
|
||||
my $request;
|
||||
my $req=undef;
|
||||
alarm(15);
|
||||
while (<$sock>) {
|
||||
alarm(0);
|
||||
$request .= $_;
|
||||
#$req = eval { XMLin($request, ForceArray => [ 'attribute' , 'attributepair' ]) };
|
||||
if ($request =~ m/<\/xcatrequest>/) {
|
||||
$req = eval { XMLin($request, SuppressEmpty=>undef,ForceArray=>1) };
|
||||
#we have a full request..
|
||||
#printf $request."\n";
|
||||
$request="";
|
||||
if (validate($peername,$peerhost,$req)) {
|
||||
$req->{'!xcat_authname'} = [$peername];
|
||||
$req->{'!xcat_clienthost'} = [$peerhost];
|
||||
$req->{'!xcat_clientport'}= [$peerport];
|
||||
$$progname="xCATd SSL: ".$req->{command}->[0]." for ".($peername ? $peername ."@".$peerhost : $peerhost);
|
||||
if ($cmd_handlers{$req->{command}->[0]}) {
|
||||
return plugin_command($req,$sock,\&convey_response);
|
||||
} elsif ($req->{command}->[0] eq "noderange" and $req->{noderange}) {
|
||||
my @nodes = noderange($req->{noderange}->[0]);
|
||||
my %resp;
|
||||
if (nodesmissed) {
|
||||
$resp{warning}="Invalid nodes in noderange:".join ',',nodesmissed;
|
||||
}
|
||||
$resp{serverdone} = {};
|
||||
@{$resp{node}}=@nodes;
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
print $sock XMLout(\%resp,RootName => 'xcatresponse',NoAttr=>1);
|
||||
next;
|
||||
} else {
|
||||
my %resp=(error=>"Unsupported request");
|
||||
$resp{serverdone} = {};
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
print $sock XMLout(\%resp,RootName => 'xcatresponse',NoAttr=>1);
|
||||
next;
|
||||
}
|
||||
} else {
|
||||
my %resp=(error=>"Permission denied for request");
|
||||
$resp{serverdone} = {};
|
||||
if ($req->{transid}) {
|
||||
$resp{transid}=$req->{transid}->[0];
|
||||
}
|
||||
my $response=XMLout(\%resp,RootName =>'xcatresponse',NoAttr => 1);
|
||||
print $sock $response;
|
||||
next;
|
||||
}
|
||||
}
|
||||
alarm(15);
|
||||
}
|
||||
};
|
||||
if ($@) { # The eval statement caught a program bug..
|
||||
unless ($@ =~ /^SIGPIPE/) {
|
||||
syslog("local1|err","xcatd: possible BUG encountered by xCAT TCP service: ".$@);
|
||||
} else {
|
||||
syslog("local1|info","xcatd: Unexpected client disconnect");
|
||||
}
|
||||
}
|
||||
alarm(0);
|
||||
foreach (keys %tables) {
|
||||
$tables{$_}->commit;
|
||||
}
|
||||
$sock->close;
|
||||
if ($timedout == 1) {
|
||||
printf ("Client timeout");
|
||||
}
|
||||
}
|
||||
|
||||
sub relay_fds { #Relays file descriptors from pipes to children to the SSL socket
|
||||
my $fds = shift;
|
||||
my $sock = shift;
|
||||
unless ($sock) { return 0; }
|
||||
my $collate = ( scalar @_ > 0 ? shift : 0);
|
||||
my @readyset = $fds->can_read(1);
|
||||
my $rfh;
|
||||
my $rc = @readyset;
|
||||
my $text;
|
||||
foreach $rfh (@readyset) { #go through each child, extract a complete, atomic message
|
||||
my $line;
|
||||
while ($line = <$rfh>) { #Will break on complete </xcatresponse> messages, avoid interleave
|
||||
print $sock $line;
|
||||
if ($line =~ /<\/xcatresponse>/) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($line) {
|
||||
print $rfh "fin\n"; #Notify convey_response message done
|
||||
} else {
|
||||
$fds->remove($rfh);
|
||||
close($rfh);
|
||||
}
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
sub validate {
|
||||
#BIG TODO, make this do something meaningful
|
||||
#here is where we check if $peername is allowed to do $request. $peername if set signifies client has a
|
||||
#cert that the xCAT CA accepted. This will be a policy table with $peername as key
|
||||
#things like 'stage2/stage3' and install images will have no client certificate.
|
||||
#A client key for something that a third party could easily tftp down themselves means nothing
|
||||
#however, privacy between the nodes can be maintained, and $peerhost will be checked just like 1.2.0.
|
||||
# returns 1 if policy engine allows the action, 0 if denied
|
||||
my $peername=shift;
|
||||
my $peerhost=shift;
|
||||
my $request=shift;
|
||||
my $policytable = xCAT::Table->new('policy');
|
||||
unless ($policytable) {
|
||||
syslog("err","Unable to open policy data, denying");
|
||||
return 0;
|
||||
}
|
||||
my @policies = $policytable->getTable;
|
||||
my $rule;
|
||||
foreach $rule (@policies) {
|
||||
if ($rule->{name} and $rule->{name} ne '*') {
|
||||
#TODO: more complex matching (lists, wildcards)
|
||||
next unless ($peername eq $rule->{name});
|
||||
}
|
||||
if ($rule->{time} and $rule->{time} ne '*') {
|
||||
#TODO: time ranges
|
||||
}
|
||||
if ($rule->{host} and $rule->{host} ne '*') {
|
||||
#TODO: more complex matching (lists, noderanges?, wildcards)
|
||||
next unless ($peerhost eq $rule->{host});
|
||||
}
|
||||
if ($rule->{commands} and $rule->{commands} ne '*') {
|
||||
#TODO: syntax for multiple commands
|
||||
next unless ($request->{command}->[0] eq $rule->{commands});
|
||||
}
|
||||
if ($rule->{parameters} and $rule->{parameters} ne '*') {
|
||||
next; #TODO: not ignore this field
|
||||
}
|
||||
if ($rule->{noderange} and $rule->{noderange} ne '*') {
|
||||
next; #TODO: not ignore this field
|
||||
}
|
||||
# If we are still in, that means this rule is the first match and dictates behavior.
|
||||
if ($rule->{rule}) {
|
||||
if ($rule->{rule} =~ /allow/i or $rule->{rule} =~ /accept/i) {
|
||||
my $logst = "xCAT: Allowing ".$request->{command}->[0];
|
||||
if ($peername) { $logst .= " for " . $peername };
|
||||
syslog("authpriv|info",$logst);
|
||||
return 1;
|
||||
} else {
|
||||
my $logst = "xCAT: Denying ".$request->{command}->[0];
|
||||
if ($peername) { $logst .= " for " . $peername };
|
||||
syslog("authpriv|info",$logst);
|
||||
return 0;
|
||||
}
|
||||
} else { #Shouldn't be possible....
|
||||
syslog("err","Impossible line in xcatd reached");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#Reached end of policy table, reject by default.
|
||||
syslog("err","Request matched no policy rule: ".$request->{command}->[0]);
|
||||
return 0;
|
||||
}
|
||||
|
73
xCAT-server-2.0/usr/share/xcat/ca/Makefile
Normal file
73
xCAT-server-2.0/usr/share/xcat/ca/Makefile
Normal file
@ -0,0 +1,73 @@
|
||||
# $Id: Makefile,v 1.4 2006/06/20 18:55:37 jmates Exp $
|
||||
#
|
||||
# NOTE If running OpenSSL 0.9.8a or higher, see -newkey, below.
|
||||
#
|
||||
# Automates the setup of a custom Certificate Authority and provides
|
||||
# routines for signing and revocation of certificates. To use, first
|
||||
# customize the commands in this file and the settings in openssl.cnf,
|
||||
# then run:
|
||||
#
|
||||
# make init
|
||||
#
|
||||
# Then, copy in certificate signing requests, and ensure their suffix is
|
||||
# .csr before signing them with the following command:
|
||||
#
|
||||
# make sign
|
||||
#
|
||||
# To revoke a key, name the certificate file with the cert option
|
||||
# as shown below:
|
||||
#
|
||||
# make revoke cert=foo.cert
|
||||
#
|
||||
# This will revoke the certificate and call gencrl; the revocation list
|
||||
# will then need to be copied somehow to the various systems that use
|
||||
# your CA cert.
|
||||
|
||||
requests = *.csr
|
||||
|
||||
sign: ${requests}
|
||||
|
||||
# remove -batch option if want chance to not certify a particular request
|
||||
${requests}: FORCE
|
||||
@openssl ca -config openssl.cnf -in $@ -out ${@:.csr=.cert}
|
||||
@[ -f ${@:.csr=.cert} ] && rm $@
|
||||
|
||||
revoke:
|
||||
@test $${cert:?"usage: make revoke cert=certificate"}
|
||||
@openssl ca -config openssl.cnf -revoke $(cert)
|
||||
@$(MAKE) gencrl
|
||||
|
||||
gencrl:
|
||||
@openssl ca -config openssl.cnf -gencrl -out ca-crl.pem
|
||||
|
||||
clean:
|
||||
-rm ${requests}
|
||||
|
||||
# creates required supporting files, CA key and certificate
|
||||
init:
|
||||
@test ! -f serial
|
||||
@mkdir crl certs private
|
||||
@chmod go-rwx private
|
||||
@echo '01' > serial
|
||||
@touch index
|
||||
# NOTE use "-newkey rsa:2048" if running OpenSSL 0.9.8a or higher
|
||||
# @openssl req -nodes -config openssl.cnf -days 2650 -x509 -newkey rsa:2048 -out ca-cert.pem -outform PEM
|
||||
|
||||
help:
|
||||
@echo make sign
|
||||
@echo ' - signs all *.csr files in this directory'
|
||||
@echo
|
||||
@echo make revoke cert=filename
|
||||
@echo ' - revokes certificate in named file and calls gencrl'
|
||||
@echo
|
||||
@echo make gencrl
|
||||
@echo ' - updates Certificate Revocation List (CRL)'
|
||||
@echo
|
||||
@echo make clean
|
||||
@echo ' - removes all *.csr files in this directory'
|
||||
@echo
|
||||
@echo make init
|
||||
@echo ' - required initial setup command for new CA'
|
||||
|
||||
# for legacy make support
|
||||
FORCE:
|
313
xCAT-server-2.0/usr/share/xcat/ca/openssl.cnf.tmpl
Normal file
313
xCAT-server-2.0/usr/share/xcat/ca/openssl.cnf.tmpl
Normal file
@ -0,0 +1,313 @@
|
||||
#
|
||||
# OpenSSL example configuration file.
|
||||
# This is mostly being used for generation of certificate requests.
|
||||
#
|
||||
|
||||
# This definition stops the following lines choking if HOME isn't
|
||||
# defined.
|
||||
HOME = .
|
||||
RANDFILE = $ENV::HOME/.rnd
|
||||
|
||||
# Extra OBJECT IDENTIFIER info:
|
||||
#oid_file = $ENV::HOME/.oid
|
||||
oid_section = new_oids
|
||||
|
||||
# To use this configuration file with the "-extfile" option of the
|
||||
# "openssl x509" utility, name here the section containing the
|
||||
# X.509v3 extensions to use:
|
||||
# extensions =
|
||||
# (Alternatively, use a configuration file that has only
|
||||
# X.509v3 extensions in its main [= default] section.)
|
||||
|
||||
[ new_oids ]
|
||||
|
||||
# We can add new OIDs in here for use by 'ca' and 'req'.
|
||||
# Add a simple OID like this:
|
||||
# testoid1=1.2.3.4
|
||||
# Or use config file substitution like this:
|
||||
# testoid2=${testoid1}.5.6
|
||||
|
||||
####################################################################
|
||||
[ ca ]
|
||||
default_ca = CA_default # The default ca section
|
||||
|
||||
####################################################################
|
||||
[ CA_default ]
|
||||
|
||||
dir = ##XCATCADIR## # Where everything is kept
|
||||
certs = $dir/certs # Where the issued certs are kept
|
||||
crl_dir = $dir/crl # Where the issued crl are kept
|
||||
database = $dir/index # database index file.
|
||||
#unique_subject = no # Set to 'no' to allow creation of
|
||||
# several ctificates with same subject.
|
||||
new_certs_dir = $dir/certs # default place for new certs.
|
||||
|
||||
certificate = $dir/ca-cert.pem # The CA certificate
|
||||
serial = $dir/serial # The current serial number
|
||||
crlnumber = $dir/crlnumber # the current crl number
|
||||
# must be commented out to leave a V1 CRL
|
||||
crl = $dir/crl.pem # The current CRL
|
||||
private_key = $dir/private/ca-key.pem # The private key
|
||||
RANDFILE = $dir/private/.rand # private random number file
|
||||
|
||||
x509_extensions = usr_cert # The extentions to add to the cert
|
||||
|
||||
# Comment out the following two lines for the "traditional"
|
||||
# (and highly broken) format.
|
||||
name_opt = ca_default # Subject Name options
|
||||
cert_opt = ca_default # Certificate field options
|
||||
|
||||
# Extension copying option: use with caution.
|
||||
# copy_extensions = copy
|
||||
|
||||
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
|
||||
# so this is commented out by default to leave a V1 CRL.
|
||||
# crlnumber must also be commented out to leave a V1 CRL.
|
||||
# crl_extensions = crl_ext
|
||||
|
||||
default_days = 7300 # how long to certify for
|
||||
default_crl_days= 30 # how long before next CRL
|
||||
default_md = sha1 # which md to use.
|
||||
preserve = no # keep passed DN ordering
|
||||
|
||||
# A few difference way of specifying how similar the request should look
|
||||
# For type CA, the listed attributes must be the same, and the optional
|
||||
# and supplied fields are just that :-)
|
||||
policy = policy_match
|
||||
|
||||
# For the CA policy
|
||||
[ policy_match ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
# For the 'anything' policy
|
||||
# At this point in time, you must list all acceptable 'object'
|
||||
# types.
|
||||
[ policy_anything ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
####################################################################
|
||||
[ req ]
|
||||
default_bits = 2048
|
||||
default_keyfile = private/ca-key.pem
|
||||
distinguished_name = req_distinguished_name
|
||||
attributes = req_attributes
|
||||
x509_extensions = v3_ca # The extentions to add to the self signed cert
|
||||
|
||||
# Passwords for private keys if not present they will be prompted for
|
||||
# input_password = secret
|
||||
# output_password = secret
|
||||
|
||||
# This sets a mask for permitted string types. There are several options.
|
||||
# default: PrintableString, T61String, BMPString.
|
||||
# pkix : PrintableString, BMPString.
|
||||
# utf8only: only UTF8Strings.
|
||||
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
|
||||
# MASK:XXXX a literal mask value.
|
||||
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
|
||||
# so use this option with caution!
|
||||
string_mask = nombstr
|
||||
|
||||
# req_extensions = v3_req # The extensions to add to a certificate request
|
||||
|
||||
[ req_distinguished_name ]
|
||||
#countryName = Country Name (2 letter code)
|
||||
#countryName_default = US
|
||||
#countryName_min = 2
|
||||
#countryName_max = 2
|
||||
|
||||
#stateOrProvinceName = State or Province Name (full name)
|
||||
#stateOrProvinceName_default = Some-State
|
||||
|
||||
#localityName = Locality Name (eg, city)
|
||||
|
||||
#0.organizationName = Organization Name (eg, company)
|
||||
#0.organizationName_default = Internet Widgits Pty Ltd
|
||||
|
||||
# we can do this but it is not needed normally :-)
|
||||
#1.organizationName = Second Organization Name (eg, company)
|
||||
#1.organizationName_default = World Wide Web Pty Ltd
|
||||
|
||||
#organizationalUnitName = Organizational Unit Name (eg, section)
|
||||
#organizationalUnitName_default =
|
||||
|
||||
commonName = Common Name (eg, YOUR name)
|
||||
commonName_max = 64
|
||||
|
||||
#emailAddress = Email Address
|
||||
#emailAddress_max = 64
|
||||
|
||||
# SET-ex3 = SET extension number 3
|
||||
|
||||
[ req_attributes ]
|
||||
#challengePassword = A challenge password
|
||||
#challengePassword_min = 4
|
||||
#challengePassword_max = 20
|
||||
|
||||
#unstructuredName = An optional company name
|
||||
|
||||
[ usr_cert ]
|
||||
|
||||
# These extensions are added when 'ca' signs a request.
|
||||
|
||||
# This goes against PKIX guidelines but some CAs do it and some software
|
||||
# requires this to avoid interpreting an end user certificate as a CA.
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
|
||||
# This stuff is for subjectAltName and issuerAltname.
|
||||
# Import the email address.
|
||||
# subjectAltName=email:copy
|
||||
# An alternative to produce certificates that aren't
|
||||
# deprecated according to PKIX.
|
||||
# subjectAltName=email:move
|
||||
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
[ v3_req ]
|
||||
|
||||
# Extensions to add to a certificate request
|
||||
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
[ v3_ca ]
|
||||
|
||||
|
||||
# Extensions for a typical CA
|
||||
|
||||
|
||||
# PKIX recommendation.
|
||||
|
||||
subjectKeyIdentifier=hash
|
||||
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
# This is what PKIX recommends but some broken software chokes on critical
|
||||
# extensions.
|
||||
#basicConstraints = critical,CA:true
|
||||
# So we do this instead.
|
||||
basicConstraints = CA:true
|
||||
|
||||
# Key usage: this is typical for a CA certificate. However since it will
|
||||
# prevent it being used as an test self-signed certificate it is best
|
||||
# left out by default.
|
||||
# keyUsage = cRLSign, keyCertSign
|
||||
|
||||
# Some might want this also
|
||||
# nsCertType = sslCA, emailCA
|
||||
|
||||
# Include email address in subject alt name: another PKIX recommendation
|
||||
# subjectAltName=email:copy
|
||||
# Copy issuer details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
# DER hex encoding of an extension: beware experts only!
|
||||
# obj=DER:02:03
|
||||
# Where 'obj' is a standard or added object
|
||||
# You can even override a supported extension:
|
||||
# basicConstraints= critical, DER:30:03:01:01:FF
|
||||
|
||||
[ crl_ext ]
|
||||
|
||||
# CRL extensions.
|
||||
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
|
||||
|
||||
# issuerAltName=issuer:copy
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
|
||||
[ proxy_cert_ext ]
|
||||
# These extensions should be added when creating a proxy certificate
|
||||
|
||||
# This goes against PKIX guidelines but some CAs do it and some software
|
||||
# requires this to avoid interpreting an end user certificate as a CA.
|
||||
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# Here are some examples of the usage of nsCertType. If it is omitted
|
||||
# the certificate can be used for anything *except* object signing.
|
||||
|
||||
# This is OK for an SSL server.
|
||||
# nsCertType = server
|
||||
|
||||
# For an object signing certificate this would be used.
|
||||
# nsCertType = objsign
|
||||
|
||||
# For normal client use this is typical
|
||||
# nsCertType = client, email
|
||||
|
||||
# and for everything including object signing:
|
||||
# nsCertType = client, email, objsign
|
||||
|
||||
# This is typical in keyUsage for a client certificate.
|
||||
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
|
||||
# This will be displayed in Netscape's comment listbox.
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer:always
|
||||
|
||||
# This stuff is for subjectAltName and issuerAltname.
|
||||
# Import the email address.
|
||||
# subjectAltName=email:copy
|
||||
# An alternative to produce certificates that aren't
|
||||
# deprecated according to PKIX.
|
||||
# subjectAltName=email:move
|
||||
|
||||
# Copy subject details
|
||||
# issuerAltName=issuer:copy
|
||||
|
||||
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
|
||||
#nsBaseUrl
|
||||
#nsRevocationUrl
|
||||
#nsRenewalUrl
|
||||
#nsCaPolicyUrl
|
||||
#nsSslServerName
|
||||
|
||||
# This really needs to be in place for it to be a proxy certificate.
|
||||
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
|
45
xCAT-server-2.0/usr/share/xcat/cons/blade
Executable file
45
xCAT-server-2.0/usr/share/xcat/cons/blade
Executable file
@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use xCAT::Table;
|
||||
use File::Basename;
|
||||
my $scriptname = $0;
|
||||
|
||||
$mptab = xCAT::Table->new('mp');
|
||||
unless ($mptab) {
|
||||
sleep 5; #Try not to overwhelm logfiles...
|
||||
die "mp table must be configured";
|
||||
}
|
||||
$mpatab = xCAT::Table->new('mpa');
|
||||
$passtab = xCAT::Table->new('passwd');
|
||||
|
||||
my $username = "USERID";
|
||||
my $passsword = "PASSW0RD";
|
||||
my $mm;
|
||||
my $slot;
|
||||
my $dba;
|
||||
if ($passtab) {
|
||||
($dba) = $passtab->getAttribs({key=>blade},qw(username password));
|
||||
if ($dba->{username}) {
|
||||
$username = $dba->{username};
|
||||
}
|
||||
if ($dba->{password}) {
|
||||
$password = $dba->{password};
|
||||
}
|
||||
}
|
||||
|
||||
$dba = $mptab->getNodeAttribs($ARGV[0],[qw(mpa id)]);
|
||||
$mm = $dba->{mpa};
|
||||
$slot = $dba->{id};
|
||||
if ($mpatab) {
|
||||
($dba) = $mpatab->getAttribs({mpa=>$mm},qw(username password));
|
||||
if ($dba) {
|
||||
if ($dba->{username}) { $username = $dba->username; }
|
||||
if ($dba->{password}) { $password = $dba->password; }
|
||||
}
|
||||
}
|
||||
my $pathtochild= dirname($scriptname). "/";
|
||||
exec $pathtochild."blade.expect $mm $slot $username $password";
|
||||
|
||||
|
||||
|
||||
|
35
xCAT-server-2.0/usr/share/xcat/cons/blade.expect
Executable file
35
xCAT-server-2.0/usr/share/xcat/cons/blade.expect
Executable file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env expect
|
||||
|
||||
set timeout 45
|
||||
|
||||
set bcmm [lindex $argv 0]
|
||||
set bayno [lindex $argv 1]
|
||||
set username [lindex $argv 2]
|
||||
set password [lindex $argv 3]
|
||||
set cmdline "console -o -T blade\[$bayno\]"
|
||||
|
||||
spawn telnet $bcmm
|
||||
expect -re ".*username: "
|
||||
send "$username\r"
|
||||
expect -re ".*password: "
|
||||
send "$password\r"
|
||||
expect -re ".*system> "
|
||||
send "$cmdline\r"
|
||||
expect {
|
||||
eof {
|
||||
exit
|
||||
}
|
||||
-re ".*system> " {
|
||||
sleep 5
|
||||
send "$cmdline\r"
|
||||
}
|
||||
"?" {
|
||||
interact {
|
||||
-o
|
||||
"system> " {
|
||||
sleep 5
|
||||
send "$cmdline\r"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
xCAT-server-2.0/usr/share/xcat/cons/ipmi
Executable file
29
xCAT-server-2.0/usr/share/xcat/cons/ipmi
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use xCAT::Table;
|
||||
my $dba;
|
||||
my $ipmitab = xCAT::Table->new('ipmi');
|
||||
unless ($ipmitab) { sleep 5; die "Unable to open IPMI table"; }
|
||||
my $passtab = xCAT::Table->new('passwd');
|
||||
my $username = 'USERID';
|
||||
my $password = 'PASSW0RD';
|
||||
my $node = $ARGV[0];
|
||||
my $bmc = $node;
|
||||
if ($passtab) {
|
||||
($dba) = $passtab->getAttribs({key=>'ipmi'},qw(username password));
|
||||
if ($dba) {
|
||||
if ($dba->{username}) { $username = $dba->{username}; }
|
||||
if ($dba->{password}) { $password = $dba->{password}; }
|
||||
}
|
||||
}
|
||||
|
||||
$dba = $ipmitab->getNodeAttribs($ARGV[0],[qw(bmc username password)]);
|
||||
if ($dba) {
|
||||
if ($dba->{bmc}) { $bmc = $dba->{bmc}; }
|
||||
if ($dba->{username}) { $username = $dba->{username}; }
|
||||
if ($dba->{password}) { $password = $dba->{password}; }
|
||||
}
|
||||
system "ipmitool -I lanplus -U $username -P $password -H $bmc sol deactivate"; #Stop any active session
|
||||
exec "ipmitool -I lanplus -U $username -P $password -H $bmc sol activate";
|
||||
|
||||
|
184
xCAT-server-2.0/usr/share/xcat/install/centos/all.tmpl
Normal file
184
xCAT-server-2.0/usr/share/xcat/install/centos/all.tmpl
Normal file
@ -0,0 +1,184 @@
|
||||
#RedHat Enterprise Linux 4 AS Only
|
||||
#egan@us.ibm.com
|
||||
#
|
||||
|
||||
lang en_US
|
||||
langsupport en_US
|
||||
network --bootproto dhcp
|
||||
|
||||
#
|
||||
# Where's the source?
|
||||
# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image
|
||||
#
|
||||
nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR#
|
||||
|
||||
#device ethernet e100
|
||||
keyboard "#TABLE:site.tab:keyboard:1#"
|
||||
|
||||
#
|
||||
# Clear the MBR
|
||||
#
|
||||
zerombr yes
|
||||
|
||||
#
|
||||
# Wipe out the disk
|
||||
#
|
||||
clearpart --all --initlabel
|
||||
#clearpart --linux
|
||||
|
||||
#
|
||||
# Customize to fit your needs
|
||||
# /boot is strongly recommended
|
||||
#
|
||||
|
||||
#No RAID
|
||||
part /boot --size 50 --ondisk sda --fstype ext3
|
||||
part swap --size 1024 --ondisk sda
|
||||
part / --size 6000 --grow --ondisk sda --fstype ext3
|
||||
|
||||
#RAID 0 /scr for performance
|
||||
#part / --size 1024 --ondisk sda
|
||||
#part swap --size 512 --ondisk sda
|
||||
#part /var --size 1024 --ondisk sdb
|
||||
#part swap --size 512 --ondisk sdb
|
||||
#part raid.01 --size 1 --grow --ondisk sda
|
||||
#part raid.02 --size 1 --grow --ondisk sdb
|
||||
#raid /scr --level 0 --device md0 raid.01 raid.02
|
||||
|
||||
#Full RAID 1 Sample
|
||||
#part raid.01 --size 50 --ondisk sda
|
||||
#part raid.02 --size 50 --ondisk sdb
|
||||
#raid /boot --level 1 --device md0 raid.01 raid.02
|
||||
#
|
||||
#part raid.11 --size 1024 --ondisk sda
|
||||
#part raid.12 --size 1024 --ondisk sdb
|
||||
#raid / --level 1 --device md1 raid.11 raid.12
|
||||
#
|
||||
#part raid.21 --size 1024 --ondisk sda
|
||||
#part raid.22 --size 1024 --ondisk sdb
|
||||
#raid /var --level 1 --device md2 raid.21 raid.22
|
||||
#
|
||||
#part raid.31 --size 1024 --ondisk sda
|
||||
#part raid.32 --size 1024 --ondisk sdb
|
||||
#raid swap --level 1 --device md3 raid.31 raid.32
|
||||
#
|
||||
#part raid.41 --size 1 --grow --ondisk sda
|
||||
#part raid.42 --size 1 --grow --ondisk sdb
|
||||
#raid /scr --level 1 --device md4 raid.41 raid.42
|
||||
|
||||
#
|
||||
# bootloader config
|
||||
# --append <args>
|
||||
# --useLilo
|
||||
# --md5pass <crypted MD5 password for GRUB>
|
||||
#
|
||||
bootloader
|
||||
|
||||
#
|
||||
# install or upgrade
|
||||
#
|
||||
install
|
||||
|
||||
#
|
||||
# text mode install (default is graphical)
|
||||
#
|
||||
text
|
||||
|
||||
#
|
||||
# firewall
|
||||
#
|
||||
firewall --disabled
|
||||
|
||||
#
|
||||
# mouse selection
|
||||
#
|
||||
#mouse genericps/2 --emulthree
|
||||
mouse none
|
||||
|
||||
#
|
||||
# Select a zone
|
||||
# Add the --utc switch if your hardware clock is set to GMT
|
||||
#
|
||||
#timezone US/Hawaii
|
||||
#timezone US/Pacific
|
||||
#timezone US/Mountain
|
||||
#timezone US/Central
|
||||
#timezone US/Eastern
|
||||
timezone --utc #TABLE:site.tab:timezone:1#
|
||||
|
||||
#
|
||||
# Don't do X
|
||||
#
|
||||
skipx
|
||||
|
||||
#
|
||||
# Geez!
|
||||
#
|
||||
key --skip
|
||||
|
||||
#
|
||||
# To generate an encrypted root password use:
|
||||
#
|
||||
# perl -e 'print crypt("blah","Xa") . "\n";'p
|
||||
# openssl passwd -apr1 -salt xxxxxxxx password
|
||||
#
|
||||
# where "blah" is your root password.
|
||||
#
|
||||
#rootpw --iscrypted XaLGAVe1C41x2
|
||||
#rootpw XaLGAVe1C41x2 --iscrypted
|
||||
#rootpw #TABLE:passwd.tab:rootpw:1#
|
||||
rootpw --iscrypted #COMMAND:perl -e 'print crypt("#TABLE:passwd.tab:rootpw:1#","Xa") . "\n";'p#
|
||||
|
||||
#
|
||||
# NIS setup: auth --enablenis --nisdomain sensenet
|
||||
# --nisserver neptune --useshadow --enablemd5
|
||||
#
|
||||
# OR
|
||||
auth --useshadow --enablemd5
|
||||
|
||||
#
|
||||
# SE Linux
|
||||
#
|
||||
selinux --disabled
|
||||
|
||||
#
|
||||
# Reboot after installation
|
||||
#
|
||||
reboot
|
||||
|
||||
#
|
||||
#end of section
|
||||
#
|
||||
%packages --resolvedeps
|
||||
@Everything
|
||||
@ Everything
|
||||
@ System Tools
|
||||
@ X Window System
|
||||
@ Legacy Software Development
|
||||
#kernel-smp
|
||||
autofs
|
||||
ksh
|
||||
tcsh
|
||||
ntp
|
||||
tftp
|
||||
xinetd
|
||||
rsh
|
||||
rsh-server
|
||||
psacct
|
||||
nfs-utils
|
||||
net-snmp
|
||||
rsync
|
||||
yp-tools
|
||||
ypserv
|
||||
ypbind
|
||||
m4
|
||||
sendmail-cf
|
||||
gdb
|
||||
binutils
|
||||
openssh-server
|
||||
util-linux
|
||||
compat-libstdc++-33
|
||||
%pre
|
||||
#COMMAND:genscript pre #ENV:OSVER# #ENV:ARCH##
|
||||
%post
|
||||
#COMMAND:genscript post #ENV:OSVER# #ENV:ARCH##
|
178
xCAT-server-2.0/usr/share/xcat/install/centos/compute.tmpl
Normal file
178
xCAT-server-2.0/usr/share/xcat/install/centos/compute.tmpl
Normal file
@ -0,0 +1,178 @@
|
||||
#RedHat Enterprise Linux 4 AS Only
|
||||
#egan@us.ibm.com
|
||||
#
|
||||
|
||||
lang en_US
|
||||
langsupport en_US
|
||||
network --bootproto dhcp
|
||||
|
||||
#
|
||||
# Where's the source?
|
||||
# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image
|
||||
#
|
||||
#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR#
|
||||
url --url http://#TABLE:noderes:$NODE:nfsserver#/install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch#
|
||||
|
||||
#device ethernet e100
|
||||
keyboard "us"
|
||||
|
||||
#
|
||||
# Clear the MBR
|
||||
#
|
||||
zerombr yes
|
||||
|
||||
#
|
||||
# Wipe out the disk
|
||||
#
|
||||
clearpart --all --initlabel
|
||||
#clearpart --linux
|
||||
|
||||
#
|
||||
# Customize to fit your needs
|
||||
#
|
||||
|
||||
#No RAID
|
||||
#/boot really significant for this sort of setup nowadays?
|
||||
#part /boot --size 50 --fstype ext3
|
||||
part swap --size 1024
|
||||
part / --size 1 --grow --fstype ext3
|
||||
|
||||
#RAID 0 /scr for performance
|
||||
#part / --size 1024 --ondisk sda
|
||||
#part swap --size 512 --ondisk sda
|
||||
#part /var --size 1024 --ondisk sdb
|
||||
#part swap --size 512 --ondisk sdb
|
||||
#part raid.01 --size 1 --grow --ondisk sda
|
||||
#part raid.02 --size 1 --grow --ondisk sdb
|
||||
#raid /scr --level 0 --device md0 raid.01 raid.02
|
||||
|
||||
#Full RAID 1 Sample
|
||||
#part raid.01 --size 50 --ondisk sda
|
||||
#part raid.02 --size 50 --ondisk sdb
|
||||
#raid /boot --level 1 --device md0 raid.01 raid.02
|
||||
#
|
||||
#part raid.11 --size 1024 --ondisk sda
|
||||
#part raid.12 --size 1024 --ondisk sdb
|
||||
#raid / --level 1 --device md1 raid.11 raid.12
|
||||
#
|
||||
#part raid.21 --size 1024 --ondisk sda
|
||||
#part raid.22 --size 1024 --ondisk sdb
|
||||
#raid /var --level 1 --device md2 raid.21 raid.22
|
||||
#
|
||||
#part raid.31 --size 1024 --ondisk sda
|
||||
#part raid.32 --size 1024 --ondisk sdb
|
||||
#raid swap --level 1 --device md3 raid.31 raid.32
|
||||
#
|
||||
#part raid.41 --size 1 --grow --ondisk sda
|
||||
#part raid.42 --size 1 --grow --ondisk sdb
|
||||
#raid /scr --level 1 --device md4 raid.41 raid.42
|
||||
|
||||
#
|
||||
# bootloader config
|
||||
# --append <args>
|
||||
# --useLilo
|
||||
# --md5pass <crypted MD5 password for GRUB>
|
||||
#
|
||||
bootloader
|
||||
|
||||
#
|
||||
# install or upgrade
|
||||
#
|
||||
install
|
||||
|
||||
#
|
||||
# text mode install (default is graphical)
|
||||
#
|
||||
text
|
||||
|
||||
#
|
||||
# firewall
|
||||
#
|
||||
firewall --disabled
|
||||
|
||||
#
|
||||
# mouse selection
|
||||
#
|
||||
#mouse genericps/2 --emulthree
|
||||
mouse none
|
||||
|
||||
#
|
||||
# Select a zone
|
||||
# Add the --utc switch if your hardware clock is set to GMT
|
||||
#
|
||||
#timezone US/Hawaii
|
||||
#timezone US/Pacific
|
||||
#timezone US/Mountain
|
||||
#timezone US/Central
|
||||
#timezone US/Eastern
|
||||
timezone --utc #TABLE:site:key=timezone:value#
|
||||
|
||||
#
|
||||
# Don't do X
|
||||
#
|
||||
skipx
|
||||
|
||||
|
||||
#
|
||||
# To generate an encrypted root password use:
|
||||
#
|
||||
# perl -e 'print crypt("blah","Xa") . "\n";'p
|
||||
# openssl passwd -apr1 -salt xxxxxxxx password
|
||||
#
|
||||
# where "blah" is your root password.
|
||||
#
|
||||
#rootpw --iscrypted XaLGAVe1C41x2
|
||||
#rootpw XaLGAVe1C41x2 --iscrypted
|
||||
rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password#
|
||||
#rootpw --iscrypted #COMMAND:perl -e 'print crypt("#TABLE:passwd.tab:rootpw:1#","Xa") . "\n";'p#
|
||||
|
||||
#
|
||||
# NIS setup: auth --enablenis --nisdomain sensenet
|
||||
# --nisserver neptune --useshadow --enablemd5
|
||||
#
|
||||
# OR
|
||||
auth --useshadow --enablemd5
|
||||
|
||||
#
|
||||
# SE Linux
|
||||
#
|
||||
selinux --disabled
|
||||
|
||||
#
|
||||
# Reboot after installation
|
||||
#
|
||||
reboot
|
||||
|
||||
#
|
||||
#end of section
|
||||
#
|
||||
%packages --resolvedeps
|
||||
@ Network Servers
|
||||
@ System Tools
|
||||
@ X Window System
|
||||
@ Legacy Software Development
|
||||
autofs
|
||||
tcsh
|
||||
ntp
|
||||
tftp
|
||||
xinetd
|
||||
rsh
|
||||
rsh-server
|
||||
psacct
|
||||
nfs-utils
|
||||
net-snmp
|
||||
rsync
|
||||
yp-tools
|
||||
ypserv
|
||||
ypbind
|
||||
m4
|
||||
sendmail-cf
|
||||
gdb
|
||||
binutils
|
||||
openssh-server
|
||||
util-linux
|
||||
compat-libstdc++-33
|
||||
%pre
|
||||
#INCLUDE:../scripts/pre.rh#
|
||||
%post
|
||||
#INCLUDE:../scripts/post.rh#
|
180
xCAT-server-2.0/usr/share/xcat/install/rh/compute.tmpl
Normal file
180
xCAT-server-2.0/usr/share/xcat/install/rh/compute.tmpl
Normal file
@ -0,0 +1,180 @@
|
||||
#RedHat Enterprise Linux 4 AS Only
|
||||
#egan@us.ibm.com
|
||||
#
|
||||
|
||||
lang en_US
|
||||
langsupport en_US
|
||||
network --bootproto dhcp
|
||||
|
||||
#
|
||||
# Where's the source?
|
||||
# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image
|
||||
#
|
||||
#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR#
|
||||
url --url http://#TABLE:noderes:$NODE:nfsserver#/install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch#
|
||||
|
||||
#device ethernet e100
|
||||
keyboard "us"
|
||||
|
||||
#
|
||||
# Clear the MBR
|
||||
#
|
||||
zerombr yes
|
||||
|
||||
#
|
||||
# Wipe out the disk
|
||||
#
|
||||
clearpart --all --initlabel
|
||||
#clearpart --linux
|
||||
key --skip
|
||||
|
||||
#
|
||||
# Customize to fit your needs
|
||||
#
|
||||
|
||||
#No RAID
|
||||
#/boot really significant for this sort of setup nowadays?
|
||||
#part /boot --size 50 --fstype ext3
|
||||
part swap --size 1024
|
||||
part / --size 1 --grow --fstype ext3
|
||||
|
||||
#RAID 0 /scr for performance
|
||||
#part / --size 1024 --ondisk sda
|
||||
#part swap --size 512 --ondisk sda
|
||||
#part /var --size 1024 --ondisk sdb
|
||||
#part swap --size 512 --ondisk sdb
|
||||
#part raid.01 --size 1 --grow --ondisk sda
|
||||
#part raid.02 --size 1 --grow --ondisk sdb
|
||||
#raid /scr --level 0 --device md0 raid.01 raid.02
|
||||
|
||||
#Full RAID 1 Sample
|
||||
#part raid.01 --size 50 --ondisk sda
|
||||
#part raid.02 --size 50 --ondisk sdb
|
||||
#raid /boot --level 1 --device md0 raid.01 raid.02
|
||||
#
|
||||
#part raid.11 --size 1024 --ondisk sda
|
||||
#part raid.12 --size 1024 --ondisk sdb
|
||||
#raid / --level 1 --device md1 raid.11 raid.12
|
||||
#
|
||||
#part raid.21 --size 1024 --ondisk sda
|
||||
#part raid.22 --size 1024 --ondisk sdb
|
||||
#raid /var --level 1 --device md2 raid.21 raid.22
|
||||
#
|
||||
#part raid.31 --size 1024 --ondisk sda
|
||||
#part raid.32 --size 1024 --ondisk sdb
|
||||
#raid swap --level 1 --device md3 raid.31 raid.32
|
||||
#
|
||||
#part raid.41 --size 1 --grow --ondisk sda
|
||||
#part raid.42 --size 1 --grow --ondisk sdb
|
||||
#raid /scr --level 1 --device md4 raid.41 raid.42
|
||||
|
||||
#
|
||||
# bootloader config
|
||||
# --append <args>
|
||||
# --useLilo
|
||||
# --md5pass <crypted MD5 password for GRUB>
|
||||
#
|
||||
bootloader
|
||||
|
||||
#
|
||||
# install or upgrade
|
||||
#
|
||||
install
|
||||
|
||||
#
|
||||
# text mode install (default is graphical)
|
||||
#
|
||||
text
|
||||
|
||||
#
|
||||
# firewall
|
||||
#
|
||||
firewall --disabled
|
||||
|
||||
#
|
||||
# mouse selection
|
||||
#
|
||||
#mouse genericps/2 --emulthree
|
||||
mouse none
|
||||
|
||||
#
|
||||
# Select a zone
|
||||
# Add the --utc switch if your hardware clock is set to GMT
|
||||
#
|
||||
#timezone US/Hawaii
|
||||
#timezone US/Pacific
|
||||
#timezone US/Mountain
|
||||
#timezone US/Central
|
||||
#timezone US/Eastern
|
||||
timezone --utc #TABLE:site:key=timezone:value#
|
||||
|
||||
#
|
||||
# Don't do X
|
||||
#
|
||||
skipx
|
||||
|
||||
|
||||
#
|
||||
# To generate an encrypted root password use:
|
||||
#
|
||||
# perl -e 'print crypt("blah","Xa") . "\n";'p
|
||||
# openssl passwd -apr1 -salt xxxxxxxx password
|
||||
#
|
||||
# where "blah" is your root password.
|
||||
#
|
||||
#rootpw --iscrypted XaLGAVe1C41x2
|
||||
#rootpw XaLGAVe1C41x2 --iscrypted
|
||||
rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password#
|
||||
#rootpw --iscrypted #COMMAND:perl -e 'print crypt("#TABLE:passwd.tab:rootpw:1#","Xa") . "\n";'p#
|
||||
|
||||
#
|
||||
# NIS setup: auth --enablenis --nisdomain sensenet
|
||||
# --nisserver neptune --useshadow --enablemd5
|
||||
#
|
||||
# OR
|
||||
auth --useshadow --enablemd5
|
||||
|
||||
#
|
||||
# SE Linux
|
||||
#
|
||||
selinux --disabled
|
||||
|
||||
#
|
||||
# Reboot after installation
|
||||
#
|
||||
reboot
|
||||
|
||||
#
|
||||
#end of section
|
||||
#
|
||||
%packages --resolvedeps
|
||||
@ Network Servers
|
||||
@ System Tools
|
||||
@ X Window System
|
||||
@ Legacy Software Development
|
||||
autofs
|
||||
ksh
|
||||
tcsh
|
||||
ntp
|
||||
tftp
|
||||
xinetd
|
||||
rsh
|
||||
rsh-server
|
||||
psacct
|
||||
nfs-utils
|
||||
net-snmp
|
||||
rsync
|
||||
yp-tools
|
||||
ypserv
|
||||
ypbind
|
||||
m4
|
||||
sendmail-cf
|
||||
gdb
|
||||
binutils
|
||||
openssh-server
|
||||
util-linux
|
||||
compat-libstdc++-33
|
||||
%pre
|
||||
#INCLUDE:../scripts/pre.rh#
|
||||
%post
|
||||
#INCLUDE:../scripts/post.rh#
|
44
xCAT-server-2.0/usr/share/xcat/install/scripts/chroot.sles
Normal file
44
xCAT-server-2.0/usr/share/xcat/install/scripts/chroot.sles
Normal file
@ -0,0 +1,44 @@
|
||||
<chroot-scripts config:type="list">
|
||||
<script>
|
||||
<filename>boot.sh</filename>
|
||||
<interpreter>shell</interpreter>
|
||||
<source>
|
||||
|
||||
<![CDATA[
|
||||
#!/bin/sh
|
||||
|
||||
AWK=`find / -name awk | head -1`
|
||||
#old awk /mounts/instsys/bin/awk -f
|
||||
|
||||
cat >/tmp/updateflag.awk <<EOF
|
||||
#!$AWK -f
|
||||
|
||||
BEGIN {
|
||||
xcatdport = #TABLE:site:key=xcatiport:value#
|
||||
xcatdhost = "#XCATVAR:XCATMASTER#"
|
||||
|
||||
ns = "/inet/tcp/0/" xcatdhost "/" xcatdport
|
||||
|
||||
while(1) {
|
||||
if((ns |& getline) > 0)
|
||||
print \$0
|
||||
|
||||
if(\$0 == "ready")
|
||||
print "next" |& ns
|
||||
if(\$0 == "done")
|
||||
break
|
||||
}
|
||||
|
||||
close(ns)
|
||||
|
||||
exit 0
|
||||
}
|
||||
EOF
|
||||
|
||||
chmod 755 /tmp/updateflag.awk
|
||||
/tmp/updateflag.awk
|
||||
]]>
|
||||
|
||||
</source>
|
||||
</script>
|
||||
</chroot-scripts>
|
58
xCAT-server-2.0/usr/share/xcat/install/scripts/post.rh
Normal file
58
xCAT-server-2.0/usr/share/xcat/install/scripts/post.rh
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Setup hostname
|
||||
#
|
||||
echo "post scripts" >/root/post.log
|
||||
export PRINIC=#TABLE:noderes:THISNODE:primarynic#
|
||||
if [ -z "$PRINIC" ]
|
||||
then
|
||||
export PRINIC=eth0
|
||||
fi
|
||||
IP=$(ifconfig $PRINIC | grep inet | awk '{print $2}' | awk -F: '{print $2}')
|
||||
if [ -z $IP ]
|
||||
then
|
||||
dhclient eth0
|
||||
IP=$(ifconfig $PRINIC | grep inet | awk '{print $2}' | awk -F: '{print $2}')
|
||||
fi
|
||||
echo "search #TABLE:site:key=domain:value#" >/etc/resolv.conf
|
||||
for i in $(echo #TABLE:site:key=nameservers:value# | tr ',' ' ')
|
||||
do
|
||||
echo "nameserver $i"
|
||||
done >>/etc/resolv.conf
|
||||
export HOSTNAME=$(host $IP 2>/dev/null | awk '{print $5}' | awk -F. '{print $1}')
|
||||
hostname $HOSTNAME
|
||||
#
|
||||
# Run xCAT post install
|
||||
#
|
||||
export MASTER_IP="#XCATVAR:XCATMASTER#"
|
||||
export MASTER_IPS="#XCATVAR:XCATMASTER#"
|
||||
mkdir -p /xcatpost
|
||||
RAND=$(perl -e 'print int(rand(50)). "\n"')
|
||||
sleep $RAND
|
||||
for i in $(seq 1 20)
|
||||
do
|
||||
GOTIT=0
|
||||
for i in $MASTER_IPS
|
||||
do
|
||||
# mount -r $i:$XCATROOT $XCATROOT
|
||||
mount -o ro,nolock $i:/install/postscripts /xcatpost
|
||||
if [ "$?" = "0" ]
|
||||
then
|
||||
GOTIT=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$GOTIT" = "1" ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
RAND=$(perl -e 'print int(rand(5)). "\n"')
|
||||
sleep $RAND
|
||||
done
|
||||
#mount -r #XCATVAR:MASTER_IP#:$XCATROOT $XCATROOT
|
||||
#mount -o ro,nolock #XCATVAR:MASTER_IP#:$XCATROOT $XCATROOT
|
||||
#$XCATROOT/bin/postage
|
||||
/xcatpost/#TABLE:nodelist:THISNODE:node#
|
||||
cd /
|
||||
umount /xcatpost
|
||||
rmdir /xcatpost
|
||||
exit 0
|
84
xCAT-server-2.0/usr/share/xcat/install/scripts/post.sles
Normal file
84
xCAT-server-2.0/usr/share/xcat/install/scripts/post.sles
Normal file
@ -0,0 +1,84 @@
|
||||
<post-scripts config:type="list">
|
||||
<script>
|
||||
<filename>xcat.sh</filename>
|
||||
<interpreter>shell</interpreter>
|
||||
<source>
|
||||
|
||||
<![CDATA[
|
||||
#!/bin/sh
|
||||
|
||||
cd /etc/sysconfig/network
|
||||
rm -f ifcfg-eth-id*
|
||||
rm -f ifcfg-myri*
|
||||
cat >ifcfg-eth0 <<EOF
|
||||
DEVICE=eth0
|
||||
BOOTPROTO=dhcp
|
||||
STARTMODE=onboot
|
||||
EOF
|
||||
|
||||
export PRINIC=#TABLE:noderes:$NODE:primarynic#
|
||||
if [ -z "$PRINIC" ]; then
|
||||
export PRINIC=eth0
|
||||
fi
|
||||
if [ "$PRINIC" != "eth0" ]
|
||||
then
|
||||
cd /etc/sysconfig/network
|
||||
if [ ! -r ifcfg-$PRINIC ]
|
||||
then
|
||||
cp -f ifcfg-eth0 ifcfg-$PRINIC
|
||||
perl -pi -e "s/eth0/$PRINIC/" ifcfg-$PRINIC
|
||||
echo "DHCLIENT_PRIMARY_DEVICE=yes" >> ifcfg-$PRINIC
|
||||
fi
|
||||
fi
|
||||
perl -pi -e 's/^FIREWALL="yes"/FIREWALL="no"/' /etc/sysconfig/network/config
|
||||
/etc/init.d/network restart
|
||||
|
||||
RAND=$(perl -e 'print int(rand(50)). "\n"')
|
||||
sleep $RAND
|
||||
jsi=0
|
||||
while [ $(hostname) == 'linux' ]
|
||||
do
|
||||
if [ $jsi -gt 10 ]; then
|
||||
logger "Slept too long!"
|
||||
exit
|
||||
fi
|
||||
let jsi=jsi+1
|
||||
sleep 1
|
||||
done
|
||||
echo "Slept $jsi seconds before hostname made sense."
|
||||
|
||||
HOSTNAME=$(hostname -s)
|
||||
echo $HOSTNAME
|
||||
|
||||
/sbin/portmap
|
||||
export MASTER_IP=#XCATVAR:XCATMASTER#
|
||||
export MASTER_IPS=#XCATVAR:XCATMASTER#
|
||||
mkdir -p /xcatpost
|
||||
for i in $(seq 1 20)
|
||||
do
|
||||
GOTIT=0
|
||||
for i in $MASTER_IPS
|
||||
do
|
||||
mount -r $i:/install/postscripts /xcatpost
|
||||
if [ "$?" = "0" ]
|
||||
then
|
||||
GOTIT=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$GOTIT" = "1" ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
RAND=$(perl -e 'print int(rand(5)). "\n"')
|
||||
sleep $RAND
|
||||
done
|
||||
cd /
|
||||
/xcatpost/#TABLE:nodelist:$NODE:node#
|
||||
umount /xcatpost
|
||||
rmdir /xcatpost
|
||||
]]>
|
||||
|
||||
</source>
|
||||
</script>
|
||||
</post-scripts>
|
123
xCAT-server-2.0/usr/share/xcat/install/scripts/pre.rh
Normal file
123
xCAT-server-2.0/usr/share/xcat/install/scripts/pre.rh
Normal file
@ -0,0 +1,123 @@
|
||||
if grep n8r /proc/cmdline >& /dev/null;
|
||||
then
|
||||
stty crtscts
|
||||
fi
|
||||
for x in 0 1 2 3 4 5 6 7 8
|
||||
do
|
||||
mknod /dev/vcs$x c 7 $x
|
||||
mknod /dev/vcsa$x c 7 $[$x+128]
|
||||
done
|
||||
chmod 644 /dev/vcs*
|
||||
chown root /dev/vcs*
|
||||
|
||||
cat >/tmp/foo.py <<EOF
|
||||
#!/usr/bin/python
|
||||
|
||||
import socket
|
||||
import os
|
||||
import linecache
|
||||
import re
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect(('#XCATVAR:XCATMASTER#',#TABLE:site:key=xcatiport:value#))
|
||||
|
||||
response = sock.recv(100)
|
||||
if(response == "ready\n"):
|
||||
sock.send("installmonitor\n")
|
||||
response = sock.recv(100)
|
||||
|
||||
sock.close()
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
port = 3001
|
||||
sock.bind(('', port))
|
||||
|
||||
sock.listen(5)
|
||||
|
||||
try:
|
||||
while 1:
|
||||
newSocket, address = sock.accept()
|
||||
while 1:
|
||||
received = newSocket.recv(200)
|
||||
if not received:
|
||||
break
|
||||
command = re.split('\s+',received)
|
||||
if(command[0] == "stat"):
|
||||
ilog = ""
|
||||
firstline = ""
|
||||
line = ""
|
||||
post = 0
|
||||
percent = 0
|
||||
count = 0
|
||||
numpack = 0
|
||||
if(os.path.isfile('/mnt/sysimage/root/install.log')):
|
||||
ilog = '/mnt/sysimage/root/install.log'
|
||||
if(os.path.isfile('/mnt/sysimage/tmp/install.log')):
|
||||
ilog = '/mnt/sysimage/tmp/install.log'
|
||||
if(os.path.isfile('/mnt/sysimage/root/post.log')):
|
||||
ilog = '/mnt/sysimage/root/post.log'
|
||||
post = 1
|
||||
if(ilog):
|
||||
count = len(open(ilog).readlines())
|
||||
firstline = linecache.getline(ilog,1)
|
||||
line = linecache.getline(ilog,count)
|
||||
linecache.clearcache()
|
||||
if(line and not post):
|
||||
r1 = re.compile("^Installing (\d+) ")
|
||||
m1 = r1.search(firstline)
|
||||
if m1:
|
||||
numpack = int(m1.group(1))
|
||||
if(numpack > 0):
|
||||
percent = int(((count - 2) * 100)/numpack + .5)
|
||||
if(percent > 100):
|
||||
percent = 100
|
||||
if(percent < 0):
|
||||
percent = 0
|
||||
r2 = re.compile("^Installing (.*)\.")
|
||||
m2 = r2.search(line)
|
||||
if m2:
|
||||
newline = m2.group(1)
|
||||
newline = newline + " ("
|
||||
newline = newline + str(percent)
|
||||
newline = newline + "%)"
|
||||
# newline = newline + " ["
|
||||
# count = count - 2
|
||||
# newline = newline + str(count)
|
||||
# newline = newline + "/"
|
||||
# newline = newline + str(numpack)
|
||||
# newline = newline + "]"
|
||||
else:
|
||||
newline = "prep"
|
||||
line = "installing " + newline
|
||||
if(line and post):
|
||||
line = "installing " + line
|
||||
if(not line):
|
||||
line = "installing prep"
|
||||
newSocket.send(line)
|
||||
break
|
||||
# if(command[0] == "sh"): #DEBUG purposes only, wide open root priv command here.
|
||||
# newcommand = ""
|
||||
# for i in command[1:]:
|
||||
# newcommand = newcommand + i + " "
|
||||
# output = os.popen(newcommand).read()
|
||||
# newSocket.send(output)
|
||||
# break
|
||||
if(command[0] == "screendump"):
|
||||
newcommand = "cat /dev/vcs"
|
||||
for i in command[1:]:
|
||||
newcommand = newcommand + i
|
||||
output = os.popen(newcommand).read()
|
||||
newSocket.send(output)
|
||||
break
|
||||
|
||||
newSocket.close()
|
||||
|
||||
finally:
|
||||
sock.close()
|
||||
EOF
|
||||
|
||||
chmod 755 /tmp/foo.py
|
||||
|
||||
/tmp/foo.py >/foo.log 2>&1 &
|
98
xCAT-server-2.0/usr/share/xcat/install/scripts/pre.sles
Normal file
98
xCAT-server-2.0/usr/share/xcat/install/scripts/pre.sles
Normal file
@ -0,0 +1,98 @@
|
||||
<pre-scripts config:type="list">
|
||||
<script>
|
||||
<filename>foo.sh</filename>
|
||||
<interpreter>shell</interpreter>
|
||||
<source>
|
||||
|
||||
<![CDATA[
|
||||
#!/bin/sh
|
||||
|
||||
AWK=`find / -name awk | tail -1`
|
||||
#old awk /mounts/instsys/bin/awk -f
|
||||
|
||||
cat >/tmp/bar.awk <<EOF
|
||||
#!$AWK -f
|
||||
|
||||
BEGIN {
|
||||
xcatdport = "#TABLE:site:key=xcatiport:value#"
|
||||
xcatdhost = "#XCATVAR:XCATMASTER#"
|
||||
|
||||
ns = "/inet/tcp/0/" xcatdhost "/" xcatiport
|
||||
|
||||
print "xCAT_xcatd" |& ns
|
||||
|
||||
while(1) {
|
||||
ns |& getline
|
||||
|
||||
if(\$0 == "ready")
|
||||
print "installmonitor" |& ns
|
||||
if(\$0 == "done")
|
||||
break
|
||||
}
|
||||
|
||||
close(ns)
|
||||
|
||||
exit 0
|
||||
}
|
||||
EOF
|
||||
|
||||
if [ ! -c /dev/vcs ]; then
|
||||
mknod /dev/vcs c 7 0
|
||||
fi
|
||||
cat >/tmp/foo.awk <<EOF
|
||||
#!$AWK -f
|
||||
|
||||
BEGIN {
|
||||
ns = "/inet/tcp/3001/0/0"
|
||||
|
||||
while(1) {
|
||||
ns |& getline
|
||||
|
||||
# if(\$1 == "sh") { #TODO: ENABLE IF DEBUG
|
||||
# sub(/^sh +/,"",\$0)
|
||||
# output = \$0
|
||||
# while((output | getline) > 0)
|
||||
# print \$0 |& ns
|
||||
# print "EOO" |& ns
|
||||
# close(output)
|
||||
# }
|
||||
|
||||
if(\$1 == "screendump") {
|
||||
output = "chvt " \$2 ";cat /dev/vcs"
|
||||
while((output | getline) > 0)
|
||||
print \$0 |& ns
|
||||
close(output)
|
||||
}
|
||||
|
||||
if(\$1 == "stat") {
|
||||
while((getline < "/mnt/var/log/YaST2/y2logRPM") > 0) {
|
||||
line = \$0
|
||||
}
|
||||
close("/mnt/var/log/YaST2/y2logRPM")
|
||||
|
||||
if(line ~ /\.rpm /) {
|
||||
sub(/\.[^\.]+\.rpm .*$/,"",line)
|
||||
sub(/^.* /,"",line)
|
||||
}
|
||||
else {
|
||||
line = "prep"
|
||||
}
|
||||
|
||||
print ("installing " line) |& ns
|
||||
}
|
||||
|
||||
close(ns)
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
chmod 755 /tmp/foo.awk
|
||||
chmod 755 /tmp/bar.awk
|
||||
|
||||
/tmp/bar.awk &
|
||||
/tmp/foo.awk >/tmp/foo.log 2>&1 &
|
||||
]]>
|
||||
|
||||
</source>
|
||||
</script>
|
||||
</pre-scripts>
|
116
xCAT-server-2.0/usr/share/xcat/install/sles/compute.tmpl
Normal file
116
xCAT-server-2.0/usr/share/xcat/install/sles/compute.tmpl
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE profile SYSTEM "/usr/share/YaST2/include/autoinstall/profile.dtd">
|
||||
<profile xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.suse.com/1.0/configns">
|
||||
<install>
|
||||
<bootloader>
|
||||
<write_bootloader config:type="boolean">true</write_bootloader>
|
||||
<activate config:type="boolean">true</activate>
|
||||
<kernel_parameters></kernel_parameters>
|
||||
<lba_support config:type="boolean">false</lba_support>
|
||||
<linear config:type="boolean">false</linear>
|
||||
<location>mbr</location>
|
||||
</bootloader>
|
||||
<general>
|
||||
<clock>
|
||||
<hwclock>GMT</hwclock>
|
||||
<timezone>#TABLE:site:key=timezone:value#</timezone>
|
||||
</clock>
|
||||
<keyboard>
|
||||
<keymap>english-us</keymap>
|
||||
</keyboard>
|
||||
<language>en_US</language>
|
||||
<mode>
|
||||
<confirm config:type="boolean">false</confirm>
|
||||
<forceboot config:type="boolean">false</forceboot>
|
||||
<interactive_boot config:type="boolean">false</interactive_boot>
|
||||
<reboot config:type="boolean">true</reboot>
|
||||
</mode>
|
||||
<mouse>
|
||||
<id>non</id>
|
||||
</mouse>
|
||||
</general>
|
||||
<partitioning config:type="list">
|
||||
<drive>
|
||||
<device>/dev/sda</device>
|
||||
<initialize config:type="boolean">true</initialize>
|
||||
<use>all</use>
|
||||
<partitions config:type="list">
|
||||
<partition>
|
||||
<filesystem config:type="symbol">ext2</filesystem>
|
||||
<mount>/boot</mount>
|
||||
<partition_id config:type="integer">131</partition_id>
|
||||
<partition_nr config:type="integer">1</partition_nr>
|
||||
<size>50MB</size>
|
||||
</partition>
|
||||
<partition>
|
||||
<mount>swap</mount>
|
||||
<partition_nr config:type="integer">2</partition_nr>
|
||||
<size>auto</size>
|
||||
</partition>
|
||||
<partition>
|
||||
<filesystem config:type="symbol">ext3</filesystem>
|
||||
<mount>/var</mount>
|
||||
<partition_id config:type="integer">131</partition_id>
|
||||
<partition_nr config:type="integer">3</partition_nr>
|
||||
<size>2GB</size>
|
||||
</partition>
|
||||
<partition>
|
||||
<filesystem config:type="symbol">ext3</filesystem>
|
||||
<mount>/</mount>
|
||||
<partition_id config:type="integer">131</partition_id>
|
||||
<partition_nr config:type="integer">4</partition_nr>
|
||||
<size>max</size>
|
||||
</partition>
|
||||
</partitions>
|
||||
</drive>
|
||||
</partitioning>
|
||||
<software>
|
||||
<patterns config:type="list">
|
||||
<pattern>base</pattern>
|
||||
<pattern>base-32bit</pattern>
|
||||
<pattern>32bit</pattern>
|
||||
<pattern>x11-32bit</pattern>
|
||||
<pattern>x11</pattern>
|
||||
</patterns>
|
||||
<packages config:type="list">
|
||||
<package>xntp</package>
|
||||
<package>rsync</package>
|
||||
</packages>
|
||||
</software>
|
||||
</install>
|
||||
<configure>
|
||||
<users config:type="list">
|
||||
<user>
|
||||
<username>root</username>
|
||||
<user_password>#CRYPT:passwd:key=system,username=root:password#</user_password>
|
||||
<encrypted config:type="boolean">true</encrypted>
|
||||
<forename/>
|
||||
<surname/>
|
||||
</user>
|
||||
</users>
|
||||
<networking>
|
||||
<dns>
|
||||
<dhcp_hostname config:type="boolean">true</dhcp_hostname>
|
||||
<dhcp_resolv config:type="boolean">true</dhcp_resolv>
|
||||
<domain>local</domain>
|
||||
<hostname>linux</hostname>
|
||||
</dns>
|
||||
<interfaces config:type="list">
|
||||
<interface>
|
||||
<bootproto>dhcp</bootproto>
|
||||
<device>eth0</device>
|
||||
<startmode>onboot</startmode>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<routing>
|
||||
<ip_forward config:type="boolean">false</ip_forward>
|
||||
<routes config:type="list"/>
|
||||
</routing>
|
||||
</networking>
|
||||
<scripts>
|
||||
#INCLUDE:../scripts/pre.sles#
|
||||
#INCLUDE:../scripts/chroot.sles#
|
||||
#INCLUDE:../scripts/post.sles#
|
||||
</scripts>
|
||||
</configure>
|
||||
</profile>
|
19
xCAT-server-2.0/usr/share/xcat/postscripts/enablesysreq
Executable file
19
xCAT-server-2.0/usr/share/xcat/postscripts/enablesysreq
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/ksh
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#egan@us.ibm.com
|
||||
#(C)IBM Corp
|
||||
|
||||
case "$OSVER" in
|
||||
sles*|suse*|ul*)
|
||||
perl -pi -e 's/^ENABLE_SYSRQ.*/ENABLE_SYSRQ="yes"/' /etc/sysconfig/sysctl
|
||||
;;
|
||||
rh*)
|
||||
if egrep "^kernel\.sysrq" /etc/sysctl.conf >/dev/null 2>&1
|
||||
then
|
||||
perl -pi -e 's/^kernel\.sysrq.*/kernel.sysrq = 1/' /etc/sysctl.conf
|
||||
else
|
||||
echo "kernel.sysrq = 1" >>/etc/sysctl.conf
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user