ubuntu-server-iso-testing-dev team mailing list archive
-
ubuntu-server-iso-testing-dev team
-
Mailing list archive
-
Message #00000
lp:~ubuntu-server-iso-testing-dev/ubuntu-server-iso-testing/1.0-RC1 into lp:ubuntu-server-iso-testing
James Page has proposed merging lp:~ubuntu-server-iso-testing-dev/ubuntu-server-iso-testing/1.0-RC1 into lp:ubuntu-server-iso-testing.
Requested reviews:
Ubuntu Server Iso Testing Developers (ubuntu-server-iso-testing-dev)
For more details, see:
https://code.launchpad.net/~ubuntu-server-iso-testing-dev/ubuntu-server-iso-testing/1.0-RC1/+merge/46038
--
https://code.launchpad.net/~ubuntu-server-iso-testing-dev/ubuntu-server-iso-testing/1.0-RC1/+merge/46038
Your team Ubuntu Server Iso Testing Developers is requested to review the proposed merge of lp:~ubuntu-server-iso-testing-dev/ubuntu-server-iso-testing/1.0-RC1 into lp:ubuntu-server-iso-testing.
=== added file 'LICENSE.txt'
--- LICENSE.txt 1970-01-01 00:00:00 +0000
+++ LICENSE.txt 2011-01-12 20:50:44 +0000
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
=== removed directory 'couchapp'
=== removed file 'couchapp/.couchapprc'
--- couchapp/.couchapprc 2010-08-30 21:50:15 +0000
+++ couchapp/.couchapprc 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-{}
\ No newline at end of file
=== removed file 'couchapp/README.md'
--- couchapp/README.md 2010-08-30 21:50:15 +0000
+++ couchapp/README.md 1970-01-01 00:00:00 +0000
@@ -1,40 +0,0 @@
-## Generated by CouchApp
-
-CouchApps are web applications which can be served directly from [CouchDB](http://couchdb.apache.org). This gives them the nice property of replicating just like any other data stored in CouchDB. They are also simple to write as they can use the built-in jQuery libraries and plugins that ship with CouchDB.
-
-[More info about CouchApps here.](http://couchapp.org)
-
-## Deploying this app
-
-Assuming you just cloned this app from git, and you have changed into the app directory in your terminal, you want to push it to your CouchDB with the CouchApp command line tool, like this:
-
- couchapp push . http://name:password@hostname:5984/mydatabase
-
-If you don't have a password on your CouchDB (admin party) you can do it like this (but it's a bad, idea, set a password):
-
- couchapp push . http://hostname:5984/mydatabase
-
-If you get sick of typing the URL, you should setup a `.couchapprc` file in the root of your directory. Remember not to check this into version control as it will have passwords in it.
-
-The `.couchapprc` file should have contents like this:
-
- {
- "env" : {
- "public" : {
- "db" : "http://name:pass@xxxxxxxxxxxxxxxxxxxx/mydatabase"
- },
- "default" : {
- "db" : "http://name:pass@localhost:5984/mydatabase"
- }
- }
- }
-
-Now that you have the `.couchapprc` file set up, you can push your app to the CouchDB as simply as:
-
- couchapp push
-
-This pushes to the `default` as specified. To push to the `public` you'd run:
-
- couchapp push public
-
-Of course you can continue to add more deployment targets as you see fit, and give them whatever names you like.
=== removed directory 'couchapp/_attachments'
=== removed file 'couchapp/_attachments/index.html'
--- couchapp/_attachments/index.html 2010-09-02 21:44:21 +0000
+++ couchapp/_attachments/index.html 1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Test Tracker</title>
- <link rel="stylesheet" href="style/main.css" type="text/css">
- </head>
- <body>
- <h1>Test Tracker</h1>
-
- <div id="test-results"></div>
-
- </body>
- <script src="vendor/couchapp/loader.js"></script>
- <script type="text/javascript" charset="utf-8">
- $.couch.app(function(app) {
- $("#test-results").evently("test-results", app);
- });
- </script>
-</html>
=== removed directory 'couchapp/_attachments/style'
=== removed file 'couchapp/_attachments/style/main.css'
--- couchapp/_attachments/style/main.css 2010-08-30 21:50:15 +0000
+++ couchapp/_attachments/style/main.css 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
-/* add styles here */
-
-body {
- font:1em Helvetica, sans-serif;
- padding:4px;
-}
-
-h1 {
- margin-top:0;
-}
-
-#account {
- float:right;
-}
-
-#profile {
- border:4px solid #edd;
- background:#fee;
- padding:8px;
- margin-bottom:8px;
-}
-
-#items {
- border:4px solid #dde;
- background:#eef;
- padding:8px;
- width:60%;
- float:left;
-}
-
-#sidebar {
- border:4px solid #dfd;
- padding:8px;
- float:right;
- width:30%;
-}
-
-#items li {
- border:4px solid #f5f5ff;
- background:#fff;
- padding:8px;
- margin:4px 0;
-}
-
-form {
- padding:4px;
- margin:6px;
- background-color:#ddd;
-}
-
-div.avatar {
- padding:2px;
- padding-bottom:0;
- margin-right:4px;
- float:left;
- font-size:0.78em;
- width : 60px;
- height : 60px;
- text-align: center;
-}
-
-div.avatar .name {
- padding-top:2px;
-}
-
-div.avatar img {
- margin:0 auto;
- padding:0;
- width : 40px;
- height : 40px;
-}
-
-#items ul {
- list-style: none;
-}
=== removed file 'couchapp/_id'
--- couchapp/_id 2010-08-30 21:50:15 +0000
+++ couchapp/_id 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-_design/couchapp
\ No newline at end of file
=== removed file 'couchapp/couchapp.json'
--- couchapp/couchapp.json 2010-08-30 21:50:15 +0000
+++ couchapp/couchapp.json 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-{
- "name": "Name of your CouchApp",
- "description": "CouchApp"
-}
\ No newline at end of file
=== removed directory 'couchapp/evently'
=== removed directory 'couchapp/evently/test-results'
=== removed directory 'couchapp/evently/test-results/_changes'
=== removed file 'couchapp/evently/test-results/_changes/data.js'
--- couchapp/evently/test-results/_changes/data.js 2010-09-02 21:44:21 +0000
+++ couchapp/evently/test-results/_changes/data.js 1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-function (data) {
- var isos = new Array();
- for (var idx in data.rows) {
- var iso_name = data.rows[idx].key[0];
- if (isos[iso_name] == null) {
- isos[iso_name] = { 'name' : iso_name,
- 'tests' : new Array()}
- };
- isos[iso_name].tests.push({ "name": data.rows[idx].key[2],
- "status": data.rows[idx].key[1],
- "stderr": data.rows[idx].value.script_stderr
- });
- }
- var isos2 = new Array();
- for (var idx in isos) {
- isos2.push(isos[idx]);
- }
- $.log(isos2);
- return { 'isos': isos2 };
-}
=== removed file 'couchapp/evently/test-results/_changes/mustache.html'
--- couchapp/evently/test-results/_changes/mustache.html 2010-09-02 21:44:21 +0000
+++ couchapp/evently/test-results/_changes/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
-<ul>
-{{#isos}}
-{{ name }}
-<ul>
- {{#tests}}
- <li>{{ name }}: {{ status }}
- Stderr: <pre>{{ stderr }}</pre>
- </li>
- {{/tests}}
-</ul>
-{{/isos}}
-</ul>
=== removed file 'couchapp/evently/test-results/_changes/query.json'
--- couchapp/evently/test-results/_changes/query.json 2010-09-02 21:44:21 +0000
+++ couchapp/evently/test-results/_changes/query.json 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-{
- "view" : "test-results"
-}
=== removed file 'couchapp/language'
--- couchapp/language 2010-09-01 04:49:09 +0000
+++ couchapp/language 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-python
=== removed directory 'couchapp/lists'
=== removed directory 'couchapp/shows'
=== removed file 'couchapp/shows/test.py'
--- couchapp/shows/test.py 2010-09-01 05:26:45 +0000
+++ couchapp/shows/test.py 1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
-def fun(doc, req):
- import jinja2
- template = jinja2.Template("Hello {{ doc._id }}!")
- return {'body': template.render(doc=doc), 'headers': {'Content-Type': 'text/html'}}
-
=== removed directory 'couchapp/updates'
=== removed directory 'couchapp/vendor'
=== removed directory 'couchapp/vendor/couchapp'
=== removed file 'couchapp/vendor/couchapp/README.md'
--- couchapp/vendor/couchapp/README.md 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/README.md 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-## CouchApp - more than just a filesystem mapper
-
-This is where documentation will go for the client and server JavaScript parts of CouchApp.
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/_attachments'
=== removed file 'couchapp/vendor/couchapp/_attachments/jquery.couch.app.js'
--- couchapp/vendor/couchapp/_attachments/jquery.couch.app.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/_attachments/jquery.couch.app.js 1970-01-01 00:00:00 +0000
@@ -1,329 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy
-// of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Usage: The passed in function is called when the page is ready.
-// CouchApp passes in the app object, which takes care of linking to
-// the proper database, and provides access to the CouchApp helpers.
-// $.couch.app(function(app) {
-// app.db.view(...)
-// ...
-// });
-
-(function($) {
-
- function Design(db, name) {
- this.doc_id = "_design/"+name;
- this.view = function(view, opts) {
- db.view(name+'/'+view, opts);
- };
- this.list = function(list, view, opts) {
- db.list(name+'/'+list, view, opts);
- };
- }
-
- $.couch.app = $.couch.app || function(appFun, opts) {
- opts = opts || {};
- $(function() {
- var urlPrefix = opts.urlPrefix || "";
- $.couch.urlPrefix = urlPrefix;
-
- var index = urlPrefix.split('/').length;
- var fragments = unescape(document.location.href).split('/');
- var dbname = opts.db || fragments[index + 2];
- var dname = opts.design || fragments[index + 4];
-
- var db = $.couch.db(dbname);
- var design = new Design(db, dname);
-
- // docForm applies CouchDB behavior to HTML forms.
- // todo make this a couch.app plugin
- function docForm(formSelector, opts) {
- var localFormDoc = {};
- opts = opts || {};
- opts.fields = opts.fields || [];
-
- // turn the form into deep json
- // field names like 'author-email' get turned into json like
- // {"author":{"email":"quentin@xxxxxxxxxxx"}}
- function formToDeepJSON(form, fields, doc) {
- form = $(form);
- fields.forEach(function(field) {
- var element = form.find("[name="+field+"]");
- if (element.attr('type') === 'checkbox') {
- var val = element.attr('checked');
- } else {
- var val = element.val();
- if (!val) return;
- }
- var parts = field.split('-');
- var frontObj = doc, frontName = parts.shift();
- while (parts.length > 0) {
- frontObj[frontName] = frontObj[frontName] || {};
- frontObj = frontObj[frontName];
- frontName = parts.shift();
- }
- frontObj[frontName] = val;
- });
- }
-
- // Apply the behavior
- $(formSelector).submit(function(e) {
- e.preventDefault();
- if (opts.validate && opts.validate() == false) { return false;}
- // formToDeepJSON acts on localFormDoc by reference
- formToDeepJSON(this, opts.fields, localFormDoc);
- if (opts.beforeSave) {opts.beforeSave(localFormDoc);}
- db.saveDoc(localFormDoc, {
- success : function(resp) {
- if (opts.success) {opts.success(resp, localFormDoc);}
- }
- });
-
- return false;
- });
-
- // populate form from an existing doc
- function docToForm(doc) {
- var form = $(formSelector);
- // fills in forms
- opts.fields.forEach(function(field) {
- var parts = field.split('-');
- var run = true, frontObj = doc, frontName = parts.shift();
- while (frontObj && parts.length > 0) {
- frontObj = frontObj[frontName];
- frontName = parts.shift();
- }
- if (frontObj && frontObj[frontName]) {
- var element = form.find("[name="+field+"]");
- if (element.attr('type') === 'checkbox') {
- element.attr('checked', frontObj[frontName]);
- } else {
- element.val(frontObj[frontName]);
- }
- }
- });
- }
-
- if (opts.id) {
- db.openDoc(opts.id, {
- attachPrevRev : opts.attachPrevRev,
- error: function() {
- if (opts.error) {opts.error.apply(opts, arguments);}
- },
- success: function(doc) {
- if (opts.load || opts.onLoad) {(opts.load || opts.onLoad)(doc);}
- localFormDoc = doc;
- docToForm(doc);
- }});
- } else if (opts.template) {
- if (opts.load || opts.onLoad) {(opts.load || opts.onLoad)(opts.template);}
- localFormDoc = opts.template;
- docToForm(localFormDoc);
- }
- var instance = {
- deleteDoc : function(opts) {
- opts = opts || {};
- if (confirm("Really delete this document?")) {
- db.removeDoc(localFormDoc, opts);
- }
- },
- localDoc : function() {
- formToDeepJSON(formSelector, opts.fields, localFormDoc);
- return localFormDoc;
- }
- };
- return instance;
- }
-
- function resolveModule(names, parent, current) {
- if (names.length === 0) {
- if (typeof current != "string") {
- throw ["error","invalid_require_path",
- 'Must require a JavaScript string, not: '+(typeof current)];
- }
- return [current, parent];
- }
- // we need to traverse the path
- var n = names.shift();
- if (n == '..') {
- if (!(parent && parent.parent)) {
- throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)];
- }
- return resolveModule(names, parent.parent.parent, parent.parent);
- } else if (n == '.') {
- if (!parent) {
- throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)];
- }
- return resolveModule(names, parent.parent, parent);
- }
- if (!current[n]) {
- throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(current)];
- }
- var p = current;
- current = current[n];
- current.parent = p;
- return resolveModule(names, p, current);
- }
-
- var p = document.location.pathname.split('/');
- p.shift();
- var qs = document.location.search.replace(/^\?/,'').split('&');
- var q = {};
- qs.forEach(function(param) {
- var ps = param.split('=');
- var k = decodeURIComponent(ps[0]);
- var v = decodeURIComponent(ps[1]);
- if (["startkey", "endkey", "key"].indexOf(k) != -1) {
- q[k] = JSON.parse(v);
- } else {
- q[k] = v;
- }
- });
- var mockReq = {
- path : p,
- query : q
- };
-
- var appExports = $.extend({
- db : db,
- design : design,
- view : design.view,
- list : design.list,
- docForm : docForm,
- req : mockReq
- }, $.couch.app.app);
-
- function handleDDoc(ddoc) {
- var moduleCache = [];
-
- function getCachedModule(name, parent) {
- var key, i, len = moduleCache.length;
- for (i=0;i<len;++i) {
- key = moduleCache[i].key;
- if (key[0] === name && key[1] === parent) {
- return moduleCache[i].module;
- }
- }
-
- return null;
- }
-
- function setCachedModule(name, parent, module) {
- moduleCache.push({ key: [name, parent], module: module });
- }
-
- if (ddoc) {
- var require = function(name, parent) {
- var cachedModule = getCachedModule(name, parent);
- if (cachedModule !== null) {
- return cachedModule;
- }
-
- var exports = {};
- var resolved = resolveModule(name.split('/'), parent, ddoc);
- var source = resolved[0];
- parent = resolved[1];
- var s = "var func = function (exports, require) { " + source + " };";
- try {
- eval(s);
- func.apply(ddoc, [exports, function(name) {return require(name, parent, source)}]);
- } catch(e) {
- throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()];
- }
-
- setCachedModule(name, parent, exports);
-
- return exports;
- }
- appExports.ddoc = ddoc;
- appExports.require = require;
- }
- // todo make app-exports the this in the execution context?
- appFun.apply(appExports, [appExports]);
- }
-
- if ($.couch.app.ddocs[design.doc_id]) {
- handleDDoc($.couch.app.ddocs[design.doc_id])
- } else {
- // only open 1 connection for this ddoc
- if ($.couch.app.ddoc_handlers[design.doc_id]) {
- // we are already fetching, just wait
- $.couch.app.ddoc_handlers[design.doc_id].push(handleDDoc);
- } else {
- $.couch.app.ddoc_handlers[design.doc_id] = [handleDDoc];
- db.openDoc(design.doc_id, {
- success : function(doc) {
- $.couch.app.ddocs[design.doc_id] = doc;
- $.couch.app.ddoc_handlers[design.doc_id].forEach(function(h) {
- h(doc);
- });
- $.couch.app.ddoc_handlers[design.doc_id] = null;
- },
- error : function() {
- $.couch.app.ddoc_handlers[design.doc_id].forEach(function(h) {
- h();
- });
- $.couch.app.ddoc_handlers[design.doc_id] = null;
- }
- });
- }
- }
-
- });
- };
- $.couch.app.ddocs = {};
- $.couch.app.ddoc_handlers = {};
- // legacy support. $.CouchApp is deprecated, please use $.couch.app
- $.CouchApp = $.couch.app;
-})(jQuery);
-
-// JavaScript 1.6 compatibility functions that are missing from IE7/IE8
-
-if (!Array.prototype.forEach)
-{
- Array.prototype.forEach = function(fun /*, thisp*/)
- {
- var len = this.length >>> 0;
- if (typeof fun != "function")
- throw new TypeError();
-
- var thisp = arguments[1];
- for (var i = 0; i < len; i++)
- {
- if (i in this)
- fun.call(thisp, this[i], i, this);
- }
- };
-}
-
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
=== removed file 'couchapp/vendor/couchapp/_attachments/jquery.couch.app.util.js'
--- couchapp/vendor/couchapp/_attachments/jquery.couch.app.util.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/_attachments/jquery.couch.app.util.js 1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
-$.log = function(m) {
- if (window && window.console && window.console.log) {
- window.console.log(arguments.length == 1 ? m : arguments);
- }
-};
-
-// http://stackoverflow.com/questions/1184624/serialize-form-to-json-with-jquery/1186309#1186309
-$.fn.serializeObject = function() {
- var o = {};
- var a = this.serializeArray();
- $.each(a, function() {
- if (o[this.name]) {
- if (!o[this.name].push) {
- o[this.name] = [o[this.name]];
- }
- o[this.name].push(this.value || '');
- } else {
- o[this.name] = this.value || '';
- }
- });
- return o;
-};
-
-// todo remove this crap
-function escapeHTML(st) {
- return(
- st && st.replace(/&/g,'&').
- replace(/>/g,'>').
- replace(/</g,'<').
- replace(/"/g,'"')
- );
-};
-
-function safeHTML(st, len) {
- return st ? escapeHTML(st.substring(0,len)) : '';
-}
-
-// todo this should take a replacement template
-$.linkify = function(body) {
- return body.replace(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi,function(a) {
- return '<a target="_blank" href="'+a+'">'+a+'</a>';
- }).replace(/\@([\w\-]+)/g,function(user,name) {
- return '<a href="#/mentions/'+encodeURIComponent(name.toLowerCase())+'">'+user+'</a>';
- }).replace(/\#([\w\-\.]+)/g,function(word,tag) {
- return '<a href="#/tags/'+encodeURIComponent(tag.toLowerCase())+'">'+word+'</a>';
- });
-};
-
-$.fn.prettyDate = function() {
- $(this).each(function() {
- $(this).text($.prettyDate($(this).text()));
- });
-};
-
-$.prettyDate = function(time){
-
- var date = new Date(time.replace(/-/g,"/").replace("T", " ").replace("Z", " +0000").replace(/(\d*\:\d*:\d*)\.\d*/g,"$1")),
- diff = (((new Date()).getTime() - date.getTime()) / 1000),
- day_diff = Math.floor(diff / 86400);
-
- if (isNaN(day_diff)) return time;
-
- return day_diff < 1 && (
- diff < 60 && "just now" ||
- diff < 120 && "1 minute ago" ||
- diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
- diff < 7200 && "1 hour ago" ||
- diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
- day_diff == 1 && "yesterday" ||
- day_diff < 21 && day_diff + " days ago" ||
- day_diff < 45 && Math.ceil( day_diff / 7 ) + " weeks ago" ||
- day_diff < 730 && Math.ceil( day_diff / 31 ) + " months ago" ||
- Math.ceil( day_diff / 365 ) + " years ago";
-};
-
-$.argsToArray = function(args) {
- if (!args.callee) return args;
- var array = [];
- for (var i=0; i < args.length; i++) {
- array.push(args[i]);
- };
- return array;
-}
=== removed file 'couchapp/vendor/couchapp/_attachments/jquery.evently.js'
--- couchapp/vendor/couchapp/_attachments/jquery.evently.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/_attachments/jquery.evently.js 1970-01-01 00:00:00 +0000
@@ -1,363 +0,0 @@
-// $$ inspired by @wycats: http://yehudakatz.com/2009/04/20/evented-programming-with-jquery/
-function $$(node) {
- var data = $(node).data("$$");
- if (data) {
- return data;
- } else {
- data = {};
- $(node).data("$$", data);
- return data;
- }
-};
-
-(function($) {
- // utility functions used in the implementation
-
- function forIn(obj, fun) {
- var name;
- for (name in obj) {
- if (obj.hasOwnProperty(name)) {
- fun(name, obj[name]);
- }
- }
- };
- $.forIn = forIn;
- function funViaString(fun) {
- if (fun && fun.match && fun.match(/^function/)) {
- eval("var f = "+fun);
- if (typeof f == "function") {
- return function() {
- try {
- return f.apply(this, arguments);
- } catch(e) {
- // IF YOU SEE AN ERROR HERE IT HAPPENED WHEN WE TRIED TO RUN YOUR FUNCTION
- $.log({"message": "Error in evently function.", "error": e, "src" : fun});
- throw(e);
- }
- };
- }
- }
- return fun;
- };
-
- function runIfFun(me, fun, args) {
- // if the field is a function, call it, bound to the widget
- var f = funViaString(fun);
- if (typeof f == "function") {
- return f.apply(me, args);
- } else {
- return fun;
- }
- }
-
- $.evently = {
- connect : function(source, target, events) {
- events.forEach(function(ev) {
- $(source).bind(ev, function() {
- var args = $.makeArray(arguments);
- // remove the original event to keep from stacking args extra deep
- // it would be nice if jquery had a way to pass the original
- // event to the trigger method.
- args.shift();
- $(target).trigger(ev, args);
- return false;
- });
- });
- },
- paths : [],
- changesDBs : {},
- changesOpts : {}
- };
-
- function extractFrom(name, evs) {
- return evs[name];
- };
-
- function extractEvents(name, ddoc) {
- // extract events from ddoc.evently and ddoc.vendor.*.evently
- var events = [true, {}];
- $.forIn(ddoc.vendor, function(k, v) {
- if (v.evently && v.evently[name]) {
- events.push(v.evently[name]);
- }
- });
- if (ddoc.evently[name]) {events.push(ddoc.evently[name]);}
- return $.extend.apply(null, events);
- }
-
- $.fn.evently = function(events, app, args) {
- var elem = $(this);
- // store the app on the element for later use
- if (app) {
- $$(elem).app = app;
- }
-
- if (typeof events == "string") {
- events = extractEvents(events, app.ddoc);
- }
-
- $$(elem).evently = events;
- // setup the handlers onto elem
- forIn(events, function(name, h) {
- eventlyHandler(elem, name, h, args);
- });
-
- if (events._init) {
- // $.log("ev _init", elem);
- elem.trigger("_init", args);
- }
-
- if (app && events._changes) {
- $("body").bind("evently-changes-"+app.db.name, function() {
- // we want to unbind this function when the element is deleted.
- // maybe jquery 1.4.2 has this covered?
- // $.log('changes', elem);
- elem.trigger("_changes");
- });
- followChanges(app);
- elem.trigger("_changes");
- }
- };
-
- // eventlyHandler applies the user's handler (h) to the
- // elem, bound to trigger based on name.
- function eventlyHandler(elem, name, h, args) {
- if (h.path) {
- elem.pathbinder(name, h.path);
- }
- var f = funViaString(h);
- if (typeof f == "function") {
- elem.bind(name, {args:args}, f);
- } else if (typeof f == "string") {
- elem.bind(name, {args:args}, function() {
- $(this).trigger(f, arguments);
- return false;
- });
- } else if ($.isArray(h)) {
- // handle arrays recursively
- for (var i=0; i < h.length; i++) {
- eventlyHandler(elem, name, h[i], args);
- }
- } else {
- // an object is using the evently / mustache template system
- if (h.fun) {
- elem.bind(name, {args:args}, funViaString(h.fun));
- }
- // templates, selectors, etc are intepreted
- // when our named event is triggered.
- elem.bind(name, {args:args}, function() {
- renderElement($(this), h, arguments);
- return false;
- });
- }
- };
-
- $.fn.replace = function(elem) {
- // $.log("Replace", this)
- $(this).empty().append(elem);
- };
-
- // todo: ability to call this
- // to render and "prepend/append/etc" a new element to the host element (me)
- // as well as call this in a way that replaces the host elements content
- // this would be easy if there is a simple way to get at the element we just appended
- // (as html) so that we can attache the selectors
- function renderElement(me, h, args, qrun, arun) {
- // if there's a query object we run the query,
- // and then call the data function with the response.
- if (h.before && (!qrun || !arun)) {
- funViaString(h.before).apply(me, args);
- }
- if (h.async && !arun) {
- runAsync(me, h, args)
- } else if (h.query && !qrun) {
- // $.log("query before renderElement", arguments)
- runQuery(me, h, args)
- } else {
- // $.log("renderElement")
- // $.log(me, h, args, qrun)
- // otherwise we just render the template with the current args
- var selectors = runIfFun(me, h.selectors, args);
- var act = (h.render || "replace").replace(/\s/g,"");
- var app = $$(me).app;
- if (h.mustache) {
- // $.log("rendering", h.mustache)
- var newElem = mustachioed(me, h, args);
- me[act](newElem);
- }
- if (selectors) {
- if (act == "replace") {
- var s = me;
- } else {
- var s = newElem;
- }
- forIn(selectors, function(selector, handlers) {
- // $.log("selector", selector);
- // $.log("selected", $(selector, s));
- $(selector, s).evently(handlers, app, args);
- // $.log("applied", selector);
- });
- }
- if (h.after) {
- runIfFun(me, h.after, args);
- // funViaString(h.after).apply(me, args);
- }
- }
- };
-
- // todo this should return the new element
- function mustachioed(me, h, args) {
- return $($.mustache(
- runIfFun(me, h.mustache, args),
- runIfFun(me, h.data, args),
- runIfFun(me, h.partials, args)));
- };
-
- function runAsync(me, h, args) {
- // the callback is the first argument
- funViaString(h.async).apply(me, [function() {
- renderElement(me, h,
- $.argsToArray(arguments).concat($.argsToArray(args)), false, true);
- }].concat($.argsToArray(args)));
- };
-
-
- function runQuery(me, h, args) {
- // $.log("runQuery: args", args)
- var app = $$(me).app;
- var qu = runIfFun(me, h.query, args);
- var qType = qu.type;
- var viewName = qu.view;
- var userSuccess = qu.success;
- // $.log("qType", qType)
-
- var q = {};
- forIn(qu, function(k, v) {
- q[k] = v;
- });
-
- if (qType == "newRows") {
- q.success = function(resp) {
- // $.log("runQuery newRows success", resp.rows.length, me, resp)
- resp.rows.reverse().forEach(function(row) {
- renderElement(me, h, [row].concat($.argsToArray(args)), true)
- });
- if (userSuccess) userSuccess(resp);
- };
- newRows(me, app, viewName, q);
- } else {
- q.success = function(resp) {
- // $.log("runQuery success", resp)
- renderElement(me, h, [resp].concat($.argsToArray(args)), true);
- userSuccess && userSuccess(resp);
- };
- // $.log(app)
- app.view(viewName, q);
- }
- }
-
- // this is for the items handler
- // var lastViewId, highKey, inFlight;
- // this needs to key per elem
- function newRows(elem, app, view, opts) {
- // $.log("newRows", arguments);
- // on success we'll set the top key
- var thisViewId, successCallback = opts.success, full = false;
- function successFun(resp) {
- // $.log("newRows success", resp)
- $$(elem).inFlight = false;
- var JSONhighKey = JSON.stringify($$(elem).highKey);
- resp.rows = resp.rows.filter(function(r) {
- return JSON.stringify(r.key) != JSONhighKey;
- });
- if (resp.rows.length > 0) {
- if (opts.descending) {
- $$(elem).highKey = resp.rows[0].key;
- } else {
- $$(elem).highKey = resp.rows[resp.rows.length -1].key;
- }
- };
- if (successCallback) {successCallback(resp, full)};
- };
- opts.success = successFun;
-
- if (opts.descending) {
- thisViewId = view + (opts.startkey ? JSON.stringify(opts.startkey) : "");
- } else {
- thisViewId = view + (opts.endkey ? JSON.stringify(opts.endkey) : "");
- }
- // $.log(["thisViewId",thisViewId])
- // for query we'll set keys
- if (thisViewId == $$(elem).lastViewId) {
- // we only want the rows newer than changesKey
- var hk = $$(elem).highKey;
- if (hk !== undefined) {
- if (opts.descending) {
- opts.endkey = hk;
- // opts.inclusive_end = false;
- } else {
- opts.startkey = hk;
- }
- }
- // $.log("add view rows", opts)
- if (!$$(elem).inFlight) {
- $$(elem).inFlight = true;
- app.view(view, opts);
- }
- } else {
- // full refresh
- // $.log("new view stuff")
- full = true;
- $$(elem).lastViewId = thisViewId;
- $$(elem).highKey = undefined;
- $$(elem).inFlight = true;
- app.view(view, opts);
- }
- };
-
- // only start one changes listener per db
- function followChanges(app) {
- var dbName = app.db.name, changeEvent = function(resp) {
- $("body").trigger("evently-changes-"+dbName, [resp]);
- };
- if (!$.evently.changesDBs[dbName]) {
- if (app.db.changes) {
- // new api in jquery.couch.js 1.0
- app.db.changes(null, $.evently.changesOpts).onChange(changeEvent);
- } else {
- // in case you are still on CouchDB 0.11 ;) deprecated.
- connectToChanges(app, changeEvent);
- }
- $.evently.changesDBs[dbName] = true;
- }
- }
- $.evently.followChanges = followChanges;
- // deprecated. use db.changes() from jquery.couch.js
- // this does not have an api for closing changes request.
- function connectToChanges(app, fun, update_seq) {
- function changesReq(seq) {
- var url = app.db.uri+"_changes?heartbeat=10000&feed=longpoll&since="+seq;
- if ($.evently.changesOpts.include_docs) {
- url = url + "&include_docs=true";
- }
- $.ajax({
- url: url,
- contentType: "application/json",
- dataType: "json",
- complete: function(req) {
- var resp = $.httpData(req, "json");
- fun(resp);
- connectToChanges(app, fun, resp.last_seq);
- }
- });
- };
- if (update_seq) {
- changesReq(update_seq);
- } else {
- app.db.info({success: function(db_info) {
- changesReq(db_info.update_seq);
- }});
- }
- };
-
-})(jQuery);
=== removed file 'couchapp/vendor/couchapp/_attachments/jquery.mustache.js'
--- couchapp/vendor/couchapp/_attachments/jquery.mustache.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/_attachments/jquery.mustache.js 1970-01-01 00:00:00 +0000
@@ -1,346 +0,0 @@
-/*
-Shameless port of a shameless port
-@defunkt => @janl => @aq
-
-See http://github.com/defunkt/mustache for more info.
-*/
-
-;(function($) {
-
-/*
- mustache.js â Logic-less templates in JavaScript
-
- See http://mustache.github.com/ for more info.
-*/
-
-var Mustache = function() {
- var Renderer = function() {};
-
- Renderer.prototype = {
- otag: "{{",
- ctag: "}}",
- pragmas: {},
- buffer: [],
- pragmas_implemented: {
- "IMPLICIT-ITERATOR": true
- },
- context: {},
-
- render: function(template, context, partials, in_recursion) {
- // reset buffer & set context
- if(!in_recursion) {
- this.context = context;
- this.buffer = []; // TODO: make this non-lazy
- }
-
- // fail fast
- if(!this.includes("", template)) {
- if(in_recursion) {
- return template;
- } else {
- this.send(template);
- return;
- }
- }
-
- template = this.render_pragmas(template);
- var html = this.render_section(template, context, partials);
- if(in_recursion) {
- return this.render_tags(html, context, partials, in_recursion);
- }
-
- this.render_tags(html, context, partials, in_recursion);
- },
-
- /*
- Sends parsed lines
- */
- send: function(line) {
- if(line != "") {
- this.buffer.push(line);
- }
- },
-
- /*
- Looks for %PRAGMAS
- */
- render_pragmas: function(template) {
- // no pragmas
- if(!this.includes("%", template)) {
- return template;
- }
-
- var that = this;
- var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
- this.ctag);
- return template.replace(regex, function(match, pragma, options) {
- if(!that.pragmas_implemented[pragma]) {
- throw({message:
- "This implementation of mustache doesn't understand the '" +
- pragma + "' pragma"});
- }
- that.pragmas[pragma] = {};
- if(options) {
- var opts = options.split("=");
- that.pragmas[pragma][opts[0]] = opts[1];
- }
- return "";
- // ignore unknown pragmas silently
- });
- },
-
- /*
- Tries to find a partial in the curent scope and render it
- */
- render_partial: function(name, context, partials) {
- name = this.trim(name);
- if(!partials || partials[name] === undefined) {
- throw({message: "unknown_partial '" + name + "'"});
- }
- if(typeof(context[name]) != "object") {
- return this.render(partials[name], context, partials, true);
- }
- return this.render(partials[name], context[name], partials, true);
- },
-
- /*
- Renders inverted (^) and normal (#) sections
- */
- render_section: function(template, context, partials) {
- if(!this.includes("#", template) && !this.includes("^", template)) {
- return template;
- }
-
- var that = this;
- // CSW - Added "+?" so it finds the tighest bound, not the widest
- var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
- "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
- "\\s*", "mg");
-
- // for each {{#foo}}{{/foo}} section do...
- return template.replace(regex, function(match, type, name, content) {
- var value = that.find(name, context);
- if(type == "^") { // inverted section
- if(!value || that.is_array(value) && value.length === 0) {
- // false or empty list, render it
- return that.render(content, context, partials, true);
- } else {
- return "";
- }
- } else if(type == "#") { // normal section
- if(that.is_array(value)) { // Enumerable, Let's loop!
- return that.map(value, function(row) {
- return that.render(content, that.create_context(row),
- partials, true);
- }).join("");
- } else if(that.is_object(value)) { // Object, Use it as subcontext!
- return that.render(content, that.create_context(value),
- partials, true);
- } else if(typeof value === "function") {
- // higher order section
- return value.call(context, content, function(text) {
- return that.render(text, context, partials, true);
- });
- } else if(value) { // boolean section
- return that.render(content, context, partials, true);
- } else {
- return "";
- }
- }
- });
- },
-
- /*
- Replace {{foo}} and friends with values from our view
- */
- render_tags: function(template, context, partials, in_recursion) {
- // tit for tat
- var that = this;
-
- var new_regex = function() {
- return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
- that.ctag + "+", "g");
- };
-
- var regex = new_regex();
- var tag_replace_callback = function(match, operator, name) {
- switch(operator) {
- case "!": // ignore comments
- return "";
- case "=": // set new delimiters, rebuild the replace regexp
- that.set_delimiters(name);
- regex = new_regex();
- return "";
- case ">": // render partial
- return that.render_partial(name, context, partials);
- case "{": // the triple mustache is unescaped
- return that.find(name, context);
- default: // escape the value
- return that.escape(that.find(name, context));
- }
- };
- var lines = template.split("\n");
- for(var i = 0; i < lines.length; i++) {
- lines[i] = lines[i].replace(regex, tag_replace_callback, this);
- if(!in_recursion) {
- this.send(lines[i]);
- }
- }
-
- if(in_recursion) {
- return lines.join("\n");
- }
- },
-
- set_delimiters: function(delimiters) {
- var dels = delimiters.split(" ");
- this.otag = this.escape_regex(dels[0]);
- this.ctag = this.escape_regex(dels[1]);
- },
-
- escape_regex: function(text) {
- // thank you Simon Willison
- if(!arguments.callee.sRE) {
- var specials = [
- '/', '.', '*', '+', '?', '|',
- '(', ')', '[', ']', '{', '}', '\\'
- ];
- arguments.callee.sRE = new RegExp(
- '(\\' + specials.join('|\\') + ')', 'g'
- );
- }
- return text.replace(arguments.callee.sRE, '\\$1');
- },
-
- /*
- find `name` in current `context`. That is find me a value
- from the view object
- */
- find: function(name, context) {
- name = this.trim(name);
-
- // Checks whether a value is thruthy or false or 0
- function is_kinda_truthy(bool) {
- return bool === false || bool === 0 || bool;
- }
-
- var value;
- if(is_kinda_truthy(context[name])) {
- value = context[name];
- } else if(is_kinda_truthy(this.context[name])) {
- value = this.context[name];
- }
-
- if(typeof value === "function") {
- return value.apply(context);
- }
- if(value !== undefined) {
- return value;
- }
- // silently ignore unkown variables
- return "";
- },
-
- // Utility methods
-
- /* includes tag */
- includes: function(needle, haystack) {
- return haystack.indexOf(this.otag + needle) != -1;
- },
-
- /*
- Does away with nasty characters
- */
- escape: function(s) {
- s = String(s === null ? "" : s);
- return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
- switch(s) {
- case "&": return "&";
- case "\\": return "\\\\";
- case '"': return '\"';
- case "<": return "<";
- case ">": return ">";
- default: return s;
- }
- });
- },
-
- // by @langalex, support for arrays of strings
- create_context: function(_context) {
- if(this.is_object(_context)) {
- return _context;
- } else {
- var iterator = ".";
- if(this.pragmas["IMPLICIT-ITERATOR"]) {
- iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
- }
- var ctx = {};
- ctx[iterator] = _context;
- return ctx;
- }
- },
-
- is_object: function(a) {
- return a && typeof a == "object";
- },
-
- is_array: function(a) {
- return Object.prototype.toString.call(a) === '[object Array]';
- },
-
- /*
- Gets rid of leading and trailing whitespace
- */
- trim: function(s) {
- return s.replace(/^\s*|\s*$/g, "");
- },
-
- /*
- Why, why, why? Because IE. Cry, cry cry.
- */
- map: function(array, fn) {
- if (typeof array.map == "function") {
- return array.map(fn);
- } else {
- var r = [];
- var l = array.length;
- for(var i = 0; i < l; i++) {
- r.push(fn(array[i]));
- }
- return r;
- }
- }
- };
-
- return({
- name: "mustache.js",
- version: "0.3.1-dev",
-
- /*
- Turns a template and view into HTML
- */
- to_html: function(template, view, partials, send_fun) {
- var renderer = new Renderer();
- if(send_fun) {
- renderer.send = send_fun;
- }
- renderer.render(template, view, partials);
- if(!send_fun) {
- return renderer.buffer.join("\n");
- }
- },
- escape : function(text) {
- return new Renderer().escape(text);
- }
- });
-}();
-
- $.mustache = function(template, view, partials) {
- return Mustache.to_html(template, view, partials);
- };
-
- $.mustache.escape = function(text) {
- return Mustache.escape(text);
- };
-
-})(jQuery);
=== removed file 'couchapp/vendor/couchapp/_attachments/jquery.pathbinder.js'
--- couchapp/vendor/couchapp/_attachments/jquery.pathbinder.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/_attachments/jquery.pathbinder.js 1970-01-01 00:00:00 +0000
@@ -1,172 +0,0 @@
-(function($) {
- // functions for handling the path
- // thanks sammy.js
- var PATH_REPLACER = "([^\/]+)",
- PATH_NAME_MATCHER = /:([\w\d]+)/g,
- QUERY_STRING_MATCHER = /\?([^#]*)$/,
- SPLAT_MATCHER = /(\*)/,
- SPLAT_REPLACER = "(.+)",
- _currentPath,
- _lastPath,
- _pathInterval;
-
- function hashChanged() {
- _currentPath = getPath();
- // if path is actually changed from what we thought it was, then react
- if (_lastPath != _currentPath) {
- _lastPath = _currentPath;
- return triggerOnPath(_currentPath);
- }
- }
-
- $.pathbinder = {
- changeFuns : [],
- paths : [],
- begin : function(defaultPath) {
- // this should trigger the defaultPath if there's not a path in the URL
- // otherwise it should trigger the URL's path
- $(function() {
- var loadPath = getPath();
- if (loadPath) {
- triggerOnPath(loadPath);
- } else {
- goPath(defaultPath);
- triggerOnPath(defaultPath);
- }
- })
- },
- go : function(path) {
- goPath(path);
- triggerOnPath(path);
- },
- currentPath : function() {
- return getPath();
- },
- onChange : function (fun) {
- $.pathbinder.changeFuns.push(fun);
- }
- };
-
- function pollPath(every) {
- function hashCheck() {
- _currentPath = getPath();
- // path changed if _currentPath != _lastPath
- if (_lastPath != _currentPath) {
- setTimeout(function() {
- $(window).trigger('hashchange');
- }, 1);
- }
- };
- hashCheck();
- _pathInterval = setInterval(hashCheck, every);
- $(window).bind('unload', function() {
- clearInterval(_pathInterval);
- });
- }
-
- function triggerOnPath(path) {
- path = path.replace(/^#/,'');
- $.pathbinder.changeFuns.forEach(function(fun) {fun(path)});
- var pathSpec, path_params, params = {}, param_name, param;
- for (var i=0; i < $.pathbinder.paths.length; i++) {
- pathSpec = $.pathbinder.paths[i];
- // $.log("pathSpec", pathSpec);
- if ((path_params = pathSpec.matcher.exec(path)) !== null) {
- // $.log("path_params", path_params);
- path_params.shift();
- for (var j=0; j < path_params.length; j++) {
- param_name = pathSpec.param_names[j];
- param = decodeURIComponent(path_params[j]);
- if (param_name) {
- params[param_name] = param;
- } else {
- if (!params.splat) params.splat = [];
- params.splat.push(param);
- }
- };
- pathSpec.callback(params);
- // return true; // removed this to allow for multi match
- }
- };
- };
-
- // bind the event
- $(function() {
- if ('onhashchange' in window) {
- // we have a native event
- } else {
- pollPath(10);
- }
- // setTimeout(hashChanged,50);
- $(window).bind('hashchange', hashChanged);
- });
-
- function registerPath(pathSpec) {
- $.pathbinder.paths.push(pathSpec);
- };
-
- function setPath(pathSpec, params) {
- var newPath = $.mustache(pathSpec.template, params);
- goPath(newPath);
- };
-
- function goPath(newPath) {
- // $.log("goPath", newPath)
- window.location = '#'+newPath;
- _lastPath = getPath();
- };
-
- function getPath() {
- var matches = window.location.toString().match(/^[^#]*(#.+)$/);
- return matches ? matches[1] : '';
- };
-
- function makePathSpec(path, callback) {
- var param_names = [];
- var template = "";
-
- PATH_NAME_MATCHER.lastIndex = 0;
-
- while ((path_match = PATH_NAME_MATCHER.exec(path)) !== null) {
- param_names.push(path_match[1]);
- }
-
- return {
- param_names : param_names,
- matcher : new RegExp("^" + path.replace(
- PATH_NAME_MATCHER, PATH_REPLACER).replace(
- SPLAT_MATCHER, SPLAT_REPLACER) + "/?$"),
- template : path.replace(PATH_NAME_MATCHER, function(a, b) {
- return '{{'+b+'}}';
- }).replace(SPLAT_MATCHER, '{{splat}}'),
- callback : callback
- };
- };
-
- $.fn.pathbinder = function(name, paths, options) {
- options = options || {};
- var self = $(this), pathList = paths.split(/\n/);
- $.each(pathList, function() {
- var path = this;
- if (path) {
- // $.log("bind path", path);
- var pathSpec = makePathSpec(path, function(params) {
- // $.log("path cb", name, path, self)
- // $.log("trigger path: "+path+" params: ", params);
- self.trigger(name, [params]);
- });
- // set the path when the event triggered through other means
- if (options.bindPath) {
- self.bind(name, function(ev, params) {
- params = params || {};
- // $.log("set path", name, pathSpec)
- setPath(pathSpec, params);
- });
- }
- // trigger when the path matches
- registerPath(pathSpec);
- }
- });
- };
-})(jQuery);
-
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/_attachments/loader.js'
--- couchapp/vendor/couchapp/_attachments/loader.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/_attachments/loader.js 1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-
-function couchapp_load(scripts) {
- for (var i=0; i < scripts.length; i++) {
- document.write('<script src="'+scripts[i]+'"><\/script>')
- };
-};
-
-couchapp_load([
- "/_utils/script/sha1.js",
- "/_utils/script/json2.js",
- "/_utils/script/jquery.js",
- "/_utils/script/jquery.couch.js",
- "vendor/couchapp/jquery.couch.app.js",
- "vendor/couchapp/jquery.couch.app.util.js",
- "vendor/couchapp/jquery.mustache.js",
- "vendor/couchapp/jquery.evently.js"
-]);
=== removed directory 'couchapp/vendor/couchapp/evently'
=== removed file 'couchapp/vendor/couchapp/evently/README.md'
--- couchapp/vendor/couchapp/evently/README.md 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/README.md 1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-## Starting the Document this code challenge
-
-I need help on this code. I only have so many hours in the day. Please be liberal about patching and hacking (and sharing code!) so we can all benefit.
-
-Docs patches are deeply appreciated. For now you can just stick Markdown files in the Docs directory.
-
-# Evently
-
-These are some vendor Evently widgets that are running on the CouchApp system.
-
-## Account
- This is how you signup, login and logout without worry about the code.
- Todo, we could have this work against remote APIs like that Facebook stuff or whatever.
-
-
-## Profile
- Use this to load the local users profile for the logged in user. Useful if you're going to be posting new messages. Most applications end up customizing `profile.profileReady` to render the primary data-entry form. This gets you benefits like refreshing on login / logout, etc, automatically.
-
-
-## Docs
- This needs to be moved to it's own app.
- I have this vision of a docs app designed for offline editing, that involves each Markdown paragraph being it's own document, with automatic use of Bespin for code samples. Any help on this would be thanked much.
=== removed directory 'couchapp/vendor/couchapp/evently/account'
=== removed file 'couchapp/vendor/couchapp/evently/account/_init.js'
--- couchapp/vendor/couchapp/evently/account/_init.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/_init.js 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-function() {
- var elem = $(this);
- $$(this).userCtx = null;
- $.couch.session({
- success : function(r) {
- var userCtx = r.userCtx;
- if (userCtx.name) {
- elem.trigger("loggedIn", [r]);
- } else if (userCtx.roles.indexOf("_admin") != -1) {
- elem.trigger("adminParty");
- } else {
- elem.trigger("loggedOut");
- };
- }
- });
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/adminParty'
=== removed file 'couchapp/vendor/couchapp/evently/account/adminParty/mustache.html'
--- couchapp/vendor/couchapp/evently/account/adminParty/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/adminParty/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-<p><strong>Admin party, everyone is admin!</strong> Fix this in <a href="/_utils/index.html">Futon</a> before proceeding.</p>
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/doLogin.js'
--- couchapp/vendor/couchapp/evently/account/doLogin.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/doLogin.js 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-function(e, name, pass) {
- var elem = $(this);
- $.couch.login({
- name : name,
- password : pass,
- success : function(r) {
- elem.trigger("_init")
- }
- });
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/doLogout.js'
--- couchapp/vendor/couchapp/evently/account/doLogout.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/doLogout.js 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
-function() {
- var elem = $(this);
- $.couch.logout({
- success : function() {
- elem.trigger("_init");
- }
- });
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/doSignup.js'
--- couchapp/vendor/couchapp/evently/account/doSignup.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/doSignup.js 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-function(e, name, pass) {
- var elem = $(this);
- $.couch.signup({
- name : name
- }, pass, {
- success : function() {
- elem.trigger("doLogin", [name, pass]);
- }
- });
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/loggedIn'
=== removed file 'couchapp/vendor/couchapp/evently/account/loggedIn/after.js'
--- couchapp/vendor/couchapp/evently/account/loggedIn/after.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loggedIn/after.js 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-function(e, r) {
- $$(this).userCtx = r.userCtx;
- $$(this).info = r.info;
-};
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/loggedIn/data.js'
--- couchapp/vendor/couchapp/evently/account/loggedIn/data.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loggedIn/data.js 1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
-function(e, r) {
- return {
- name : r.userCtx.name,
- uri_name : encodeURIComponent(r.userCtx.name),
- auth_db : encodeURIComponent(r.info.authentication_db)
- };
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/loggedIn/mustache.html'
--- couchapp/vendor/couchapp/evently/account/loggedIn/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loggedIn/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-<span>Welcome
-<a target="_new" href="/_utils/document.html?{{auth_db}}/org.couchdb.user%3A{{uri_name}}">{{name}}</a>!
-<a href="#logout">Logout?</a>
-</span>
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/loggedIn/selectors.json'
--- couchapp/vendor/couchapp/evently/account/loggedIn/selectors.json 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loggedIn/selectors.json 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-{
- "a[href=#logout]" : {"click" : ["doLogout"]}
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/loggedOut'
=== removed file 'couchapp/vendor/couchapp/evently/account/loggedOut/mustache.html'
--- couchapp/vendor/couchapp/evently/account/loggedOut/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loggedOut/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-<a href="#signup">Signup</a> or <a href="#login">Login</a>
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/loggedOut/selectors.json'
--- couchapp/vendor/couchapp/evently/account/loggedOut/selectors.json 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loggedOut/selectors.json 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-{
- "a[href=#signup]" : {"click" : ["signupForm"]},
- "a[href=#login]" : {"click" : ["loginForm"]}
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/loginForm'
=== removed file 'couchapp/vendor/couchapp/evently/account/loginForm/after.js'
--- couchapp/vendor/couchapp/evently/account/loginForm/after.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loginForm/after.js 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-function() {
- $("input[name=name]", this).focus();
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/loginForm/mustache.html'
--- couchapp/vendor/couchapp/evently/account/loginForm/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loginForm/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-<form>
- <label for="name">Name</label> <input type="text" name="name" value="">
- <label for="password">Password</label> <input type="password" name="password" value="">
- <input type="submit" value="Login">
- <a href="#signup">or Signup</a>
-</form>
=== removed directory 'couchapp/vendor/couchapp/evently/account/loginForm/selectors'
=== removed file 'couchapp/vendor/couchapp/evently/account/loginForm/selectors/a[href=#signup].json'
--- couchapp/vendor/couchapp/evently/account/loginForm/selectors/a[href=#signup].json 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loginForm/selectors/a[href=#signup].json 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-{"click" : ["signupForm"]}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/loginForm/selectors/form'
=== removed file 'couchapp/vendor/couchapp/evently/account/loginForm/selectors/form/submit.js'
--- couchapp/vendor/couchapp/evently/account/loginForm/selectors/form/submit.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/loginForm/selectors/form/submit.js 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-function(e) {
- var name = $('input[name=name]', this).val(),
- pass = $('input[name=password]', this).val();
- $(this).trigger('doLogin', [name, pass]);
- return false;
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/signupForm'
=== removed file 'couchapp/vendor/couchapp/evently/account/signupForm/after.js'
--- couchapp/vendor/couchapp/evently/account/signupForm/after.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/signupForm/after.js 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-function() {
- $("input[name=name]", this).focus();
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/account/signupForm/mustache.html'
--- couchapp/vendor/couchapp/evently/account/signupForm/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/signupForm/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-<form>
- <label for="name">Name</label> <input type="text" name="name" value="">
- <label for="password">Password</label> <input type="password" name="password" value="">
- <input type="submit" value="Signup">
- <a href="#login">or Login</a>
-</form>
=== removed directory 'couchapp/vendor/couchapp/evently/account/signupForm/selectors'
=== removed file 'couchapp/vendor/couchapp/evently/account/signupForm/selectors/a[href=#login].json'
--- couchapp/vendor/couchapp/evently/account/signupForm/selectors/a[href=#login].json 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/signupForm/selectors/a[href=#login].json 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-{"click" : ["loginForm"]}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/account/signupForm/selectors/form'
=== removed file 'couchapp/vendor/couchapp/evently/account/signupForm/selectors/form/submit.js'
--- couchapp/vendor/couchapp/evently/account/signupForm/selectors/form/submit.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/account/signupForm/selectors/form/submit.js 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-function(e) {
- var name = $('input[name=name]', this).val(),
- pass = $('input[name=password]', this).val();
- $(this).trigger('doSignup', [name, pass]);
- return false;
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/profile'
=== removed file 'couchapp/vendor/couchapp/evently/profile/loggedIn.js'
--- couchapp/vendor/couchapp/evently/profile/loggedIn.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/loggedIn.js 1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-function(e, r) {
- var userCtx = r.userCtx;
- var widget = $(this);
- // load the profile from the user doc
- var db = $.couch.db(r.info.authentication_db);
- var userDocId = "org.couchdb.user:"+userCtx.name;
- db.openDoc(userDocId, {
- success : function(userDoc) {
- var profile = userDoc["couch.app.profile"];
- if (profile) {
- // we copy the name to the profile so it can be used later
- // without publishing the entire userdoc (roles, pass, etc)
- profile.name = userDoc.name;
- $$(widget).profile = profile;
- widget.trigger("profileReady", [profile]);
- } else {
- widget.trigger("noProfile", [userCtx]);
- }
- }
- });
-}
=== removed directory 'couchapp/vendor/couchapp/evently/profile/loggedOut'
=== removed file 'couchapp/vendor/couchapp/evently/profile/loggedOut/after.js'
--- couchapp/vendor/couchapp/evently/profile/loggedOut/after.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/loggedOut/after.js 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-function() {
- $$(this).profile = null;
-};
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/profile/loggedOut/mustache.html'
--- couchapp/vendor/couchapp/evently/profile/loggedOut/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/loggedOut/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-<p>Please log in to see your profile.</p>
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/profile/noProfile'
=== removed file 'couchapp/vendor/couchapp/evently/profile/noProfile/data.js'
--- couchapp/vendor/couchapp/evently/profile/noProfile/data.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/noProfile/data.js 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-function(e, userCtx) {
- return userCtx;
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/profile/noProfile/mustache.html'
--- couchapp/vendor/couchapp/evently/profile/noProfile/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/noProfile/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
-<form>
- <p>Hello {{name}}, Please setup your user profile.</p>
- <label for="nickname">Nickname
- <input type="text" name="nickname" value=""></label>
- <label for="email">Email (<em>for <a href="http://gravatar.com">Gravatar</a></em>)
- <input type="text" name="email" value=""></label>
- <label for="url">URL
- <input type="text" name="url" value=""></label>
- <input type="submit" value="Go →">
- <input type="hidden" name="userCtxName" value="{{name}}" id="userCtxName">
-</form>
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/profile/noProfile/selectors'
=== removed directory 'couchapp/vendor/couchapp/evently/profile/noProfile/selectors/form'
=== removed file 'couchapp/vendor/couchapp/evently/profile/noProfile/selectors/form/submit.js'
--- couchapp/vendor/couchapp/evently/profile/noProfile/selectors/form/submit.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/noProfile/selectors/form/submit.js 1970-01-01 00:00:00 +0000
@@ -1,36 +0,0 @@
-function() {
- var md5 = $$(this).app.require("vendor/couchapp/lib/md5");
-
- // TODO this can be cleaned up with docForm?
- // it still needs the workflow to edit an existing profile
- var name = $("input[name=userCtxName]",this).val();
- var newProfile = {
- rand : Math.random().toString(),
- nickname : $("input[name=nickname]",this).val(),
- email : $("input[name=email]",this).val(),
- url : $("input[name=url]",this).val()
- }, widget = $(this);
-
- // setup gravatar_url
- if (md5) {
- newProfile.gravatar_url = 'http://www.gravatar.com/avatar/'+md5.hex(newProfile.email || newProfile.rand)+'.jpg?s=40&d=identicon';
- }
-
- // store the user profile on the user account document
- $.couch.userDb(function(db) {
- var userDocId = "org.couchdb.user:"+name;
- db.openDoc(userDocId, {
- success : function(userDoc) {
- userDoc["couch.app.profile"] = newProfile;
- db.saveDoc(userDoc, {
- success : function() {
- newProfile.name = userDoc.name;
- $$(widget).profile = newProfile;
- widget.trigger("profileReady", [newProfile]);
- }
- });
- }
- });
- });
- return false;
-}
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/evently/profile/profileReady'
=== removed file 'couchapp/vendor/couchapp/evently/profile/profileReady/after.js'
--- couchapp/vendor/couchapp/evently/profile/profileReady/after.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/profileReady/after.js 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-function(e, p) {
- $$(this).profile = p;
-};
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/evently/profile/profileReady/data.js'
--- couchapp/vendor/couchapp/evently/profile/profileReady/data.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/profileReady/data.js 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-function(e, p) {
- return p
-}
=== removed file 'couchapp/vendor/couchapp/evently/profile/profileReady/mustache.html'
--- couchapp/vendor/couchapp/evently/profile/profileReady/mustache.html 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/evently/profile/profileReady/mustache.html 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
-<div class="avatar">
- {{#gravatar_url}}<img src="{{gravatar_url}}"/>{{/gravatar_url}}
- <div class="name">
- {{nickname}}
- </div>
-</div>
-<p>Hello {{nickname}}!</p>
-<div style="clear:left;"></div>
\ No newline at end of file
=== removed directory 'couchapp/vendor/couchapp/lib'
=== removed file 'couchapp/vendor/couchapp/lib/atom.js'
--- couchapp/vendor/couchapp/lib/atom.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/atom.js 1970-01-01 00:00:00 +0000
@@ -1,39 +0,0 @@
-// atom feed generator
-// requries E4X support.
-
-function f(n) { // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
-}
-
-function rfc3339(date) {
- return date.getUTCFullYear() + '-' +
- f(date.getUTCMonth() + 1) + '-' +
- f(date.getUTCDate()) + 'T' +
- f(date.getUTCHours()) + ':' +
- f(date.getUTCMinutes()) + ':' +
- f(date.getUTCSeconds()) + 'Z';
-};
-
-exports.header = function(data) {
- var f = <feed xmlns="http://www.w3.org/2005/Atom"/>;
- f.title = data.title;
- f.id = data.feed_id;
- f.link.@href = data.feed_link;
- f.link.@rel = "self";
- f.generator = "CouchApp on CouchDB";
- f.updated = rfc3339(data.updated);
- return f.toXMLString().replace(/\<\/feed\>/,'');
-};
-
-exports.entry = function(data) {
- var entry = <entry/>;
- entry.id = data.entry_id;
- entry.title = data.title;
- entry.content = data.content;
- entry.content.@type = (data.content_type || 'html');
- entry.updated = rfc3339(data.updated);
- entry.author = <author><name>{data.author}</name></author>;
- entry.link.@href = data.alternate;
- entry.link.@rel = "alternate";
- return entry;
-}
=== removed file 'couchapp/vendor/couchapp/lib/cache.js'
--- couchapp/vendor/couchapp/lib/cache.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/cache.js 1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
-exports.get = function(db, docid, setFun, getFun) {
- db.openDoc(docid, {
- success : function(doc) {
- getFun(doc.cache);
- },
- error : function() {
- setFun(function(cache) {
- db.saveDoc({
- _id : docid,
- cache : cache
- });
- getFun(cache);
- });
- }
- });
-};
-
-exports.clear = function(db, docid) {
- db.openDoc(docid, {
- success : function(doc) {
- db.removeDoc(doc);
- },
- error : function() {}
- });
-};
=== removed file 'couchapp/vendor/couchapp/lib/docform.js'
--- couchapp/vendor/couchapp/lib/docform.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/docform.js 1970-01-01 00:00:00 +0000
@@ -1,108 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy
-// of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// turn the form into deep json
-// field names like 'author-email' get turned into json like
-// {"author":{"email":"quentin@xxxxxxxxxxx"}}
-// acts on doc by reference, so you can safely pass non-form fields through
-function formToDeepJSON(form, fields, doc) {
- form = $(form);
- fields.forEach(function(field) {
- var val = form.find("[name="+field+"]").val();
- if (!val) {return;}
- var parts = field.split('-');
- var frontObj = doc, frontName = parts.shift();
- while (parts.length > 0) {
- frontObj[frontName] = frontObj[frontName] || {};
- frontObj = frontObj[frontName];
- frontName = parts.shift();
- }
- frontObj[frontName] = val;
- });
-}
-
-function onSubmit(form, db, doc, opts) {
- formToDeepJSON(form, opts.fields, doc);
- if (opts.beforeSave) {opts.beforeSave(doc);}
- db.saveDoc(localFormDoc, {
- success : function(resp) {
- if (opts.success) {opts.success(resp, doc);}
- }
- });
-};
-
-function applyFields(form, doc) {
-
-};
-exports.applyFields = applyFields;
-
-// docForm applies CouchDB behavior to HTML forms.
-// todo make this a couch.app plugin
-function docForm(formSelector, opts) {
- var localFormDoc = {};
- opts = opts || {};
- opts.fields = opts.fields || [];
-
- // Apply the behavior
- $(formSelector).submit(function(e) {
-
-
- return false;
- });
-
- // populate form from an existing doc
- function docToForm(doc) {
- var form = $(formSelector);
- // fills in forms
- opts.fields.forEach(function(field) {
- var parts = field.split('-');
- var run = true, frontObj = doc, frontName = parts.shift();
- while (frontObj && parts.length > 0) {
- frontObj = frontObj[frontName];
- frontName = parts.shift();
- }
- if (frontObj && frontObj[frontName]) {
- form.find("[name="+field+"]").val(frontObj[frontName]);
- }
- });
- }
-
- if (opts.id) {
- db.openDoc(opts.id, {
- success: function(doc) {
- if (opts.onLoad) {opts.onLoad(doc);}
- localFormDoc = doc;
- docToForm(doc);
- }});
- } else if (opts.template) {
- if (opts.onLoad) {opts.onLoad(opts.template);}
- localFormDoc = opts.template;
- docToForm(localFormDoc);
- }
- var instance = {
- deleteDoc : function(opts) {
- opts = opts || {};
- if (confirm("Really delete this document?")) {
- db.removeDoc(localFormDoc, opts);
- }
- },
- localDoc : function() {
- formToDeepJSON(formSelector, opts.fields, localFormDoc);
- return localFormDoc;
- }
- };
- return instance;
- }
-
-
-
-
=== removed file 'couchapp/vendor/couchapp/lib/linkup.js'
--- couchapp/vendor/couchapp/lib/linkup.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/linkup.js 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
-// this code makes http://example.com into a link,
-// and also handles @name and #hashtag
-
-// todo add [[wiki_links]]
-
-var mustache = require("vendor/couchapp/lib/mustache");
-exports.encode = function(body, person_prefix, tag_prefix) {
- body = mustache.escape(body);
- person_prefix = person_prefix || "http://twitter.com/";
- tag_prefix = tag_prefix || "http://delicious.com/tag/";
- return body.replace(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi,function(a) {
- return '<a target="_blank" href="'+a+'">'+a+'</a>';
- }).replace(/\@([\w\-]+)/g,function(user,name) {
- return '<a href="'+person_prefix+encodeURIComponent(name.toLowerCase())+'">'+user+'</a>';
- }).replace(/\#([\w\-\.]+)/g,function(word,tag) {
- return '<a href="'+tag_prefix+encodeURIComponent(tag.toLowerCase())+'">'+word+'</a>';
- });
-};
=== removed file 'couchapp/vendor/couchapp/lib/list.js'
--- couchapp/vendor/couchapp/lib/list.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/list.js 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-// Helpers for writing server-side _list functions in CouchDB
-exports.withRows = function(fun) {
- var f = function() {
- var row = getRow();
- return row && fun(row);
- };
- f.iterator = true;
- return f;
-}
-
-exports.send = function(chunk) {
- send(chunk + "\n")
-}
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/lib/markdown.js'
--- couchapp/vendor/couchapp/lib/markdown.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/markdown.js 1970-01-01 00:00:00 +0000
@@ -1,1300 +0,0 @@
-//
-// showdown.js -- A javascript port of Markdown.
-//
-// Copyright (c) 2007 John Fraser.
-//
-// Original Markdown Copyright (c) 2004-2005 John Gruber
-// <http://daringfireball.net/projects/markdown/>
-//
-// Redistributable under a BSD-style open source license.
-// See license.txt for more information.
-//
-// The full source distribution is at:
-//
-// A A L
-// T C A
-// T K B
-//
-// <http://www.attacklab.net/>
-//
-
-//
-// Wherever possible, Showdown is a straight, line-by-line port
-// of the Perl version of Markdown.
-//
-// This is not a normal parser design; it's basically just a
-// series of string substitutions. It's hard to read and
-// maintain this way, but keeping Showdown close to the original
-// design makes it easier to port new features.
-//
-// More importantly, Showdown behaves like markdown.pl in most
-// edge cases. So web applications can do client-side preview
-// in Javascript, and then build identical HTML on the server.
-//
-// This port needs the new RegExp functionality of ECMA 262,
-// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers
-// should do fine. Even with the new regular expression features,
-// We do a lot of work to emulate Perl's regex functionality.
-// The tricky changes in this file mostly have the "attacklab:"
-// label. Major or self-explanatory changes don't.
-//
-// Smart diff tools like Araxis Merge will be able to match up
-// this file with markdown.pl in a useful way. A little tweaking
-// helps: in a copy of markdown.pl, replace "#" with "//" and
-// replace "$text" with "text". Be sure to ignore whitespace
-// and line endings.
-//
-
-
-//
-// Showdown usage:
-//
-// var text = "Markdown *rocks*.";
-//
-// var markdown = require("markdown");
-// var html = markdown.encode(text);
-//
-// print(html);
-//
-// Note: move the sample code to the bottom of this
-// file before uncommenting it.
-//
-
-
-//
-// Globals:
-//
-
-// Global hashes, used by various utility routines
-var g_urls;
-var g_titles;
-var g_html_blocks;
-
-// Used to track when we're inside an ordered or unordered list
-// (see _ProcessListItems() for details):
-var g_list_level = 0;
-
-
-exports.makeHtml = function(text) {
-//
-// Main function. The order in which other subs are called here is
-// essential. Link and image substitutions need to happen before
-// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
-// and <img> tags get encoded.
-//
-
- // Clear the global hashes. If we don't clear these, you get conflicts
- // from other articles when generating a page which contains more than
- // one article (e.g. an index page that shows the N most recent
- // articles):
- g_urls = new Array();
- g_titles = new Array();
- g_html_blocks = new Array();
-
- // attacklab: Replace ~ with ~T
- // This lets us use tilde as an escape char to avoid md5 hashes
- // The choice of character is arbitray; anything that isn't
- // magic in Markdown will work.
- text = text.replace(/~/g,"~T");
-
- // attacklab: Replace $ with ~D
- // RegExp interprets $ as a special character
- // when it's in a replacement string
- text = text.replace(/\$/g,"~D");
-
- // Standardize line endings
- text = text.replace(/\r\n/g,"\n"); // DOS to Unix
- text = text.replace(/\r/g,"\n"); // Mac to Unix
-
- // Make sure text begins and ends with a couple of newlines:
- text = "\n\n" + text + "\n\n";
-
- // Convert all tabs to spaces.
- text = _Detab(text);
-
- // Strip any lines consisting only of spaces and tabs.
- // This makes subsequent regexen easier to write, because we can
- // match consecutive blank lines with /\n+/ instead of something
- // contorted like /[ \t]*\n+/ .
- text = text.replace(/^[ \t]+$/mg,"");
-
- // Turn block-level HTML blocks into hash entries
- text = _HashHTMLBlocks(text);
-
- // Strip link definitions, store in hashes.
- text = _StripLinkDefinitions(text);
-
- text = _RunBlockGamut(text);
-
- text = _UnescapeSpecialChars(text);
-
- // attacklab: Restore dollar signs
- text = text.replace(/~D/g,"$$");
-
- // attacklab: Restore tildes
- text = text.replace(/~T/g,"~");
- return text;
-}
-
-
-var _StripLinkDefinitions = function(text) {
-//
-// Strips link definitions from text, stores the URLs and titles in
-// hash references.
-//
-
- // Link defs are in the form: ^[id]: url "optional title"
-
- /*
- var text = text.replace(/
- ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1
- [ \t]*
- \n? // maybe *one* newline
- [ \t]*
- <?(\S+?)>? // url = $2
- [ \t]*
- \n? // maybe one newline
- [ \t]*
- (?:
- (\n*) // any lines skipped = $3 attacklab: lookbehind removed
- ["(]
- (.+?) // title = $4
- [")]
- [ \t]*
- )? // title is optional
- (?:\n+|$)
- /gm,
- function(){...});
- */
- var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,
- function (wholeMatch,m1,m2,m3,m4) {
- m1 = m1.toLowerCase();
- g_urls[m1] = _EncodeAmpsAndAngles(m2); // Link IDs are case-insensitive
- if (m3) {
- // Oops, found blank lines, so it's not a title.
- // Put back the parenthetical statement we stole.
- return m3+m4;
- } else if (m4) {
- g_titles[m1] = m4.replace(/"/g,""");
- }
-
- // Completely remove the definition from the text
- return "";
- }
- );
-
- return text;
-}
-
-
-var _HashHTMLBlocks = function(text) {
- // attacklab: Double up blank lines to reduce lookaround
- text = text.replace(/\n/g,"\n\n");
-
- // Hashify HTML blocks:
- // We only want to do this for block-level HTML tags, such as headers,
- // lists, and tables. That's because we still want to wrap <p>s around
- // "paragraphs" that are wrapped in non-block-level tags, such as anchors,
- // phrase emphasis, and spans. The list of tags we're looking for is
- // hard-coded:
- var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del"
- var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math"
-
- // First, look for nested blocks, e.g.:
- // <div>
- // <div>
- // tags for inner block must be indented.
- // </div>
- // </div>
- //
- // The outermost tags must start at the left margin for this to match, and
- // the inner nested divs must be indented.
- // We need to do this before the next, more liberal match, because the next
- // match will start at the first `<div>` and stop at the first `</div>`.
-
- // attacklab: This regex can be expensive when it fails.
- /*
- var text = text.replace(/
- ( // save in $1
- ^ // start of line (with /m)
- <($block_tags_a) // start tag = $2
- \b // word break
- // attacklab: hack around khtml/pcre bug...
- [^\r]*?\n // any number of lines, minimally matching
- </\2> // the matching end tag
- [ \t]* // trailing spaces/tabs
- (?=\n+) // followed by a newline
- ) // attacklab: there are sentinel newlines at end of document
- /gm,function(){...}};
- */
- text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement);
-
- //
- // Now match more liberally, simply from `\n<tag>` to `</tag>\n`
- //
-
- /*
- var text = text.replace(/
- ( // save in $1
- ^ // start of line (with /m)
- <($block_tags_b) // start tag = $2
- \b // word break
- // attacklab: hack around khtml/pcre bug...
- [^\r]*? // any number of lines, minimally matching
- .*</\2> // the matching end tag
- [ \t]* // trailing spaces/tabs
- (?=\n+) // followed by a newline
- ) // attacklab: there are sentinel newlines at end of document
- /gm,function(){...}};
- */
- text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
-
- // Special case just for <hr />. It was easier to make a special case than
- // to make the other regex more complicated.
-
- /*
- text = text.replace(/
- ( // save in $1
- \n\n // Starting after a blank line
- [ ]{0,3}
- (<(hr) // start tag = $2
- \b // word break
- ([^<>])*? //
- \/?>) // the matching end tag
- [ \t]*
- (?=\n{2,}) // followed by a blank line
- )
- /g,hashElement);
- */
- text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
-
- // Special case for standalone HTML comments:
-
- /*
- text = text.replace(/
- ( // save in $1
- \n\n // Starting after a blank line
- [ ]{0,3} // attacklab: g_tab_width - 1
- <!
- (--[^\r]*?--\s*)+
- >
- [ \t]*
- (?=\n{2,}) // followed by a blank line
- )
- /g,hashElement);
- */
- text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,hashElement);
-
- // PHP and ASP-style processor instructions (<?...?> and <%...%>)
-
- /*
- text = text.replace(/
- (?:
- \n\n // Starting after a blank line
- )
- ( // save in $1
- [ ]{0,3} // attacklab: g_tab_width - 1
- (?:
- <([?%]) // $2
- [^\r]*?
- \2>
- )
- [ \t]*
- (?=\n{2,}) // followed by a blank line
- )
- /g,hashElement);
- */
- text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
-
- // attacklab: Undo double lines (see comment at top of this function)
- text = text.replace(/\n\n/g,"\n");
- return text;
-}
-
-var hashElement = function(wholeMatch,m1) {
- var blockText = m1;
-
- // Undo double lines
- blockText = blockText.replace(/\n\n/g,"\n");
- blockText = blockText.replace(/^\n/,"");
-
- // strip trailing blank lines
- blockText = blockText.replace(/\n+$/g,"");
-
- // Replace the element text with a marker ("~KxK" where x is its key)
- blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
-
- return blockText;
-};
-
-var _RunBlockGamut = function(text) {
-//
-// These are all the transformations that form block-level
-// tags like paragraphs, headers, and list items.
-//
- text = _DoHeaders(text);
-
- // Do Horizontal Rules:
- var key = hashBlock("<hr />");
- text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
- text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
- text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
-
- text = _DoLists(text);
- text = _DoCodeBlocks(text);
- text = _DoBlockQuotes(text);
-
- // We already ran _HashHTMLBlocks() before, in Markdown(), but that
- // was to escape raw HTML in the original Markdown source. This time,
- // we're escaping the markup we've just created, so that we don't wrap
- // <p> tags around block-level tags.
- text = _HashHTMLBlocks(text);
- text = _FormParagraphs(text);
-
- return text;
-}
-
-
-var _RunSpanGamut = function(text) {
-//
-// These are all the transformations that occur *within* block-level
-// tags like paragraphs, headers, and list items.
-//
-
- text = _DoCodeSpans(text);
- text = _EscapeSpecialCharsWithinTagAttributes(text);
- text = _EncodeBackslashEscapes(text);
-
- // Process anchor and image tags. Images must come first,
- // because ![foo][f] looks like an anchor.
- text = _DoImages(text);
- text = _DoAnchors(text);
-
- // Make links out of things like `<http://example.com/>`
- // Must come after _DoAnchors(), because you can use < and >
- // delimiters in inline links like [this](<url>).
- text = _DoAutoLinks(text);
- text = _EncodeAmpsAndAngles(text);
- text = _DoItalicsAndBold(text);
-
- // Do hard breaks:
- text = text.replace(/ +\n/g," <br />\n");
-
- return text;
-}
-
-var _EscapeSpecialCharsWithinTagAttributes = function(text) {
-//
-// Within tags -- meaning between < and > -- encode [\ ` * _] so they
-// don't conflict with their use in Markdown for code, italics and strong.
-//
-
- // Build a regex to find HTML tags and comments. See Friedl's
- // "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
- var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
-
- text = text.replace(regex, function(wholeMatch) {
- var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
- tag = escapeCharacters(tag,"\\`*_");
- return tag;
- });
-
- return text;
-}
-
-var _DoAnchors = function(text) {
-//
-// Turn Markdown link shortcuts into XHTML <a> tags.
-//
- //
- // First, handle reference-style links: [link text] [id]
- //
-
- /*
- text = text.replace(/
- ( // wrap whole match in $1
- \[
- (
- (?:
- \[[^\]]*\] // allow brackets nested one level
- |
- [^\[] // or anything else
- )*
- )
- \]
-
- [ ]? // one optional space
- (?:\n[ ]*)? // one optional newline followed by spaces
-
- \[
- (.*?) // id = $3
- \]
- )()()()() // pad remaining backreferences
- /g,_DoAnchors_callback);
- */
- text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
-
- //
- // Next, inline-style links: [link text](url "optional title")
- //
-
- /*
- text = text.replace(/
- ( // wrap whole match in $1
- \[
- (
- (?:
- \[[^\]]*\] // allow brackets nested one level
- |
- [^\[\]] // or anything else
- )
- )
- \]
- \( // literal paren
- [ \t]*
- () // no id, so leave $3 empty
- <?(.*?)>? // href = $4
- [ \t]*
- ( // $5
- (['"]) // quote char = $6
- (.*?) // Title = $7
- \6 // matching quote
- [ \t]* // ignore any spaces/tabs between closing quote and )
- )? // title is optional
- \)
- )
- /g,writeAnchorTag);
- */
- text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
-
- //
- // Last, handle reference-style shortcuts: [link text]
- // These must come last in case you've also got [link test][1]
- // or [link test](/foo)
- //
-
- /*
- text = text.replace(/
- ( // wrap whole match in $1
- \[
- ([^\[\]]+) // link text = $2; can't contain '[' or ']'
- \]
- )()()()()() // pad rest of backreferences
- /g, writeAnchorTag);
- */
- text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
-
- return text;
-}
-
-var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
- if (m7 == undefined) m7 = "";
- var whole_match = m1;
- var link_text = m2;
- var link_id = m3.toLowerCase();
- var url = m4;
- var title = m7;
-
- if (url == "") {
- if (link_id == "") {
- // lower-case and turn embedded newlines into spaces
- link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
- }
- url = "#"+link_id;
-
- if (g_urls[link_id] != undefined) {
- url = g_urls[link_id];
- if (g_titles[link_id] != undefined) {
- title = g_titles[link_id];
- }
- }
- else {
- if (whole_match.search(/\(\s*\)$/m)>-1) {
- // Special case for explicit empty url
- url = "";
- } else {
- return whole_match;
- }
- }
- }
-
- url = escapeCharacters(url,"*_");
- var result = "<a href=\"" + url + "\"";
-
- if (title != "") {
- title = title.replace(/"/g,""");
- title = escapeCharacters(title,"*_");
- result += " title=\"" + title + "\"";
- }
-
- result += ">" + link_text + "</a>";
-
- return result;
-}
-
-
-var _DoImages = function(text) {
-//
-// Turn Markdown image shortcuts into <img> tags.
-//
-
- //
- // First, handle reference-style labeled images: ![alt text][id]
- //
-
- /*
- text = text.replace(/
- ( // wrap whole match in $1
- !\[
- (.*?) // alt text = $2
- \]
-
- [ ]? // one optional space
- (?:\n[ ]*)? // one optional newline followed by spaces
-
- \[
- (.*?) // id = $3
- \]
- )()()()() // pad rest of backreferences
- /g,writeImageTag);
- */
- text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
-
- //
- // Next, handle inline images: 
- // Don't forget: encode * and _
-
- /*
- text = text.replace(/
- ( // wrap whole match in $1
- !\[
- (.*?) // alt text = $2
- \]
- \s? // One optional whitespace character
- \( // literal paren
- [ \t]*
- () // no id, so leave $3 empty
- <?(\S+?)>? // src url = $4
- [ \t]*
- ( // $5
- (['"]) // quote char = $6
- (.*?) // title = $7
- \6 // matching quote
- [ \t]*
- )? // title is optional
- \)
- )
- /g,writeImageTag);
- */
- text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
-
- return text;
-}
-
-var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
- var whole_match = m1;
- var alt_text = m2;
- var link_id = m3.toLowerCase();
- var url = m4;
- var title = m7;
-
- if (!title) title = "";
-
- if (url == "") {
- if (link_id == "") {
- // lower-case and turn embedded newlines into spaces
- link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
- }
- url = "#"+link_id;
-
- if (g_urls[link_id] != undefined) {
- url = g_urls[link_id];
- if (g_titles[link_id] != undefined) {
- title = g_titles[link_id];
- }
- }
- else {
- return whole_match;
- }
- }
-
- alt_text = alt_text.replace(/"/g,""");
- url = escapeCharacters(url,"*_");
- var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
-
- // attacklab: Markdown.pl adds empty title attributes to images.
- // Replicate this bug.
-
- //if (title != "") {
- title = title.replace(/"/g,""");
- title = escapeCharacters(title,"*_");
- result += " title=\"" + title + "\"";
- //}
-
- result += " />";
-
- return result;
-}
-
-
-var _DoHeaders = function(text) {
-
- // Setext-style headers:
- // Header 1
- // ========
- //
- // Header 2
- // --------
- //
- text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
- function(wholeMatch,m1){return hashBlock("<h1>" + _RunSpanGamut(m1) + "</h1>");});
-
- text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
- function(matchFound,m1){return hashBlock("<h2>" + _RunSpanGamut(m1) + "</h2>");});
-
- // atx-style headers:
- // # Header 1
- // ## Header 2
- // ## Header 2 with closing hashes ##
- // ...
- // ###### Header 6
- //
-
- /*
- text = text.replace(/
- ^(\#{1,6}) // $1 = string of #'s
- [ \t]*
- (.+?) // $2 = Header text
- [ \t]*
- \#* // optional closing #'s (not counted)
- \n+
- /gm, function() {...});
- */
-
- text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
- function(wholeMatch,m1,m2) {
- var h_level = m1.length;
- return hashBlock("<h" + h_level + ">" + _RunSpanGamut(m2) + "</h" + h_level + ">");
- });
-
- return text;
-}
-
-// This declaration keeps Dojo compressor from outputting garbage:
-var _ProcessListItems;
-
-var _DoLists = function(text) {
-//
-// Form HTML ordered (numbered) and unordered (bulleted) lists.
-//
-
- // attacklab: add sentinel to hack around khtml/safari bug:
- // http://bugs.webkit.org/show_bug.cgi?id=11231
- text += "~0";
-
- // Re-usable pattern to match any entirel ul or ol list:
-
- /*
- var whole_list = /
- ( // $1 = whole list
- ( // $2
- [ ]{0,3} // attacklab: g_tab_width - 1
- ([*+-]|\d+[.]) // $3 = first list item marker
- [ \t]+
- )
- [^\r]+?
- ( // $4
- ~0 // sentinel for workaround; should be $
- |
- \n{2,}
- (?=\S)
- (?! // Negative lookahead for another list item marker
- [ \t]*
- (?:[*+-]|\d+[.])[ \t]+
- )
- )
- )/g
- */
- var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
-
- if (g_list_level) {
- text = text.replace(whole_list,function(wholeMatch,m1,m2) {
- var list = m1;
- var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
-
- // Turn double returns into triple returns, so that we can make a
- // paragraph for the last item in a list, if necessary:
- list = list.replace(/\n{2,}/g,"\n\n\n");;
- var result = _ProcessListItems(list);
-
- // Trim any trailing whitespace, to put the closing `</$list_type>`
- // up on the preceding line, to get it past the current stupid
- // HTML block parser. This is a hack to work around the terrible
- // hack that is the HTML block parser.
- result = result.replace(/\s+$/,"");
- result = "<"+list_type+">" + result + "</"+list_type+">\n";
- return result;
- });
- } else {
- whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
- text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
- var runup = m1;
- var list = m2;
-
- var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
- // Turn double returns into triple returns, so that we can make a
- // paragraph for the last item in a list, if necessary:
- var list = list.replace(/\n{2,}/g,"\n\n\n");;
- var result = _ProcessListItems(list);
- result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
- return result;
- });
- }
-
- // attacklab: strip sentinel
- text = text.replace(/~0/,"");
-
- return text;
-}
-
-_ProcessListItems = function(list_str) {
-//
-// Process the contents of a single ordered or unordered list, splitting it
-// into individual list items.
-//
- // The $g_list_level global keeps track of when we're inside a list.
- // Each time we enter a list, we increment it; when we leave a list,
- // we decrement. If it's zero, we're not in a list anymore.
- //
- // We do this because when we're not inside a list, we want to treat
- // something like this:
- //
- // I recommend upgrading to version
- // 8. Oops, now this line is treated
- // as a sub-list.
- //
- // As a single paragraph, despite the fact that the second line starts
- // with a digit-period-space sequence.
- //
- // Whereas when we're inside a list (or sub-list), that line will be
- // treated as the start of a sub-list. What a kludge, huh? This is
- // an aspect of Markdown's syntax that's hard to parse perfectly
- // without resorting to mind-reading. Perhaps the solution is to
- // change the syntax rules such that sub-lists must start with a
- // starting cardinal number; e.g. "1." or "a.".
-
- g_list_level++;
-
- // trim trailing blank lines:
- list_str = list_str.replace(/\n{2,}$/,"\n");
-
- // attacklab: add sentinel to emulate \z
- list_str += "~0";
-
- /*
- list_str = list_str.replace(/
- (\n)? // leading line = $1
- (^[ \t]*) // leading whitespace = $2
- ([*+-]|\d+[.]) [ \t]+ // list marker = $3
- ([^\r]+? // list item text = $4
- (\n{1,2}))
- (?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+))
- /gm, function(){...});
- */
- list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
- function(wholeMatch,m1,m2,m3,m4){
- var item = m4;
- var leading_line = m1;
- var leading_space = m2;
-
- if (leading_line || (item.search(/\n{2,}/)>-1)) {
- item = _RunBlockGamut(_Outdent(item));
- }
- else {
- // Recursion for sub-lists:
- item = _DoLists(_Outdent(item));
- item = item.replace(/\n$/,""); // chomp(item)
- item = _RunSpanGamut(item);
- }
-
- return "<li>" + item + "</li>\n";
- }
- );
-
- // attacklab: strip sentinel
- list_str = list_str.replace(/~0/g,"");
-
- g_list_level--;
- return list_str;
-}
-
-
-var _DoCodeBlocks = function(text) {
-//
-// Process Markdown `<pre><code>` blocks.
-//
-
- /*
- text = text.replace(text,
- /(?:\n\n|^)
- ( // $1 = the code block -- one or more lines, starting with a space/tab
- (?:
- (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
- .*\n+
- )+
- )
- (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
- /g,function(){...});
- */
-
- // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
- text += "~0";
-
- text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
- function(wholeMatch,m1,m2) {
- var codeblock = m1;
- var nextChar = m2;
-
- codeblock = _EncodeCode( _Outdent(codeblock));
- codeblock = _Detab(codeblock);
- codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
- codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
-
- codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
-
- return hashBlock(codeblock) + nextChar;
- }
- );
-
- // attacklab: strip sentinel
- text = text.replace(/~0/,"");
-
- return text;
-}
-
-var hashBlock = function(text) {
- text = text.replace(/(^\n+|\n+$)/g,"");
- return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
-}
-
-
-var _DoCodeSpans = function(text) {
-//
-// * Backtick quotes are used for <code></code> spans.
-//
-// * You can use multiple backticks as the delimiters if you want to
-// include literal backticks in the code span. So, this input:
-//
-// Just type ``foo `bar` baz`` at the prompt.
-//
-// Will translate to:
-//
-// <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
-//
-// There's no arbitrary limit to the number of backticks you
-// can use as delimters. If you need three consecutive backticks
-// in your code, use four for delimiters, etc.
-//
-// * You can use spaces to get literal backticks at the edges:
-//
-// ... type `` `bar` `` ...
-//
-// Turns to:
-//
-// ... type <code>`bar`</code> ...
-//
-
- /*
- text = text.replace(/
- (^|[^\\]) // Character before opening ` can't be a backslash
- (`+) // $2 = Opening run of `
- ( // $3 = The code block
- [^\r]*?
- [^`] // attacklab: work around lack of lookbehind
- )
- \2 // Matching closer
- (?!`)
- /gm, function(){...});
- */
-
- text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
- function(wholeMatch,m1,m2,m3,m4) {
- var c = m3;
- c = c.replace(/^([ \t]*)/g,""); // leading whitespace
- c = c.replace(/[ \t]*$/g,""); // trailing whitespace
- c = _EncodeCode(c);
- return m1+"<code>"+c+"</code>";
- });
-
- return text;
-}
-
-
-var _EncodeCode = function(text) {
-//
-// Encode/escape certain characters inside Markdown code runs.
-// The point is that in code, these characters are literals,
-// and lose their special Markdown meanings.
-//
- // Encode all ampersands; HTML entities are not
- // entities within a Markdown code span.
- text = text.replace(/&/g,"&");
-
- // Do the angle bracket song and dance:
- text = text.replace(/</g,"<");
- text = text.replace(/>/g,">");
-
- // Now, escape characters that are magic in Markdown:
- text = escapeCharacters(text,"\*_{}[]\\",false);
-
-// jj the line above breaks this:
-//---
-
-//* Item
-
-// 1. Subitem
-
-// special char: *
-//---
-
- return text;
-}
-
-
-var _DoItalicsAndBold = function(text) {
-
- // <strong> must go first:
- text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
- "<strong>$2</strong>");
-
- text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
- "<em>$2</em>");
-
- return text;
-}
-
-
-var _DoBlockQuotes = function(text) {
-
- /*
- text = text.replace(/
- ( // Wrap whole match in $1
- (
- ^[ \t]*>[ \t]? // '>' at the start of a line
- .+\n // rest of the first line
- (.+\n)* // subsequent consecutive lines
- \n* // blanks
- )+
- )
- /gm, function(){...});
- */
-
- text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
- function(wholeMatch,m1) {
- var bq = m1;
-
- // attacklab: hack around Konqueror 3.5.4 bug:
- // "----------bug".replace(/^-/g,"") == "bug"
-
- bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0"); // trim one level of quoting
-
- // attacklab: clean up hack
- bq = bq.replace(/~0/g,"");
-
- bq = bq.replace(/^[ \t]+$/gm,""); // trim whitespace-only lines
- bq = _RunBlockGamut(bq); // recurse
-
- bq = bq.replace(/(^|\n)/g,"$1 ");
- // These leading spaces screw with <pre> content, so we need to fix that:
- bq = bq.replace(
- /(\s*<pre>[^\r]+?<\/pre>)/gm,
- function(wholeMatch,m1) {
- var pre = m1;
- // attacklab: hack around Konqueror 3.5.4 bug:
- pre = pre.replace(/^ /mg,"~0");
- pre = pre.replace(/~0/g,"");
- return pre;
- });
-
- return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
- });
- return text;
-}
-
-
-var _FormParagraphs = function(text) {
-//
-// Params:
-// $text - string to process with html <p> tags
-//
-
- // Strip leading and trailing lines:
- text = text.replace(/^\n+/g,"");
- text = text.replace(/\n+$/g,"");
-
- var grafs = text.split(/\n{2,}/g);
- var grafsOut = new Array();
-
- //
- // Wrap <p> tags.
- //
- var end = grafs.length;
- for (var i=0; i<end; i++) {
- var str = grafs[i];
-
- // if this is an HTML marker, copy it
- if (str.search(/~K(\d+)K/g) >= 0) {
- grafsOut.push(str);
- }
- else if (str.search(/\S/) >= 0) {
- str = _RunSpanGamut(str);
- str = str.replace(/^([ \t]*)/g,"<p>");
- str += "</p>"
- grafsOut.push(str);
- }
-
- }
-
- //
- // Unhashify HTML blocks
- //
- end = grafsOut.length;
- for (var i=0; i<end; i++) {
- // if this is a marker for an html block...
- while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
- var blockText = g_html_blocks[RegExp.$1];
- blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
- grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
- }
- }
-
- return grafsOut.join("\n\n");
-}
-
-
-var _EncodeAmpsAndAngles = function(text) {
-// Smart processing for ampersands and angle brackets that need to be encoded.
-
- // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
- // http://bumppo.net/projects/amputator/
- text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&");
-
- // Encode naked <'s
- text = text.replace(/<(?![a-z\/?\$!])/gi,"<");
-
- return text;
-}
-
-
-var _EncodeBackslashEscapes = function(text) {
-//
-// Parameter: String.
-// Returns: The string, with after processing the following backslash
-// escape sequences.
-//
-
- // attacklab: The polite way to do this is with the new
- // escapeCharacters() function:
- //
- // text = escapeCharacters(text,"\\",true);
- // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
- //
- // ...but we're sidestepping its use of the (slow) RegExp constructor
- // as an optimization for Firefox. This function gets called a LOT.
-
- text = text.replace(/\\(\\)/g,escapeCharacters_callback);
- text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
- return text;
-}
-
-
-var _DoAutoLinks = function(text) {
-
- text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
-
- // Email addresses: <address@xxxxxxxxxx>
-
- /*
- text = text.replace(/
- <
- (?:mailto:)?
- (
- [-.\w]+
- \@
- [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
- )
- >
- /gi, _DoAutoLinks_callback());
- */
- text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
- function(wholeMatch,m1) {
- return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
- }
- );
-
- return text;
-}
-
-
-var _EncodeEmailAddress = function(addr) {
-//
-// Input: an email address, e.g. "foo@xxxxxxxxxxx"
-//
-// Output: the email address as a mailto link, with each character
-// of the address encoded as either a decimal or hex entity, in
-// the hopes of foiling most address harvesting spam bots. E.g.:
-//
-// <a href="mailto:foo@e
-// xample.com">foo
-// @example.com</a>
-//
-// Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
-// mailing list: <http://tinyurl.com/yu7ue>
-//
-
- // attacklab: why can't javascript speak hex?
- function char2hex(ch) {
- var hexDigits = '0123456789ABCDEF';
- var dec = ch.charCodeAt(0);
- return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
- }
-
- var encode = [
- function(ch){return "&#"+ch.charCodeAt(0)+";";},
- function(ch){return "&#x"+char2hex(ch)+";";},
- function(ch){return ch;}
- ];
-
- addr = "mailto:" + addr;
-
- addr = addr.replace(/./g, function(ch) {
- if (ch == "@") {
- // this *must* be encoded. I insist.
- ch = encode[Math.floor(Math.random()*2)](ch);
- } else if (ch !=":") {
- // leave ':' alone (to spot mailto: later)
- var r = Math.random();
- // roughly 10% raw, 45% hex, 45% dec
- ch = (
- r > .9 ? encode[2](ch) :
- r > .45 ? encode[1](ch) :
- encode[0](ch)
- );
- }
- return ch;
- });
-
- addr = "<a href=\"" + addr + "\">" + addr + "</a>";
- addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
-
- return addr;
-}
-
-
-var _UnescapeSpecialChars = function(text) {
-//
-// Swap back in all the special characters we've hidden.
-//
- text = text.replace(/~E(\d+)E/g,
- function(wholeMatch,m1) {
- var charCodeToReplace = parseInt(m1);
- return String.fromCharCode(charCodeToReplace);
- }
- );
- return text;
-}
-
-
-var _Outdent = function(text) {
-//
-// Remove one level of line-leading tabs or spaces
-//
-
- // attacklab: hack around Konqueror 3.5.4 bug:
- // "----------bug".replace(/^-/g,"") == "bug"
-
- text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
-
- // attacklab: clean up hack
- text = text.replace(/~0/g,"")
-
- return text;
-}
-
-var _Detab = function(text) {
-// attacklab: Detab's completely rewritten for speed.
-// In perl we could fix it by anchoring the regexp with \G.
-// In javascript we're less fortunate.
-
- // expand first n-1 tabs
- text = text.replace(/\t(?=\t)/g," "); // attacklab: g_tab_width
-
- // replace the nth with two sentinels
- text = text.replace(/\t/g,"~A~B");
-
- // use the sentinel to anchor our regex so it doesn't explode
- text = text.replace(/~B(.+?)~A/g,
- function(wholeMatch,m1,m2) {
- var leadingText = m1;
- var numSpaces = 4 - leadingText.length % 4; // attacklab: g_tab_width
-
- // there *must* be a better way to do this:
- for (var i=0; i<numSpaces; i++) leadingText+=" ";
-
- return leadingText;
- }
- );
-
- // clean up sentinels
- text = text.replace(/~A/g," "); // attacklab: g_tab_width
- text = text.replace(/~B/g,"");
-
- return text;
-}
-
-
-//
-// attacklab: Utility functions
-//
-
-
-var escapeCharacters = function(text, charsToEscape, afterBackslash) {
- // First we have to escape the escape characters so that
- // we can build a character class out of them
- var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
-
- if (afterBackslash) {
- regexString = "\\\\" + regexString;
- }
-
- var regex = new RegExp(regexString,"g");
- text = text.replace(regex,escapeCharacters_callback);
-
- return text;
-}
-
-
-var escapeCharacters_callback = function(wholeMatch,m1) {
- var charCodeToEscape = m1.charCodeAt(0);
- return "~E"+charCodeToEscape+"E";
-}
-
-exports.encode = exports.markdown = function (src) {
- return exports.makeHtml(src);
-};
-
-exports.main = function (system) {
- var command = system.args.shift();
- if (!system.args.length) {
- system.stdout.write(exports.markdown(system.stdin.read())).flush();
- } else {
- var arg;
- while (arg = system.args.shift()) {
- var out = system.fs.basename(arg, '.md') + '.html';
- print(out);
- system.fs.write(out, exports.markdown(system.fs.read(arg)));
- }
- }
-};
-
-
=== removed file 'couchapp/vendor/couchapp/lib/md5.js'
--- couchapp/vendor/couchapp/lib/md5.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/md5.js 1970-01-01 00:00:00 +0000
@@ -1,261 +0,0 @@
-/*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
-var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
-var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
-function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
-function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
-function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
-function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
-function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function md5_vm_test()
-{
- return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
-}
-
-/*
- * Calculate the MD5 of an array of little-endian words, and a bit length
- keep
- */
-function core_md5(x, len)
-{
- /* append padding */
- x[len >> 5] |= 0x80 << ((len) % 32);
- x[(((len + 64) >>> 9) << 4) + 14] = len;
-
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
-
- for(var i = 0; i < x.length; i += 16)
- {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
-
- a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
- d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
- c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
- b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
- a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
- d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
- c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
- b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
- a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
- d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
- c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
- b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
- a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
- d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
- c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
- b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
-
- a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
- d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
- c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
- b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
- a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
- d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
- c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
- b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
- a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
- d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
- c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
- b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
- a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
- d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
- c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
- b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
- a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
- d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
- c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
- b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
- a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
- d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
- c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
- b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
- a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
- d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
- c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
- b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
- a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
- d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
- c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
- b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
- a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
- d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
- c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
- b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
- a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
- d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
- c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
- b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
- a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
- d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
- c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
- b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
- a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
- d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
- c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
- b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- }
- return Array(a, b, c, d);
-
-}
-
-/*
- * These functions implement the four basic operations the algorithm uses.
- */
-function md5_cmn(q, a, b, x, s, t)
-{
- return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
-}
-function md5_ff(a, b, c, d, x, s, t)
-{
- return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
-}
-function md5_gg(a, b, c, d, x, s, t)
-{
- return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
-}
-function md5_hh(a, b, c, d, x, s, t)
-{
- return md5_cmn(b ^ c ^ d, a, b, x, s, t);
-}
-function md5_ii(a, b, c, d, x, s, t)
-{
- return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
-}
-
-/*
- * Calculate the HMAC-MD5, of a key and some data
- */
-function core_hmac_md5(key, data)
-{
- var bkey = str2binl(key);
- if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
-
- var ipad = Array(16), opad = Array(16);
- for(var i = 0; i < 16; i++)
- {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
- return core_md5(opad.concat(hash), 512 + 128);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
- return (num << cnt) | (num >>> (32 - cnt));
-}
-
-/*
- * Convert a string to an array of little-endian words
- * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
- keep
- */
-function str2binl(str)
-{
- var bin = Array();
- var mask = (1 << chrsz) - 1;
- for(var i = 0; i < str.length * chrsz; i += chrsz)
- bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
- return bin;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2str(bin)
-{
- var str = "";
- var mask = (1 << chrsz) - 1;
- for(var i = 0; i < bin.length * 32; i += chrsz)
- str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
- return str;
-}
-
-/*
- * Convert an array of little-endian words to a hex string.
- keep
- */
-function binl2hex(binarray)
-{
- var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i++)
- {
- str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
- hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
- }
- return str;
-}
-
-/*
- * Convert an array of little-endian words to a base-64 string
- */
-function binl2b64(binarray)
-{
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i += 3)
- {
- var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
- | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
- | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
- for(var j = 0; j < 4; j++)
- {
- if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
- else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
- }
- }
- return str;
-}
-
-exports.hex = hex_md5;
=== removed file 'couchapp/vendor/couchapp/lib/mustache.js'
--- couchapp/vendor/couchapp/lib/mustache.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/mustache.js 1970-01-01 00:00:00 +0000
@@ -1,339 +0,0 @@
-/*
- * CommonJS-compatible mustache.js module
- *
- * See http://github.com/janl/mustache.js for more info.
- */
-
-/*
- mustache.js â Logic-less templates in JavaScript
-
- See http://mustache.github.com/ for more info.
-*/
-
-var Mustache = function() {
- var Renderer = function() {};
-
- Renderer.prototype = {
- otag: "{{",
- ctag: "}}",
- pragmas: {},
- buffer: [],
- pragmas_implemented: {
- "IMPLICIT-ITERATOR": true
- },
- context: {},
-
- render: function(template, context, partials, in_recursion) {
- // reset buffer & set context
- if(!in_recursion) {
- this.context = context;
- this.buffer = []; // TODO: make this non-lazy
- }
-
- // fail fast
- if(!this.includes("", template)) {
- if(in_recursion) {
- return template;
- } else {
- this.send(template);
- return;
- }
- }
-
- template = this.render_pragmas(template);
- var html = this.render_section(template, context, partials);
- if(in_recursion) {
- return this.render_tags(html, context, partials, in_recursion);
- }
-
- this.render_tags(html, context, partials, in_recursion);
- },
-
- /*
- Sends parsed lines
- */
- send: function(line) {
- if(line != "") {
- this.buffer.push(line);
- }
- },
-
- /*
- Looks for %PRAGMAS
- */
- render_pragmas: function(template) {
- // no pragmas
- if(!this.includes("%", template)) {
- return template;
- }
-
- var that = this;
- var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
- this.ctag);
- return template.replace(regex, function(match, pragma, options) {
- if(!that.pragmas_implemented[pragma]) {
- throw({message:
- "This implementation of mustache doesn't understand the '" +
- pragma + "' pragma"});
- }
- that.pragmas[pragma] = {};
- if(options) {
- var opts = options.split("=");
- that.pragmas[pragma][opts[0]] = opts[1];
- }
- return "";
- // ignore unknown pragmas silently
- });
- },
-
- /*
- Tries to find a partial in the curent scope and render it
- */
- render_partial: function(name, context, partials) {
- name = this.trim(name);
- if(!partials || partials[name] === undefined) {
- throw({message: "unknown_partial '" + name + "'"});
- }
- if(typeof(context[name]) != "object") {
- return this.render(partials[name], context, partials, true);
- }
- return this.render(partials[name], context[name], partials, true);
- },
-
- /*
- Renders inverted (^) and normal (#) sections
- */
- render_section: function(template, context, partials) {
- if(!this.includes("#", template) && !this.includes("^", template)) {
- return template;
- }
-
- var that = this;
- // CSW - Added "+?" so it finds the tighest bound, not the widest
- var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
- "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
- "\\s*", "mg");
-
- // for each {{#foo}}{{/foo}} section do...
- return template.replace(regex, function(match, type, name, content) {
- var value = that.find(name, context);
- if(type == "^") { // inverted section
- if(!value || that.is_array(value) && value.length === 0) {
- // false or empty list, render it
- return that.render(content, context, partials, true);
- } else {
- return "";
- }
- } else if(type == "#") { // normal section
- if(that.is_array(value)) { // Enumerable, Let's loop!
- return that.map(value, function(row) {
- return that.render(content, that.create_context(row),
- partials, true);
- }).join("");
- } else if(that.is_object(value)) { // Object, Use it as subcontext!
- return that.render(content, that.create_context(value),
- partials, true);
- } else if(typeof value === "function") {
- // higher order section
- return value.call(context, content, function(text) {
- return that.render(text, context, partials, true);
- });
- } else if(value) { // boolean section
- return that.render(content, context, partials, true);
- } else {
- return "";
- }
- }
- });
- },
-
- /*
- Replace {{foo}} and friends with values from our view
- */
- render_tags: function(template, context, partials, in_recursion) {
- // tit for tat
- var that = this;
-
- var new_regex = function() {
- return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
- that.ctag + "+", "g");
- };
-
- var regex = new_regex();
- var tag_replace_callback = function(match, operator, name) {
- switch(operator) {
- case "!": // ignore comments
- return "";
- case "=": // set new delimiters, rebuild the replace regexp
- that.set_delimiters(name);
- regex = new_regex();
- return "";
- case ">": // render partial
- return that.render_partial(name, context, partials);
- case "{": // the triple mustache is unescaped
- return that.find(name, context);
- default: // escape the value
- return that.escape(that.find(name, context));
- }
- };
- var lines = template.split("\n");
- for(var i = 0; i < lines.length; i++) {
- lines[i] = lines[i].replace(regex, tag_replace_callback, this);
- if(!in_recursion) {
- this.send(lines[i]);
- }
- }
-
- if(in_recursion) {
- return lines.join("\n");
- }
- },
-
- set_delimiters: function(delimiters) {
- var dels = delimiters.split(" ");
- this.otag = this.escape_regex(dels[0]);
- this.ctag = this.escape_regex(dels[1]);
- },
-
- escape_regex: function(text) {
- // thank you Simon Willison
- if(!arguments.callee.sRE) {
- var specials = [
- '/', '.', '*', '+', '?', '|',
- '(', ')', '[', ']', '{', '}', '\\'
- ];
- arguments.callee.sRE = new RegExp(
- '(\\' + specials.join('|\\') + ')', 'g'
- );
- }
- return text.replace(arguments.callee.sRE, '\\$1');
- },
-
- /*
- find `name` in current `context`. That is find me a value
- from the view object
- */
- find: function(name, context) {
- name = this.trim(name);
-
- // Checks whether a value is thruthy or false or 0
- function is_kinda_truthy(bool) {
- return bool === false || bool === 0 || bool;
- }
-
- var value;
- if(is_kinda_truthy(context[name])) {
- value = context[name];
- } else if(is_kinda_truthy(this.context[name])) {
- value = this.context[name];
- }
-
- if(typeof value === "function") {
- return value.apply(context);
- }
- if(value !== undefined) {
- return value;
- }
- // silently ignore unkown variables
- return "";
- },
-
- // Utility methods
-
- /* includes tag */
- includes: function(needle, haystack) {
- return haystack.indexOf(this.otag + needle) != -1;
- },
-
- /*
- Does away with nasty characters
- */
- escape: function(s) {
- s = String(s === null ? "" : s);
- return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
- switch(s) {
- case "&": return "&";
- case "\\": return "\\\\";
- case '"': return '\"';
- case "<": return "<";
- case ">": return ">";
- default: return s;
- }
- });
- },
-
- // by @langalex, support for arrays of strings
- create_context: function(_context) {
- if(this.is_object(_context)) {
- return _context;
- } else {
- var iterator = ".";
- if(this.pragmas["IMPLICIT-ITERATOR"]) {
- iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
- }
- var ctx = {};
- ctx[iterator] = _context;
- return ctx;
- }
- },
-
- is_object: function(a) {
- return a && typeof a == "object";
- },
-
- is_array: function(a) {
- return Object.prototype.toString.call(a) === '[object Array]';
- },
-
- /*
- Gets rid of leading and trailing whitespace
- */
- trim: function(s) {
- return s.replace(/^\s*|\s*$/g, "");
- },
-
- /*
- Why, why, why? Because IE. Cry, cry cry.
- */
- map: function(array, fn) {
- if (typeof array.map == "function") {
- return array.map(fn);
- } else {
- var r = [];
- var l = array.length;
- for(var i = 0; i < l; i++) {
- r.push(fn(array[i]));
- }
- return r;
- }
- }
- };
-
- return({
- name: "mustache.js",
- version: "0.3.1-dev",
-
- /*
- Turns a template and view into HTML
- */
- to_html: function(template, view, partials, send_fun) {
- var renderer = new Renderer();
- if(send_fun) {
- renderer.send = send_fun;
- }
- renderer.render(template, view, partials);
- if(!send_fun) {
- return renderer.buffer.join("\n");
- }
- },
- escape : function(text) {
- return new Renderer().escape(text);
- }
- });
-}();
-
-exports.name = Mustache.name;
-exports.version = Mustache.version;
-
-exports.to_html = Mustache.to_html;
-exports.escape = Mustache.escape;
=== removed file 'couchapp/vendor/couchapp/lib/path.js'
--- couchapp/vendor/couchapp/lib/path.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/path.js 1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
-// from couch.js
-function encodeOptions(options) {
- var buf = [];
- if (typeof(options) == "object" && options !== null) {
- for (var name in options) {
- if (!options.hasOwnProperty(name)) {continue;}
- var value = options[name];
- if (name == "key" || name == "startkey" || name == "endkey") {
- value = JSON.stringify(value);
- }
- buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
- }
- }
- if (!buf.length) {
- return "";
- }
- return "?" + buf.join("&");
-}
-
-function concatArgs(array, args) {
- for (var i=0; i < args.length; i++) {
- array.push(args[i]);
- };
- return array;
-};
-
-function makePath(array) {
- var options, path;
-
- if (typeof array[array.length - 1] != "string") {
- // it's a params hash
- options = array.pop();
- }
- path = array.map(function(item) {return encodeURIComponent(item)}).join('/');
- if (options) {
- return path + encodeOptions(options);
- } else {
- return path;
- }
-};
-
-exports.init = function(req) {
- return {
- asset : function() {
- var p = req.path, parts = ['', p[0], p[1] , p[2]];
- return makePath(concatArgs(parts, arguments));
- },
- show : function() {
- var p = req.path, parts = ['', p[0], p[1] , p[2], '_show'];
- return makePath(concatArgs(parts, arguments));
- },
- list : function() {
- var p = req.path, parts = ['', p[0], p[1] , p[2], '_list'];
- return makePath(concatArgs(parts, arguments));
- },
- update : function() {
- var p = req.path, parts = ['', p[0], p[1] , p[2], '_update'];
- return makePath(concatArgs(parts, arguments));
- },
- limit : function(limit) {
- var query = req.query;
- var l = query.limit;
- query.limit = limit;
- var view = req.path[req.path.length - 1];
- var list = req.path[req.path.length - 2];
- var link = this.list(list, view, query);
- query.limit = l;
- return link;
- },
- older : function(key) {
- if (!typeof key == "undefined") return null;
- var query = req.query;
- query.startkey = key;
- query.skip=1;
- var view = req.path[req.path.length - 1];
- var list = req.path[req.path.length - 2];
- return this.list(list, view, query);
- },
- absolute : function(path) {
- return 'http://' + req.headers.Host + path;
- }
- }
-};
=== removed file 'couchapp/vendor/couchapp/lib/redirect.js'
--- couchapp/vendor/couchapp/lib/redirect.js 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/lib/redirect.js 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
-exports.permanent = function(redirect) {
- return {
- code : 301,
- headers : {
- "Location" : redirect
- }
- };
-};
\ No newline at end of file
=== removed file 'couchapp/vendor/couchapp/metadata.json'
--- couchapp/vendor/couchapp/metadata.json 2010-08-30 21:50:15 +0000
+++ couchapp/vendor/couchapp/metadata.json 1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
-{
- "name": "couchapp",
- "description": "official couchapp vendor",
- "fetch_uri": "git://github.com/couchapp/couchapp.git"
-}
\ No newline at end of file
=== removed directory 'couchapp/views'
=== removed directory 'couchapp/views/states'
=== removed file 'couchapp/views/states/map.py'
--- couchapp/views/states/map.py 2010-09-01 04:49:09 +0000
+++ couchapp/views/states/map.py 1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
-def fun(doc):
- if doc['states']:
- states = doc['states']
- newest_timestamp = sorted(states.values())[-1]
- current_state = filter(lambda k: states[k] == newest_timestamp,
- states.keys())[0]
- yield [current_state, doc['states'][current_state]], doc
=== removed directory 'couchapp/views/test-results'
=== removed file 'couchapp/views/test-results/map.py'
--- couchapp/views/test-results/map.py 2010-09-02 21:44:21 +0000
+++ couchapp/views/test-results/map.py 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-def fun(doc):
- import string
-
- if doc.has_key('iso_url') and doc.has_key('results'):
- iso_name = string.join(doc['iso_url'].split('/')[-2:],'-')
- test_name = doc['test_case']
- for name, result in doc['results'].iteritems():
- if result['returncode'] == 0:
- yield [iso_name, 'success', test_name], \
- doc['results'][test_name]
- else:
- yield [iso_name, 'failed', test_name], \
- doc['results'][test_name]
=== added directory 'debian'
=== added file 'debian/README'
--- debian/README 1970-01-01 00:00:00 +0000
+++ debian/README 2011-01-12 20:50:44 +0000
@@ -0,0 +1,6 @@
+The Debian Package ubuntu-server-iso-testing
+----------------------------
+
+Comments regarding the Package
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Wed, 01 Dec 2010 08:29:07 +0000
=== added file 'debian/changelog'
--- debian/changelog 1970-01-01 00:00:00 +0000
+++ debian/changelog 2011-01-12 20:50:44 +0000
@@ -0,0 +1,41 @@
+ubuntu-server-iso-testing (1.0~ppa20) lucid; urgency=low
+
+ * Updated packaging:
+ - Separated -server and -desktop packaging
+ - New -common package with shared component
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Wed, 12 Jan 2011 10:02:30 -0600
+
+ubuntu-server-iso-testing (1.0~ppa18) maverick; urgency=low
+
+ * Merged in desktop testing from jibel
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Mon, 10 Jan 2011 16:00:11 +0000
+
+ubuntu-server-iso-testing (1.0~ppa17) maverick; urgency=low
+
+ * Merged main trunk into my local branch
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Tue, 04 Jan 2011 16:07:04 +0000
+
+ubuntu-server-iso-testing (1.0~ppa16) maverick; urgency=low
+
+ * Added upstart configuration for hudson-slave
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Tue, 14 Dec 2010 09:21:56 +0000
+
+ubuntu-server-iso-testing (1.0~ppa15) maverick; urgency=low
+
+ * Added functionality to support use of APT proxy:
+ * APT_PROXY environment variable (if set) will
+ be used in debian preseed base.
+ * apt-cacher-ng now installed as dependency of
+ ubuntu-server-iso-testing package.
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Mon, 13 Dec 2010 14:01:44 +0000
+
+ubuntu-server-iso-testing (1.0~ppa14) lucid; urgency=low
+
+ * Initial Release.
+
+ -- James Page <james.page@xxxxxxxxxxxxx> Wed, 01 Dec 2010 08:29:07 +0000
=== added file 'debian/compat'
--- debian/compat 1970-01-01 00:00:00 +0000
+++ debian/compat 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+7
=== added file 'debian/control'
--- debian/control 1970-01-01 00:00:00 +0000
+++ debian/control 2011-01-12 20:50:44 +0000
@@ -0,0 +1,44 @@
+Source: ubuntu-server-iso-testing
+Section: misc
+Priority: extra
+Maintainer: Ubuntu Server ISO Testing Developers <ubuntu-server-iso-testing-dev@xxxxxxxxxxxxxxxxxxx>
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: https://launchpad.net/ubuntu-server-iso-testing
+
+Package: ubuntu-server-iso-testing
+Architecture: i386 amd64
+Depends: ${misc:Depends}, ${python:Depends}, ubuntu-iso-testing-common
+Description: Ubuntu Server ISO Testing framework
+ This package provides the Ubuntu Server ISO testing framework,
+ a python + libvirt/kvm based framework for automating the
+ testing of Ubuntu Server ISO images in-conjunction with a
+ Hudson continuous integration server.
+
+Package: hudson-slave
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}, python, python-setuptools,
+ default-jre-headless | java2-runtime-headless, adduser
+Description: Hudson slave base package
+ This package installs the required dependencies to operate
+ a Hudson slave machine and create a utility script and upstart
+ configuration to automatically start the slave on boot.
+
+Package: ubuntu-desktop-iso-testing
+Architecture: i386 amd64
+Depends: ${misc:Depends}, ${python:Depends}, ubuntu-iso-testing-common
+Description: Ubuntu Desktop ISO Testing framework
+ This package provides the Ubuntu Desktop ISO testing framework,
+ a python + libvirt/kvm based framework for automating the
+ testing of Ubuntu Desktop ISO images in-conjunction with a
+ Hudson continuous integration server.
+
+Package: ubuntu-iso-testing-common
+Architecture: i386 amd64
+Depends: ${misc:Depends}, ${python:Depends}, couchdb, curl, python-setuptools,
+ python, python-jinja2, python-couchdb, ubuntu-qa-tools, bsdtar,
+ dnsmasq, libvirt-bin, kvm, qemu-kvm, kvm-pxe,
+ adduser, curl, hudson-slave, apt-cacher-ng
+Description: Ubuntu ISO Testing framework - common components
+ This package provides the common components for both Desktop and Server
+ ISO testing frameworks.
=== added file 'debian/copyright'
--- debian/copyright 1970-01-01 00:00:00 +0000
+++ debian/copyright 2011-01-12 20:50:44 +0000
@@ -0,0 +1,81 @@
+This work was packaged for Debian by:
+
+ James Page <james.page@xxxxxxxxxxxxx> on Wed, 01 Dec 2010 08:29:07 +0000
+
+Upstream Author(s):
+
+ James Page <james.page@xxxxxxxxxxxxx>
+ Mathias Gug <mathiaz@xxxxxxxxxx>
+
+Copyright:
+
+ Copyright (C) 2010 Canonical Ltd (http://www.canonical.com)
+
+License:
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+On Debian systems, the complete text of the GNU General
+Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
+
+
+File: hudson.py
+
+Downloaded from:
+
+ https://code.ros.org/svn/ros/stacks/ros_release/trunk/hudson/src/hudson.py
+
+Upstream Author(s):
+
+ Ken Conoly (http://kwc.org)
+
+Copyright:
+
+ Copyright (c) 2010, Willow Garage, Inc.
+ All rights reserved.
+
+License:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Willow Garage, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+The Debian packaging is:
+
+ Copyright (C) 2010 Canonical Ltd (http://www.canonical.com)
+
+and is licensed under the GPL version 3, see above.
=== added file 'debian/dirs'
--- debian/dirs 1970-01-01 00:00:00 +0000
+++ debian/dirs 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+usr/share/ubuntu-server-iso-testing/templates
=== added file 'debian/docs'
--- debian/docs 1970-01-01 00:00:00 +0000
+++ debian/docs 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+docs/*
=== added file 'debian/hudson-slave.default'
--- debian/hudson-slave.default 1970-01-01 00:00:00 +0000
+++ debian/hudson-slave.default 2011-01-12 20:50:44 +0000
@@ -0,0 +1,12 @@
+# init configuration script for hudson-slave
+# User and Group to execute slave daemon asa
+# defaults to the ubuntu server iso testing
+# account as part of this package
+USER=usit
+GROUP=nogroup
+# URL to access Hudson Master Server
+HUDSON_MASTER=
+# Options to pass to hudson-slave
+# OPTS="-d"
+# Run at startup
+STARTUP=false
=== added file 'debian/hudson-slave.install'
--- debian/hudson-slave.install 1970-01-01 00:00:00 +0000
+++ debian/hudson-slave.install 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+hudson-slave.py usr/share/hudson-slave/python
=== added file 'debian/hudson-slave.links'
--- debian/hudson-slave.links 1970-01-01 00:00:00 +0000
+++ debian/hudson-slave.links 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+usr/share/hudson-slave/python/hudson-slave.py /usr/bin/hudson-slave
=== added file 'debian/hudson-slave.upstart'
--- debian/hudson-slave.upstart 1970-01-01 00:00:00 +0000
+++ debian/hudson-slave.upstart 2011-01-12 20:50:44 +0000
@@ -0,0 +1,28 @@
+# Hudson Slave
+
+description "hudson-slave: distributed job control"
+author "James Page <james.page@xxxxxxxxxxxxx>"
+
+start on (local-filesystems and net-device-up IFACE!=lo)
+stop on runlevel [!2345]
+
+pre-start script
+ . /etc/default/hudson-slave
+ test -x /usr/bin/hudson-slave || { stop ; exit 0; }
+ test -r /etc/default/hudson-slave || { stop ; exit 0; }
+ test "${STARTUP}" = "true" || { stop; exit 0; }
+end script
+
+script
+ . /etc/default/hudson-slave
+
+ JDK_DIRS="/usr/lib/jvm/java-6-openjdk /usr/lib/jvm/java-6-sun"
+ for jdir in $JDK_DIRS; do
+ if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
+ JAVA_HOME="$jdir"
+ fi
+ done
+ export JAVA_HOME
+
+ exec start-stop-daemon --start --chuid $USER:$GROUP --exec /usr/bin/hudson-slave -- $OPTS $HUDSON_MASTER
+end script
=== added file 'debian/install'
--- debian/install 1970-01-01 00:00:00 +0000
+++ debian/install 2011-01-12 20:50:44 +0000
@@ -0,0 +1,3 @@
+templates/* usr/share/ubuntu-server-iso-testing/templates
+
+
=== added file 'debian/rules'
--- debian/rules 1970-01-01 00:00:00 +0000
+++ debian/rules 2011-01-12 20:50:44 +0000
@@ -0,0 +1,6 @@
+#!/usr/bin/make -f
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
=== added directory 'debian/source'
=== added file 'debian/source/format'
--- debian/source/format 1970-01-01 00:00:00 +0000
+++ debian/source/format 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+3.0 (native)
=== added file 'debian/ubuntu-desktop-iso-testing.dirs'
--- debian/ubuntu-desktop-iso-testing.dirs 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-desktop-iso-testing.dirs 2011-01-12 20:50:44 +0000
@@ -0,0 +1,1 @@
+usr/share/ubuntu-server-iso-testing/templates.desktop
=== added file 'debian/ubuntu-desktop-iso-testing.install'
--- debian/ubuntu-desktop-iso-testing.install 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-desktop-iso-testing.install 2011-01-12 20:50:44 +0000
@@ -0,0 +1,2 @@
+templates.desktop/* usr/share/ubuntu-server-iso-testing/templates.desktop
+
=== added file 'debian/ubuntu-iso-testing-common.dirs'
--- debian/ubuntu-iso-testing-common.dirs 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-iso-testing-common.dirs 2011-01-12 20:50:44 +0000
@@ -0,0 +1,5 @@
+usr/bin
+usr/share/ubuntu-server-iso-testing
+var/lib/ubuntu-server-iso-testing
+var/lib/ubuntu-server-iso-testing/dnsmasq.d
+var/log/ubuntu-server-iso-testing
=== added file 'debian/ubuntu-iso-testing-common.install'
--- debian/ubuntu-iso-testing-common.install 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-iso-testing-common.install 2011-01-12 20:50:44 +0000
@@ -0,0 +1,15 @@
+run-test.py usr/share/ubuntu-server-iso-testing/python
+download-latest-test-iso.py usr/share/ubuntu-server-iso-testing/python
+setup-hudson.py usr/share/ubuntu-server-iso-testing/python
+# Install TFTP configuration for dnsmasq.d
+templates/tftp-iso-testing.conf etc/dnsmasq.d
+# Install replacement libvirt configuration for dnsmasq.d
+templates/libvirtd-iso-testing.conf etc/dnsmasq.d
+# Install replacement libvirt configuration for dnsmasq.d
+templates/dnsmasq-iso-testing.conf etc/dnsmasq.d
+# Install sudo configuration for usit
+templates/usit-dnsmasq etc/sudoers.d
+# Install couchdb configuration
+templates/iso-testing.ini etc/couchdb/local.d
+# Install rc.local to fix dnsmasq/libvirtd-bin conflict
+templates/rc.local etc
=== added file 'debian/ubuntu-iso-testing-common.links'
--- debian/ubuntu-iso-testing-common.links 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-iso-testing-common.links 2011-01-12 20:50:44 +0000
@@ -0,0 +1,4 @@
+usr/share/ubuntu-server-iso-testing/python/run-test.py /usr/bin/run-test
+usr/share/ubuntu-server-iso-testing/python/download-latest-test-iso.py /usr/bin/download-latest-test-iso
+usr/share/ubuntu-server-iso-testing/python/setup-hudson.py /usr/bin/setup-hudson
+
=== added file 'debian/ubuntu-iso-testing-common.postinst'
--- debian/ubuntu-iso-testing-common.postinst 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-iso-testing-common.postinst 2011-01-12 20:50:44 +0000
@@ -0,0 +1,81 @@
+#!/bin/sh
+# postinst script for ubuntu-server-iso-testing
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+case "$1" in
+ configure)
+ # Create usit user if it doesn't exist.
+ if ! id usit > /dev/null 2>&1 ; then
+ adduser --system --home /var/lib/ubuntu-server-iso-testing --no-create-home \
+ --ingroup nogroup --disabled-password --quiet --shell /bin/bash \
+ usit || true
+ # Add usit to libvirtd as required access to vm management
+ adduser --quiet usit libvirtd || true
+ fi
+ # Fix permissions on runtime directories/files.
+ # This is copied direct from the Hudson debian package
+ # and relates to edge cases on dir perms for ssh key authentication
+ # change group/owner to usit:adm - exclude jobs directory.
+ find /var/lib/ubuntu-server-iso-testing -path "*jobs" -prune -o -exec chown usit:adm {} + || true
+ # /var/run/ubuntu-server-iso-testing
+ chown -R usit:adm /var/log/ubuntu-server-iso-testing || true
+ # change mode to 755 - exclude jobs and .ssh directories.
+ find /var/lib/ubuntu-server-iso-testing -path "*jobs" -prune -o -path "*.ssh" -prune -o -exec chmod 755 {} + || true
+ # chmod -R 755 /var/run/ubuntu-server-iso-testing || true
+ chmod 755 /var/log/ubuntu-server-iso-testing || true
+
+ # Fix perms on /etc/sudoers.d/usit-dnsmasq so sudo does not break
+ chmod 0440 /etc/sudoers.d/usit-dnsmasq || true
+
+ # Kill any existing dnsmasq (from libvirt-bin)
+ # Required due to conflict between libvirt and dnsmasq
+ pkill dnsmasq || true
+
+ # Restart dnsmasq and couchdb to pickup new settings
+ if [ -x /etc/init.d/dnsmasq ]; then
+ if [ -x /usr/sbin/invoke-rc.d ]; then
+ invoke-rc.d dnsmasq restart || true
+ else
+ /etc/init.d/dnsmasq restart || true
+ fi
+ fi
+ if [ -x /etc/init.d/couchdb ]; then
+ if [ -x /usr/sbin/invoke-rc.d ]; then
+ invoke-rc.d couchdb restart || true
+ else
+ /etc/init.d/couchdb restart || true
+ fi
+ fi
+
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
=== added file 'debian/ubuntu-iso-testing-common.postrm'
--- debian/ubuntu-iso-testing-common.postrm 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-iso-testing-common.postrm 2011-01-12 20:50:44 +0000
@@ -0,0 +1,43 @@
+#!/bin/sh
+# postrm script for ubuntu-server-iso-testing
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postrm> `remove'
+# * <postrm> `purge'
+# * <old-postrm> `upgrade' <new-version>
+# * <new-postrm> `failed-upgrade' <old-version>
+# * <new-postrm> `abort-install'
+# * <new-postrm> `abort-install' <old-version>
+# * <new-postrm> `abort-upgrade' <old-version>
+# * <disappearer's-postrm> `disappear' <overwriter>
+# <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ purge)
+ # Remove usit user
+ userdel usit || true
+ # Remove log files
+ rm -Rf /var/log/ubuntu-server-iso-testing || true
+ ;;
+ remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+ ;;
+
+ *)
+ echo "postrm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
=== added file 'debian/ubuntu-server-iso-testing.doc-base'
--- debian/ubuntu-server-iso-testing.doc-base 1970-01-01 00:00:00 +0000
+++ debian/ubuntu-server-iso-testing.doc-base 2011-01-12 20:50:44 +0000
@@ -0,0 +1,9 @@
+Document: ubuntu-server-iso-testing
+Title: Debian ubuntu-server-iso-testing Manual
+Author: James Page
+Abstract: This manual describes what ubuntu-server-iso-testing is
+ and how it can be used to to automate Ubuntu Server ISO testing.
+Section: Debian
+
+Format: text
+Files: /usr/share/doc/ubuntu-server-iso-testing/README.gz
=== removed directory 'deprecated'
=== removed file 'deprecated/configure_and_run_test.py'
--- deprecated/configure_and_run_test.py 2010-09-30 09:26:18 +0000
+++ deprecated/configure_and_run_test.py 1970-01-01 00:00:00 +0000
@@ -1,200 +0,0 @@
-#!/usr/bin/python
-
-import datetime
-import json
-import logging
-import os, os.path
-import shutil
-import subprocess
-import sys
-import urllib
-import urlparse
-import time
-
-import couchdb
-import jinja2
-
-logging.basicConfig(level=logging.DEBUG)
-
-TMPL_DIR = os.environ.get("TMPL_DIR",
- os.path.expanduser("~/reference/iso-testing/templates/"))
-
-DNSMASQ_DIR = os.environ.get("DNSMASQ_DIR", "/etc/dnsmasq.d")
-TEST_DIR = os.environ.get("TEST_DIR",
- os.path.expanduser("~/reference/iso-testing/tests"))
-ISO_DIR = os.environ.get("ISO_DIR",
- os.path.expanduser("~/reference/isos"))
-
-TEST_TRACKER = os.environ.get("TEST_TRACKER", "http://testracker:5984")
-TEST_DATABASE = os.environ.get("TEST_DATABASE", "tests")
-
-TEST_RESULTS = os.environ.get("TEST_RESULTS","test-results")
-
-server = couchdb.client.Server(TEST_TRACKER)
-db = server[TEST_DATABASE]
-
-# Load the templates
-templates = jinja2.Environment(loader = jinja2.FileSystemLoader(TMPL_DIR))
-
-if not os.path.exists(TEST_DIR):
- os.makedirs(TEST_DIR)
-
-if not os.path.exists(ISO_DIR):
- os.makedirs(ISO_DIR)
-
-if not os.path.exists(TEST_RESULTS):
- os.makedirs(TEST_RESULTS)
-
-logging.debug("Loading test case to run")
-# Grab the next test case to run
-while True:
- url_h = urllib.urlopen("%s/%s/_design/couchapp/_view/states?" \
- % (TEST_TRACKER, TEST_DATABASE) \
- + "startkey=[\"created\",\"\"]" \
- + "&endkey=[\"created\",\"Z\"]")
- results = json.load(url_h)
- logging.debug("Results: %s" % (results))
-
- if len(results['rows']) == 0:
- logging.info("Nothing to configure")
- sys.exit(0)
- else:
- logging.debug("Selecting oldest test case")
- test = results['rows'][0]["value"]
- test['states']['configuring'] = datetime.datetime.utcnow().isoformat()
- try:
- db[test['_id']]= test
- # The update worked - we've grabbed the test case to run
- break
- except couchdb.client.ResourceConflict, e:
- # The test may have been grabbed by someone else
- # Get an update list of test case to run
- pass
-
-logging.info("Configuring test case: %s" % (test['_id']))
-test_dir = os.path.join(TEST_DIR, test['_id'])
-os.mkdir(test_dir)
-
-logging.debug("Retrieving iso file")
-iso_url = test["iso_url"]
-u = urlparse.urlparse(iso_url)
-iso_file = os.path.join(ISO_DIR, u.netloc, u.path[1:])
-if not os.path.exists(iso_file):
- if not os.path.exists(os.path.dirname(iso_file)):
- os.makedirs(os.path.dirname(iso_file))
- logging.info("Retrieving iso file from url %s" % (iso_url))
- urllib.urlretrieve(iso_url, iso_file)
-else:
- logging.debug("Iso file already cached at %s" % (iso_file))
-
-logging.debug("Generating disks")
-disks = test['disks']
-for disk in disks:
- root_disk = os.path.join(test_dir, "disk%s.%s" % (disks.index(disk)+1,
- disk['format']))
- cmd = [ 'qemu-img', 'create', '-f', disk['format'], root_disk,
- disk['size'] ]
- logging.debug("Cmd: %s" % (cmd))
- subprocess.check_call(cmd)
- shutil.copy(root_disk, root_disk + ".orig")
- disk['source'] = root_disk
-
-logging.debug("Generating libvirt configuration")
-ctxt = { 'name': test['_id'],
- 'uuid': test['_id'],
- 'disks': disks,
- 'iso_file': iso_file,
- 'mac': test['mac'],
- }
-logging.debug("Context: %s" % (ctxt))
-libvirt_file = os.path.join(test_dir, 'libvirt.xml')
-tmpl = templates.get_template('libvirt.xml')
-tmpl.stream(ctxt).dump(libvirt_file)
-cmd = [ "virsh", "define", libvirt_file]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-test_case_doc = db[test['_id']]
-db.put_attachment(test_case_doc, open(libvirt_file), "libvirt.xml")
-
-logging.debug("Updating dnsmasq configuration for %s" % (test['_id']))
-tmpl = templates.get_template('dnsmasq.conf')
-ctxt = { 'mac': test['mac'],
- 'test_tracker': TEST_TRACKER,
- 'test_db': TEST_DATABASE,
- 'uuid': test['_id'],
- }
-logging.debug("Context: %s" % (ctxt))
-dnsmasq_conf_file = os.path.join(DNSMASQ_DIR, "%s.conf" % (test['_id']))
-tmpl.stream(ctxt).dump(dnsmasq_conf_file)
-cmd = [ "sudo", "/usr/sbin/service", "dnsmasq", "restart"]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-test_case_doc = db[test['_id']]
-db.put_attachment(test_case_doc, open(dnsmasq_conf_file), "dnsmasq.conf")
-
-test = db[test['_id']]
-test['states']['configured'] = datetime.datetime.utcnow().isoformat()
-db[test['_id']] = test
-
-logging.debug("Starting test case %s" % (test['_id']))
-cmd = [ "virsh", "start", test['_id']]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-
-test = db[test['_id']]
-test['states']['started'] = datetime.datetime.utcnow().isoformat()
-db[test['_id']] = test
-
-
-# Monitor the state of the virtual machine to determine
-# completion of execution of test scripts
-while True:
- logging.debug("Checking VM state for test case %s" % test['_id'])
- cmd = [ "virsh", "domstate", test['_id']]
- logging.debug("Cmd: %s" % (cmd))
- # Execute Process, capturing return code and output
- l_proc = subprocess.Popen(cmd, bufsize=2048, stdout=subprocess.PIPE)
- l_retcode = l_proc.wait()
- l_output = l_proc.communicate()[0].strip()
- logging.debug(l_output)
-
- if l_retcode == 0 and l_output == "shut off":
- logging.debug("VM powered off for test case %s" % test['_id'])
- break
- else:
- # Have another look in XX seconds
- time.sleep(30)
-
-# Retrieve latest copy of data
-test = db[test['_id']]
-if test['states'].has_key('tested'):
- # Testing appears to have completed
- # Retrieve log output an place in hudson workspace
- logging.debug("Tests completed for test case %s" % test['_id'])
-
- # Create the output directory to store results
- test_results_dir = os.path.join(TEST_RESULTS , test['_id'])
- if not os.path.exists(test_results_dir):
- os.makedirs(test_results_dir)
-
- # Iterate over all test results
- test_results = test['results']
- for test_result in test_results:
- test_results_file = os.path.join(test_results_dir, "TEST-%s.stderr" % test_result)
- f = open (test_results_file, 'w')
- f.write(test['results'][test_result]['script_stderr'])
- f.close()
- test_results_file = os.path.join(test_results_dir, "TEST-%s.stdout" % test_result)
- f = open (test_results_file, 'w')
- f.write(test['results'][test_result]['script_stdout'])
- f.close()
-
- # Bang out all attachements
-
-else:
- logging.debug("VM for test case %s powered off but tests not completed" % test['_id'])
- sys.exit(1)
-
-
-
-
=== removed file 'deprecated/configure_and_run_test_by_uuid.py'
--- deprecated/configure_and_run_test_by_uuid.py 2010-09-30 09:26:18 +0000
+++ deprecated/configure_and_run_test_by_uuid.py 1970-01-01 00:00:00 +0000
@@ -1,254 +0,0 @@
-#!/usr/bin/python
-
-import datetime
-import json
-import logging
-import os, os.path
-import shutil
-import subprocess
-import sys
-import urllib
-import urlparse
-import time
-import optparse
-
-import couchdb
-import jinja2
-
-# Get all environment variable for general test configuration
-TMPL_DIR = os.environ.get("TMPL_DIR",
- os.path.expanduser("~/reference/iso-testing/templates/"))
-
-DNSMASQ_DIR = os.environ.get("DNSMASQ_DIR", "/etc/dnsmasq.d")
-
-TEST_DIR = os.environ.get("TEST_DIR",
- os.path.expanduser("~/reference/iso-testing/tests"))
-ISO_DIR = os.environ.get("ISO_DIR",
- os.path.expanduser("~/reference/isos"))
-
-TEST_TRACKER = os.environ.get("TEST_TRACKER", "http://192.168.122.112:5984")
-TEST_DATABASE = os.environ.get("TEST_DATABASE", "tests")
-
-TEST_RESULTS = os.environ.get("TEST_RESULTS","test-results")
-
-# URL of Hudson CI Server
-HUDSON_URL = os.environ.get("HUDSON_URL", "")
-BUILD_NUMBER = os.environ.get("BUILD_NUMBER", "")
-
-# Default time to sleep for monitoring VM execution
-SLEEP_TIME = 30
-TEST_TIMEOUT = 1200
-
-usage="usage: %prog [options] testcase-UUID"
-parser = optparse.OptionParser(usage=usage)
-parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False,
- help="Enable debugging")
-(options, args) = parser.parse_args()
-
-if len(args) == 0:
- logging.error("Need a test case UUID to execute")
- parser.print_help()
- sys.exit(1)
-
-# Setup debug if required
-if options.debug:
- logging.basicConfig(level=logging.DEBUG)
-else:
- logging.basicConfig(level=logging.INFO)
-
-logging.debug("Options: %s" % (options))
-logging.debug("Arguments: %s" % (args))
-
-# UUID of test case which we are about to execute
-TEST_CASE = args[0]
-
-# Grab a connection to the database
-server = couchdb.client.Server(TEST_TRACKER)
-db = server[TEST_DATABASE]
-
-# Load the templates
-templates = jinja2.Environment(loader = jinja2.FileSystemLoader(TMPL_DIR))
-
-if not os.path.exists(TEST_DIR):
- os.makedirs(TEST_DIR)
-
-if not os.path.exists(ISO_DIR):
- os.makedirs(ISO_DIR)
-
-logging.debug("Loading test case to run")
-test = db[TEST_CASE]
-logging.info("Configuring test case: %s" % (test['_id']))
-test_dir = os.path.join(TEST_DIR, test['_id'])
-os.mkdir(test_dir)
-
-logging.debug("Retrieving iso file")
-iso_file = test["iso_url"]
-
-logging.debug("Generating disks")
-disks = test['disks']
-for disk in disks:
- root_disk = os.path.join(test_dir, "disk%s.%s" % (disks.index(disk)+1,
- disk['format']))
- cmd = [ 'qemu-img', 'create', '-f', disk['format'], root_disk,
- disk['size'] ]
- logging.debug("Cmd: %s" % (cmd))
- subprocess.check_call(cmd)
- shutil.copy(root_disk, root_disk + ".orig")
- disk['source'] = root_disk
-
-logging.debug("Generating libvirt configuration")
-ctxt = { 'name': test['_id'],
- 'uuid': test['_id'],
- 'disks': disks,
- 'iso_file': iso_file,
- 'mac': test['mac'],
- }
-logging.debug("Context: %s" % (ctxt))
-libvirt_file = os.path.join(test_dir, 'libvirt.xml')
-tmpl = templates.get_template('libvirt.xml')
-tmpl.stream(ctxt).dump(libvirt_file)
-cmd = [ "virsh", "define", libvirt_file]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-test_case_doc = db[test['_id']]
-db.put_attachment(test_case_doc, open(libvirt_file), "libvirt.xml")
-
-logging.debug("Updating dnsmasq configuration for %s" % (test['_id']))
-tmpl = templates.get_template('dnsmasq.conf')
-ctxt = { 'mac': test['mac'],
- 'test_tracker': TEST_TRACKER,
- 'test_db': TEST_DATABASE,
- 'uuid': test['_id'],
- }
-logging.debug("Context: %s" % (ctxt))
-dnsmasq_conf_file = os.path.join(DNSMASQ_DIR, "%s.conf" % (test['_id']))
-tmpl.stream(ctxt).dump(dnsmasq_conf_file)
-cmd = [ "sudo", "/usr/sbin/service", "dnsmasq", "restart"]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-test_case_doc = db[test['_id']]
-db.put_attachment(test_case_doc, open(dnsmasq_conf_file), "dnsmasq.conf")
-
-test = db[test['_id']]
-test['states']['configured'] = datetime.datetime.utcnow().isoformat()
-db[test['_id']] = test
-
-logging.debug("Starting test case %s" % (test['_id']))
-cmd = [ "virsh", "start", test['_id']]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-
-test = db[test['_id']]
-test['states']['started'] = datetime.datetime.utcnow().isoformat()
-db[test['_id']] = test
-
-
-# Monitor the state of the virtual machine to determine
-# completion of execution of test scripts
-l_timeout = TEST_TIMEOUT
-while True:
- logging.debug("Checking VM state for test case %s" % test['_id'])
- cmd = [ "virsh", "domstate", test['_id']]
- logging.debug("Cmd: %s" % (cmd))
- # Execute Process, capturing return code and output
- l_proc = subprocess.Popen(cmd, bufsize=2048, stdout=subprocess.PIPE)
- l_retcode = l_proc.wait()
- l_output = l_proc.communicate()[0].strip()
- logging.debug(l_output)
-
- if l_retcode == 0 and l_output == "shut off":
- logging.debug("VM powered off for test case %s" % test['_id'])
- break
- elif l_timeout <= 0:
- logging.debug("Test %s failed to execute within %d minutes" % (test['_id'], TEST_TIMEOUT / 60))
- logging.debug("Terminating test case %s" % (test['_id']))
- cmd = [ "virsh", "destroy", test['_id']]
- logging.debug("Cmd: %s" % (cmd))
- subprocess.check_call(cmd)
- break
- else:
- # Have another look in SLEEP_TIME seconds
- time.sleep(SLEEP_TIME)
- # Decrement the timeout
- l_timeout = l_timeout - SLEEP_TIME
-
-# Retrieve latest copy of data
-test = db[test['_id']]
-# Flag to indicate if tests successfully executed
-test_completed = False
-
-if test['states'].has_key('tested'):
- # Testing appears to have completed - VM ran and run_tests
- # execute and wrote to CouchDB
- # Retrieve log output an place in hudson workspace
- logging.debug("Tests completed for test case %s" % test['_id'])
-
- testresultsdir = os.path.join(BUILD_NUMBER, TEST_RESULTS)
- # Create the output directory to store results
- if not os.path.exists(testresultsdir):
- os.makedirs(testresultsdir)
-
- # Iterate over all test results as tests completed OK
- test_results = test['results']
- for test_result in test_results:
- test_results_file = os.path.join(testresultsdir, "%s.stderr" % test_result)
- f = open (test_results_file, 'w')
- f.write(test['results'][test_result]['script_stderr'])
- f.close()
- test_results_file = os.path.join(testresultsdir, "TEST-%s.xml" % test_result)
- f = open (test_results_file, 'w')
- f.write(test['results'][test_result]['script_stdout'])
- f.close()
-
- test_completed = True
-else:
- logging.debug("VM for test case %s powered off but tests not completed" % test['_id'])
-
-# Undefine and delete the Virtual Machine
-logging.debug("Undefine VM for test case %s" % (test['_id']))
-cmd = [ "virsh", "undefine", test['_id']]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-# Remove VM config and disks - no longer required
-shutil.rmtree(os.path.join(TEST_DIR, test['_id']))
-
-# Remove dnsmasq configuration and restart dnsmasq
-logging.debug("Removing dnsmasq configuration for %s" % (test['_id']))
-os.remove(dnsmasq_conf_file )
-cmd = [ "sudo", "/usr/sbin/service", "dnsmasq", "restart"]
-logging.debug("Cmd: %s" % (cmd))
-subprocess.check_call(cmd)
-
-# Running under Hudson?
-if HUDSON_URL:
- logging.debug("Collating output for test case %s" % (test['_id']))
- # Test output is located in a directory associated with the
- # Hudson build number
- testoutputdir= os.path.join(os.getcwd(), BUILD_NUMBER)
- if not os.path.exists(testoutputdir):
- os.makedirs(testoutputdir)
- l_cwd = os.getcwd()
- # Change to testoutput directory
- os.chdir(testoutputdir)
- # Collate attachements into workspace
- for a in test['_attachments']:
- # Retrieve attachement to CWD
- content = db.get_attachment(test, a)
- # Check to see if directory needs to be created
- dir = os.path.dirname(a)
- if dir and not os.path.exists(dir):
- os.makedirs(dir)
- # Write out the attachment
- tgt = open(a, 'w')
- tgt.write(content)
- tgt.close()
- # Move back to old working directory
- os.chdir(l_cwd)
-
-# Determine if testing failed and return exit status 1 if not executed
-if not test_completed:
- sys.exit(1)
-
-
-
-
=== removed file 'deprecated/setup_hudson.py'
--- deprecated/setup_hudson.py 2010-09-30 09:38:15 +0000
+++ deprecated/setup_hudson.py 1970-01-01 00:00:00 +0000
@@ -1,94 +0,0 @@
-#!/usr/bin/python
-
-import logging
-import glob
-import optparse
-import os
-import sys
-import urlparse
-
-import jinja2
-
-import hudson
-
-hudson_jobs= ["iso-testing-initiator"]
-TMPL_DIR="templates"
-TEST_CASE_DIR="templates/test_cases"
-DEFAULT_VARIANT = 'server'
-DEFAULT_RELEASE = 'maverick'
-DEFAULT_COUCHDB = 'http://192.168.122.1:5984'
-ARCHS= ['i386', 'amd64']
-
-usage="usage: %prog [options] HUDSON_URL"
-parser = optparse.OptionParser(usage=usage)
-parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False,
- help="Enable debugging")
-parser.add_option("-r", "--release", dest="release", default=DEFAULT_RELEASE,
- help="release of Ubuntu to download (default=%s)" % DEFAULT_RELEASE)
-parser.add_option("-v", "--variant", dest="variant", default=DEFAULT_VARIANT,
- help="variant of Ubuntu to download (default=%s)" % DEFAULT_VARIANT)
-parser.add_option("-c", "--couchdb", dest="couchdb", default=DEFAULT_COUCHDB,
- help="Location of couchdb to use for testing (default=%s)" % DEFAULT_COUCHDB)
-(options, args) = parser.parse_args()
-
-if options.debug:
- logging.basicConfig(level=logging.DEBUG)
-else:
- logging.basicConfig(level=logging.INFO)
-
-logging.debug("Options: %s" % (options))
-logging.debug("Arguments: %s" % (args))
-
-if len(args) == 0:
- parser.print_help()
- sys.exit(1)
-
-# Load the templates
-templates = jinja2.Environment(loader = jinja2.FileSystemLoader(TMPL_DIR))
-
-# Parse hudson url for username and password
-# http://username:password@hostname:port/
-url = urlparse.urlsplit(args[0])
-username = url.username
-password = url.password
-url2 = "http://%s:%s/" % (url.hostname, url.port)
-logging.debug("Hudson full url: %s" % (url.geturl()))
-logging.debug("Hudson url: %s" % (url2))
-logging.debug("Hudson username: %s" % (username))
-logging.debug("Hudson password: %s" % (password))
-l_hud = hudson.Hudson(url2, username, password)
-
-# Create default hudson jobs (may be deprecated)
-for l_jobname in hudson_jobs:
- logging.info("Creating Hudson Job %s " % l_jobname)
- # Readin config.xml for posting to Hudson
- f = open(os.path.join(TMPL_DIR, '%s-config.xml' % l_jobname ))
- config = f.read()
- f.close()
- if not l_hud.job_exists(l_jobname):
- l_hud.create_job(l_jobname, config)
- else:
- l_hud.reconfig_job(l_jobname,config)
-
-# Grab a list of preseeds
-preseeds = glob.glob(os.path.join(TEST_CASE_DIR, "*"))
-
-for p in preseeds:
- for a in ARCHS:
- preseed = os.path.basename(os.path.normpath(p))
-
- ctxt = { 'release': options.release,
- 'variant': options.variant,
- 'arch': a,
- 'preseed':preseed,
- 'couchdburl': options.couchdb
- }
- tmpl = templates.get_template('preseed-config.xml')
- config = tmpl.render(ctxt)
-
- l_jobname = options.release + '-' + options.variant + '-' + a + '_' + preseed
- if not l_hud.job_exists(l_jobname):
- l_hud.create_job(l_jobname, config)
- else:
- l_hud.reconfig_job(l_jobname, config)
-
=== removed file 'deprecated/setup_iso_test.py'
--- deprecated/setup_iso_test.py 2010-09-30 09:26:18 +0000
+++ deprecated/setup_iso_test.py 1970-01-01 00:00:00 +0000
@@ -1,266 +0,0 @@
-#!/usr/bin/python
-
-import datetime
-import glob
-import logging
-import optparse
-import os.path
-import pipes
-import random
-import shutil
-import string
-import subprocess
-import sys
-import tempfile
-import uuid
-import urllib
-import hudson
-
-import couchdb
-import jinja2
-
-logging.basicConfig(level=logging.DEBUG)
-
-# Get all environment variable for general test configuration
-TMPL_DIR = os.environ.get("TMPL_DIR",
- os.path.expanduser("~/reference/iso-testing/templates/"))
-RUN_TEST = os.path.join(TMPL_DIR, 'run_test')
-TEST_CASE_DIR = os.path.join(TMPL_DIR, 'test_cases')
-PRESEED_TMPL_DIR = [os.path.join(TMPL_DIR, 'preseeds-common'), TEST_CASE_DIR]
-DNSMASQ_DIR = os.environ.get("DNSMASQ_DIR", "/etc/dnsmasq.d")
-TEST_DIR = os.environ.get("TEST_DIR",
- os.path.expanduser("~/reference/iso-testing/tests"))
-TEST_TRACKER = os.environ.get("TEST_TRACKER", "http://192.168.122.112:5984")
-TEST_DATABASE = os.environ.get("TEST_DATABASE", "tests")
-
-# Check for Hudson URL - set automatically by Hudson.
-HUDSON_URL = os.environ.get("HUDSON_URL","")
-# Get all of the environment variables set by Hudson
-ISO_DIR=os.environ.get("ISO_DIR", "")
-RELEASE = os.environ.get("RELEASE", "")
-VARIANT = os.environ.get("VARIANT", "")
-BUILD_VERSION = os.environ.get("BUILD_VERSION", "")
-
-
-DISK_FORMAT = "qcow2"
-DISK_BUS = "virtio"
-DISK_SIZE = "2G"
-DISK_NUMBER = 1
-
-usage="usage: %prog [options] ISO_DIR|ISO_FILE [preseed1 preseed2 ...]"
-parser = optparse.OptionParser(usage=usage)
-(options, args) = parser.parse_args()
-
-logging.debug("Options: %s" % (options))
-logging.debug("Arguments: %s" % (args))
-
-if len(args) == 0:
- logging.error("Need at least iso directory or iso file")
- parser.print_help()
- sys.exit(1)
-
-if not os.path.exists(args[0]):
- logging.error("Unknow iso directory|file %s" % (args[0]))
- sys.exit(1)
-
-logging.debug("Getting the list of isos to process from %s" % (args[0]))
-isos = None
-if os.path.isdir(args[0]):
- logging.debug("Getting list of isos from directory %s" % (args[0]))
- isos = glob.glob(os.path.join(args[0], "*.iso"))
-elif os.path.isfile(args[0]):
- isos = [ args[0] ]
-if isos:
- logging.info("List of isos: %s" % isos)
-else:
- logging.warning("Unable to get list of isos from %s" % (args[0]))
- sys.exit(1)
-
-logging.debug("Getting the list of preseed to process")
-preseeds = None
-if len(args) >= 2:
- preseeds = args[1:]
-else:
- logging.debug("Getting list of preseed from template directory %s"\
- % (TEST_CASE_DIR))
- if not os.path.exists(TEST_CASE_DIR):
- logging.warning("Unkonwn preseed template directory %s"\
- % (TEST_CASE_DIR))
- sys.exit(1)
- preseeds = glob.glob(os.path.join(TEST_CASE_DIR, "*"))
-if preseeds:
- logging.info("List of preseeds: %s" % (preseeds))
-else:
- logging.warning("Unable to get list of preseeds")
- sys.exit(1)
-
-# See http://kennethreitz.com/blog/generate-a-random-mac-address-in-python/
-def random_mac_address():
- """Returns a completely random Mac Address"""
- mac = [0x52, 0x54, 0x00, random.randint(0x00, 0xff),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff)]
- return ':'.join(map(lambda x: "%02x" % x, mac))
-
-# Load the templates
-templates = jinja2.Environment(loader = jinja2.FileSystemLoader(TMPL_DIR))
-
-# Load the preseed templates
-preseed_templates = \
- jinja2.Environment(loader = jinja2.FileSystemLoader(PRESEED_TMPL_DIR))
-
-if not os.path.exists(TEST_DIR):
- os.makedirs(TEST_DIR)
-
-server = couchdb.client.Server(TEST_TRACKER)
-db = server[TEST_DATABASE]
-
-for i in isos:
- logging.info("Extracting kernel and initrd from %s" % (i))
- iso_tmp_dir = tempfile.mkdtemp(prefix="%s-" % (os.path.basename(i)))
- kernel = os.path.join(iso_tmp_dir, "install", 'vmlinuz')
- initrd = os.path.join(iso_tmp_dir, "install", "initrd.gz")
- cmd = ['bsdtar', '-xf', i, '-C', iso_tmp_dir,
- "install/vmlinuz", "install/initrd.gz"]
- logging.debug("Cmd: %s" % (cmd))
- subprocess.check_call(cmd)
-
-
- for p in preseeds:
- t_preseed = os.path.basename(os.path.normpath(p))
- logging.info("Generating %s configuration" % (t_preseed))
-
- old_wd = os.getcwd()
- test_uuid = str(uuid.uuid4())
- db[test_uuid] = { "test_case": t_preseed,
- "states": {
- 'creating': datetime.datetime.utcnow().isoformat()
- }
- }
- test_tmp_dir = tempfile.mkdtemp(prefix="%s-" % (t_preseed),
- dir=iso_tmp_dir)
- initrd_tmp_dir = tempfile.mkdtemp(prefix='initrd-', dir=test_tmp_dir)
- t_initrd = os.path.join(test_tmp_dir, 'initrd.gz')
-
- logging.debug("Generate preseed file")
- tmpl = preseed_templates.get_template("%s/preseed" % (t_preseed))
- ctxt = { 'hostname': test_uuid,
- 'test_case_url': "%s/%s/%s" % (TEST_TRACKER, TEST_DATABASE,
- test_uuid)}
- preseed_file = os.path.join(test_tmp_dir, 'preseed')
- tmpl.stream(ctxt).dump(preseed_file)
-
- logging.info("Uncompressing initrd")
- logging.debug("Initrd file: %s" % (initrd))
- os.chdir(initrd_tmp_dir)
- t = pipes.Template()
- t.prepend("zcat $IN", "f-")
- t.append("cpio -ivd 2>/dev/null", "-.")
- t.copy(initrd, '/dev/null')
-
- logging.debug("Copying preseed to initrd and test case document")
- shutil.copy(preseed_file, os.path.join(initrd_tmp_dir, 'preseed'))
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc, open(preseed_file), "preseed")
-
- logging.info("Copying run_test")
- # Put run_test in the initrd so that the installer can copy it
- # into the target system at late_command time
- shutil.copy(RUN_TEST, os.path.join(initrd_tmp_dir, 'run_test'))
- # Keep a copy in test case doc
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc, open(RUN_TEST), "run_test")
-
- logging.info("Compresssing initrd")
- os.chdir(initrd_tmp_dir)
- t = pipes.Template()
- t.prepend("find .", ".-")
- t.append("cpio --quiet -o -H newc", '--')
- t.append('gzip -9fc ', '--')
- t.copy("/dev/null", t_initrd)
-
- # Done with the initrd - chdir to old working dir
- os.chdir(old_wd)
-
- logging.debug("Attaching initrd")
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc,
- open(t_initrd),
- 'pxe/initrd')
-
- logging.debug("Attaching kernel")
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc,
- open(kernel),
- 'pxe/kernel')
-
- logging.debug("Attaching pxelinux.0")
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc,
- open(os.path.join(TMPL_DIR, 'pxelinux.0')),
- 'pxe/pxelinux.0')
-
- logging.debug("Attaching pxelinux config")
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc,
- open(os.path.join(TMPL_DIR, 'pxelinuxcfg.install')),
- "pxe/pxelinux.cfg/%s" % (test_uuid))
-
- logging.debug("Adding test script to test case document")
- t_script = os.path.join(TEST_CASE_DIR, t_preseed, 'test')
- logging.debug("Test script: %s" % (t_script))
- test_case_doc = db[test_uuid]
- db.put_attachment(test_case_doc, open(t_script),
- filename="tests/%s" % (t_preseed))
-
- logging.debug("Generating libvirt information for %s" % (p))
- logging.debug("Generating disk information")
- disks = []
- for d_i in range(1, DISK_NUMBER+1):
- disks.append({ 'target': "vd%s" % (string.ascii_lowercase[d_i-1]),
- 'bus': DISK_BUS,
- 'format': DISK_FORMAT,
- 'size': DISK_SIZE,
- })
- mac_address = random_mac_address()
- test_case_doc = db[test_uuid]
- test_case_doc['disks'] = disks
- test_case_doc['mac'] = mac_address
- test_case_doc['iso_url'] = "%s" % (i)
- db[test_uuid] = test_case_doc
-
- logging.debug("Setting state to created")
- test_case_doc = db[test_uuid]
- test_case_doc['states']['created'] = datetime.datetime.utcnow()\
- .isoformat()
- db[test_uuid] = test_case_doc
-
- shutil.rmtree(test_tmp_dir)
-
- # Setup and trigger test if operating under Hudson
- if HUDSON_URL != "":
- # Read in ISO version details
- f = open(i + ".build-version")
- bv = f.read().rstrip("\n");
- f.close()
- l_jobname = bv + "_" + os.path.basename(i) + "_" + os.path.basename(p)
- logging.debug("Setting up Hudson Jobs %s " % l_jobname)
- l_hud = hudson.Hudson(HUDSON_URL)
- # Create job if it does not exists
- if not l_hud.job_exists(l_jobname):
- logging.debug("Creating Hudson Job %s " % l_jobname)
- # Readin config.xml for posting to Hudson
- f = open(os.path.join(TMPL_DIR, 'config.xml' ))
- l_hud.create_job(l_jobname, f.read())
- f.close()
-
- # Trigger the job
- logging.debug("Initiating Hudson Job %s" % l_jobname)
- l_hud.build_job(l_jobname, {'TEST_CASE': test_uuid,
- 'TEST_TRACKER': TEST_TRACKER,
- 'ISO_DIR': ISO_DIR,
- 'RELEASE': RELEASE,
- 'VARIANT': VARIANT,
- 'BUILD_VERSION':BUILD_VERSION})
-
- shutil.rmtree(iso_tmp_dir)
=== modified file 'docs/NEWS'
--- docs/NEWS 2010-09-24 03:52:38 +0000
+++ docs/NEWS 2011-01-12 20:50:44 +0000
@@ -1,6 +1,95 @@
+.. vim: set ft=rst tw=79:
+
+
+1.0
+===
+
+Summary:
+
+ - Testing framework now makes use of apt-cacher-ng to improve the performance
+ of updates downloaded by ISO test cases.
+ - Test execution timeout is now configurable using the BUILD_TIMEOUT environment
+ variable.
+ - Framework now uses TFTP/PXE rather than gPXE to simplify solution and remove
+ dependency on non-ubuntu codebase.
+ - First -desktop test case (thanks to jibel for that).
+ - Refactoring of packages to seperate -server and -desktop
+ + ubuntu-server-iso-testing - Server ISO Test cases
+ + ubuntu-desktop-iso-testing - Desktop ISO Test cases
+ + ubuntu-iso-testing-common - common python components
+ + hudson-slave - helper script and dependencies for Hudson slave setup and
+ execution
+ - ec2 based master server: http://hudson.qa.ubuntu-uk.org
+
+
+Work items:
+
+ - [james-page] make slave more contained to support firewalled network:
+ + move all couchdb info to be local to slave: DONE
+ - [james-page] Provide a Debian package to setup a Hudson slave on a system: DONE
+ - [james-page] Provide a package in PPA for installing a slave: DONE
+ + ppa:james-page/usit
+ - [james-page] fix iso download <-> overall build time out of 20 minutes: it can take more
+ than 20 minutes to download a new iso (eg initial run - no iso are cached): DONE
+ + TEST_TIMEOUT is now configurable using an environment variable - defaults to 20 mins.
+ - [james-page] Refactor gPXE -> PXE to provide wider support and cleaner install: DONE
+ - [james-page] Use apt-proxy or alternative mirrors to decrease test times:
+ add to documentation : DONE
+ - [jibel] Support automated -desktop iso testing : DONE
+
+
+0.2
+===
+
+Schedule release date:
+ Demo at the server team mumble meeting on Tuesday, Oct 5th 2010.
+
+User stories:
+ + The hudson master runs in an instance in EC2.
+ + Couchdb server runs locally with the slave.
+ + Hudson slaves run on mathiaz laptop and james laptop.
+ + mathiaz can debug failing tests that have executed on james laptop
+ when james laptop is powered off.
+ + daily -server isos are automatically tested by Hudson.
+
+Assumptions:
+ + Hudson slaves and test vms have access to the internet.
+ + Hudson slaves can only run 1 job at a time because of iso caching.
+
+Work items:
+
+ DONE:
+ - Remove mathiaz acccount and ssh key and replace with ubuntu [DONE]
+ - Introduce sleep to run_test script to allow apps to start - 30 seconds sleep. [DONE]
+ - Fix tomcat server test. [DONE]
+ - Support multiple hudson slaves [DONE]:
+ + cache isos on each slave - use zsync:
+ + Move logic to configure_and_run_test script
+ - pass build number to determine whether correct version in local cache.
+ The build number is the date of the iso - available on cdimage in
+ the folder name (not using current).
+ + don't send qcow2 files to hudson workspace [DONE].
+ + clean up hudson slave once the test has been executed:
+ - clean up libvirt configuration, qcow files and other local files. [DONE]
+ - Amend configure_and_run_by_uuid.py to tidyup dnsmasq.d directory
+ post execution. [DONE]
+ + Add an overall build timeout in the slave configure_and_run_test script
+ of 20 minutes [DONE]
+ + workspace sync post test execution to master (ie push back workspace from
+ slaves to master). [DONE]
+ - automated trigger to test daily -server isos [DONE]:
+ + [mathiaz] ping marc tardic (cr3) about daily cron job that watches new
+ isos in the certification lab.
+ + write hudson job that leverage script above to automatically test -server
+ isos.
+ - [mathiaz] setup master in Rackspace Cloud. [DONE]
+ - [james-page] remove initrd and kernel from artifacts to minimise upload. [DONE]
+ - [james-page] update documentation to move couchdb to slave. [DONE]
+ - [james-page] setup and test additional hudson slave.
+
0.1
===
Initial release:
- all-in-one setup.
-.. vim: set ft=rst tw=79:
+
=== modified file 'docs/README'
--- docs/README 2010-10-04 10:22:53 +0000
+++ docs/README 2011-01-12 20:50:44 +0000
@@ -67,13 +67,6 @@
This allows it to be located on minimal hardware or in a cloud based location.
ISO test execution is completed by Hudson slave nodes.
-Install Required Dependencies
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following packages are required to execute the iso testing suite::
-
- sudo apt-get install bzr curl python-jinja2
-
Install Hudson
~~~~~~~~~~~~~~
@@ -96,30 +89,6 @@
The hudson user will also need to be added to the shadow group to provide
access to the /etc/shadow file for UNIX based authentication.
-
-Ubuntu Server ISO Testing Code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Under the hudson account::
-
- mkdir ~/reference
- cd reference
- bzr co lp:ubuntu-server-iso-testing iso-testing
-
-This drops all of the project codebase into the correct location for use by
-Hudson
-
-Setup Hudson Jobs
-~~~~~~~~~~~~~~~~~
-
-Under the hudson account::
-
- cd ~/reference/iso-testing
- ./setup_hudson.py -c hostname:5984 http://username:password@localhost:8080
-
-This will setup the standard job - iso-testing-initiator in Hudson.
-
-
Hudson Slave Host Setup
-----------------------
@@ -132,130 +101,40 @@
This is not current bundled seperately from Hudson, but is downloaded from the
Hudson master server and then executed.
-Setup a Hudson Account
-~~~~~~~~~~~~~~~~~~~~~~
-
-Create a hudson account to execute tests::
-
- useradd -d /var/lib/hudson -m -s /bin/bash -c "Hudson Slave Account" hudson -G libvirtd
-
-Ubuntu Server ISO Testing Code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Under the hudson account::
-
- mkdir ~/reference
- cd reference
- bzr co lp:ubuntu-server-iso-testing iso-testing
-
-This drops all of the project codebase into the correct location for use by Hudson
-
-Install Required Dependencies
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following packages are required to execute the iso testing suite on Hudson
-slave nodes::
-
- sudo apt-get install bzr git-core curl python-setuptools python-jinja2
- sudo apt-get install python-couchdb ubuntu-qa-tools bsdtar dnsmasq libvirt
- sudo apt-get install kvm-pxe default-jdk-headless
-
-dnsmasq configuration
-~~~~~~~~~~~~~~~~~~~~~
-
-Drop hudson-dnsmasq into /etc/sudoers.d to support password-less restart of
-dnsmasq for hudson account::
-
- hudson ALL = NOPASSWD: /usr/sbin/service dnsmasq restart
-
-You will also need to open up the permissions on /etc/dnsmasq.d to
-allow hudson to write to it.
-
-dnsmasq is used to create dhcp and pxe boot configurations for each of the ISO
- vm's which will be built and tested - configuration files are generated from
- dnsmasq.conf and dropped into /etc/dnsmasq.d::
-
-As dnsmasq is going to be running standalone, the configuration normally
-operated by libvirt networking needs to be deployed in the main dnsmasq
-deployment:
-
-Drop this libvirt-default.conf into /etc/dnsmasq.d::
-
- dhcp-no-override
- strict-order
- bind-interfaces
- listen-address=192.168.122.1
- except-interface=lo
- dhcp-range=192.168.122.100,192.168.122.254
- dhcp-lease-max=25
-
-You may also encounter issues after reboot as libvirt gets in first which
-stops the normal dnsmasq from operating correctly::
-
- sudo pkill dnsmasq
- sudo service dnsmasq restart
-
-Install gPXE compatible boot ROM
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The default pxe ROM image to the virtio-net driver does not support
-gPXE; backup the kvm-pxe installed rom::
-
- /usr/share/kvm
- cp pxe-virtio.bin pxe-virtio.bin-bak
-
-A new gPXE ROM was generated from >>
- http://rom-o-matic.net/gpxe/gpxe-1.0.1/contrib/rom-o-matic/
-
-|| Format || ROM binary (flashable)....||
-|| NIC Type || virtio-net ||
-|| PCI Vendor Code || 1af4 ||
-|| PCI Device Code || 1000 ||
-
-Drop in replacement ROM file to overwrite pxe-virtio.bin.
-
-Install & Setup CouchDB
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Install CouchDB
-^^^^^^^^^^^^^^^
-
-The test framework uses CouchDB to store test configuration and capture
-test results; first install it::
-
- sudo apt-get install couchdb
-
-This can be installed on the Hudson master server and must be network
-accessible from all Hudson slaves.
-
-Create Test Database
-^^^^^^^^^^^^^^^^^^^^
-
-The scripts don't check for the existence of the database prior to executing
-but its a simple one-liner to create the empty database::
-
- curl -X PUT http://localhost:5984/tests
-
-Configuration
-^^^^^^^^^^^^^
-
-The CouchDB instance needs some localised configuration to ensure that it can
-use python as a query language and is generally network accessible ( changes
-made in /usr/couchdb/local.ini ) ::
-
- [query_servers]
- python=/usr/bin/couchpy
-
- [httpd]
- ;port = 5984
- bind_address = 0.0.0.0
-
+Note that the slave *MUST* be hardware virtualisation capable as it relies on
+kvm and libvirt to execute test instances.
+
+Enable PPA repository and Install
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The latest version of the ubuntu-server-iso-testing package can be found at
+ppa:ubuntu-server-iso-testing-dev/testing.
+
+To enable the repository::
+
+ sudo add-apt-repository ppa:ubuntu-server-iso-testing-dev/testing
+
+To install the ubuntu-server-iso-testing package::
+
+ sudo apt-get install ubuntu-server-iso-testing
+
+This will install all dependencies and setup the system ready to execute
+ISO tests.
+
Hudson Configuration
^^^^^^^^^^^^^^^^^^^^
-Hudson localises the configuration of the URL for each slave instance; this is
-implemented by setting up an environment variable through the Hudson web
-interface.
+The Hudson master server can be remotely configured with all of the required
+projects (tests) using the following command on the slave::
+
+ setup-hudson -u <username> -p <password> -r <release> HUDSON_URL
+
+This can be run multiple times; it simple re-configures each project with the
+latest definition provided in the package.
+
+Hudson can localise the configuration of the TEST_TRACKER (i.e couchdb instance)
+for each slave instance; this is implemented by setting up an environment variable
+through the Hudson web interface.
Manage Husdon -> Manage Nodes -> Configure Node; then add an environment
variable defining the location of the CouchDB instance that the ISO
@@ -263,15 +142,27 @@
TEST_TRACKER=http://<IPADDRESS>:<5984>
+The following additional environment variables can be specified to create a localised
+configuration for a slave:
+
+ * TEST_DATABASE (default:tests) - name of the couchdb database to use for testing.
+ * TEST_TIMEOUT (default:1200) - time permitted for a VM to complete test execution
+ before it is terminated by the run-tests script (useful for install hangs)
+ * TEST_DIR (defaults:~/tests) - directory to use for storage of virtual machine
+ images during testing.
+
Download and execute the slave agent
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Execute the following script as the hudson user::
+Execute the following command as the usit user::
- cd ~/reference/iso-testing
- ./hudson-slave.py http://<hudsonmaster>:<port>/
+ hudson-slave http://<hudsonmaster>:<port>/ &
The script will by default use the hostname of the local box to login to the
Hudson master server.
+Your slave should now be ready to rock-and-roll!
+If you want to start the slave automatically on boot, update /etc/default/hudson-slave
+to enable the hudson-slave upstart script and set the URL to the hudson master
+server.
=== modified file 'docs/TODO'
--- docs/TODO 2010-10-19 01:52:19 +0000
+++ docs/TODO 2011-01-12 20:50:44 +0000
@@ -1,79 +1,18 @@
.. vim: set ft=rst tw=79:
.. When a release is done move all the features/info to the NEWS file.
-0.2
-===
-
-Schedule release date:
- Demo at the server team mumble meeting on Tuesday, Oct 5th 2010.
-
-User stories:
- + The hudson master runs in an instance in EC2.
- + Couchdb server runs locally with the slave.
- + Hudson slaves run on mathiaz laptop and james laptop.
- + mathiaz can debug failing tests that have executed on james laptop
- when james laptop is powered off.
- + daily -server isos are automatically tested by Hudson.
-
-Assumptions:
- + Hudson slaves and test vms have access to the internet.
- + Hudson slaves can only run 1 job at a time because of iso caching.
-
-Work items:
-
- TODO:
- - [mathiaz] setup and test additional hudson slave.
-
- DONE:
- - Remove mathiaz acccount and ssh key and replace with ubuntu [DONE]
- - Introduce sleep to run_test script to allow apps to start - 30 seconds sleep. [DONE]
- - Fix tomcat server test. [DONE]
- - Support multiple hudson slaves [TESTING_NEEDED]:
- + cache isos on each slave - use zsync:
- + Move logic to configure_and_run_test script
- - pass build number to determine whether correct version in local cache.
- The build number is the date of the iso - available on cdimage in
- the folder name (not using current).
- + don't send qcow2 files to hudson workspace [DONE].
- + clean up hudson slave once the test has been executed:
- - clean up libvirt configuration, qcow files and other local files. [DONE]
- - Amend configure_and_run_by_uuid.py to tidyup dnsmasq.d directory
- post execution. [DONE]
- + Add an overall build timeout in the slave configure_and_run_test script
- of 20 minutes [DONE]
- + workspace sync post test execution to master (ie push back workspace from
- slaves to master). [DONE]
- - automated trigger to test daily -server isos [DONE]:
- + [mathiaz] ping marc tardic (cr3) about daily cron job that watches new
- isos in the certification lab.
- + write hudson job that leverage script above to automatically test -server
- isos.
- - [mathiaz] setup master in Rackspace Cloud. [DONE]
- - [james-page] remove initrd and kernel from artifacts to minimise upload. [DONE]
- - [james-page] update documentation to move couchdb to slave. [DONE]
-
Next
====
-
+ - handle multiple job run on each slave:
+ + fix iso cache component to support multiple execution of
+ configure_and_run_test.
Later
=====
- replace dnsmasq sudo restart command with dhcp-optsfile option as dnsmasq
will reload it when SIGHUP is received. This will be faster than a restart
via dnsmasq init script.
- - make slave more contained to support firewalled network:
- * move all couchdb info to be local to slave.
- - provide a package in PPA for installing a slave.
- - keep the naming scheme: ISO-NAME_TEST-CASE - extract the iso build number (ie date) and make it more readable.
- move all test to checkbox.
- - Use apt-proxy or alternative mirrors to decrease test times:
- add to documentation.
- - handle multiple job run on each slave:
- + fix iso cache component to support multiple execution of
- configure_and_run_test.
- - fix iso download <-> overall build time out of 20 minutes: it can take more
- than 20 minutes to download a new iso (eg initial run - no iso are cached).
- - Provide a Debian package to setup a Hudson slave on a system.
- Update documentation to follow `Python Style Guide`_.
- Support for testing on physical hardware using wake-on-lan and appropriate
DHCP/PXE/TFTP configuration (see also hardware certification projects).
@@ -85,6 +24,5 @@
Or
Get rid of Hudson and write a couchapp to provide a shiny interface to
test results.
- - Support automated -desktop iso testing.
.. _Python Style Guide: http://docs.python.org/documenting/index.html
=== modified file 'download-latest-test-iso.py'
--- download-latest-test-iso.py 2010-09-28 12:50:20 +0000
+++ download-latest-test-iso.py 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
from HTMLParser import HTMLParser
import os
import optparse
=== modified file 'hudson-slave.py'
--- hudson-slave.py 2010-09-27 13:36:46 +0000
+++ hudson-slave.py 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
import logging
import optparse
=== modified file 'run-test.py'
--- run-test.py 2010-12-16 01:03:58 +0000
+++ run-test.py 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
import datetime
import glob
@@ -14,35 +33,27 @@
import tempfile
import uuid
import urllib
-import hudson
import time
import couchdb
import jinja2
+from stat import S_IRWXU, S_IRGRP, S_IXGRP, S_IROTH, S_IXOTH
logging.basicConfig(level=logging.DEBUG)
-# Get all environment variable for general test configuration
-TMPL_DIR = os.environ.get("TMPL_DIR",
- os.path.expanduser("~/reference/iso-testing/templates/"))
-RUN_TEST = os.path.join(TMPL_DIR, 'run_test')
-TEST_CASE_DIR = os.path.join(TMPL_DIR, 'test_cases')
-PRESEED_TMPL_DIR = [os.path.join(TMPL_DIR, 'preseeds-common'), TEST_CASE_DIR]
-DNSMASQ_DIR = os.environ.get("DNSMASQ_DIR", "/etc/dnsmasq.d")
-TEST_DIR = os.environ.get("TEST_DIR",
- os.path.expanduser("~/reference/iso-testing/tests"))
-TEST_TRACKER = os.environ.get("TEST_TRACKER", "http://192.168.122.1:5984")
-TEST_DATABASE = os.environ.get("TEST_DATABASE", "tests")
-TEST_RESULTS = os.environ.get("TEST_RESULTS","test-results")
-
-
-# URL of Hudson CI Server
-HUDSON_URL = os.environ.get("HUDSON_URL", "")
-BUILD_NUMBER = os.environ.get("BUILD_NUMBER", "")
-ATTACHEMENT_EXCLUSIONS = ['pxe/kernel', 'pxe/initrd']
-
-# Default time to sleep for monitoring VM execution
-SLEEP_TIME = 30
-TEST_TIMEOUT = 1200
+def set_config(variant = 'server'):
+ """ Set parameters specific to a variant """
+ global DEFAULT_TMPL_DIR, DEFAULT_TEST_TIMEOUT, DISK_SIZE, COMPRESS_CMD,\
+ UNCOMPRESS_CMD, KERNEL_DIR, INITRD
+
+ variant = variant.lower()
+ if variant == 'desktop':
+ DEFAULT_TMPL_DIR = "/usr/share/ubuntu-server-iso-testing/templates.desktop"
+ DEFAULT_TEST_TIMEOUT = 3600
+ DISK_SIZE = "4G"
+ COMPRESS_CMD = "lzma "
+ UNCOMPRESS_CMD = "lzcat -S lz "
+ KERNEL_DIR = "casper"
+ INITRD = "initrd.lz"
# Defaults
DEFAULT_VARIANT = 'server'
@@ -50,12 +61,20 @@
DEFAULT_ARCH = 'i386'
DEFAULT_FLAVOR= 'ubuntu'
DEFAULT_ISOROOT = os.path.expanduser('~/isos')
+DEFAULT_TMPL_DIR = "/usr/share/ubuntu-server-iso-testing/templates"
+DEFAULT_TEST_TIMEOUT = 1200
DISK_FORMAT = "qcow2"
DISK_BUS = "virtio"
DISK_SIZE = "2G"
DISK_NUMBER = 1
+COMPRESS_CMD = "gzip "
+UNCOMPRESS_CMD = "zcat "
+KERNEL_DIR = "install"
+INITRD = "initrd.gz"
+KERNEL = "vmlinuz"
+
usage="usage: %prog [options] preseed1"
parser = optparse.OptionParser(usage=usage)
parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False,
@@ -85,6 +104,37 @@
parser.print_help()
sys.exit(1)
+set_config(options.variant)
+# Get all environment variable for general test configuration
+TMPL_DIR = os.environ.get("TMPL_DIR", DEFAULT_TMPL_DIR)
+RUN_TEST = os.path.join(TMPL_DIR, 'run_test')
+TEST_CASE_DIR = os.path.join(TMPL_DIR, 'test_cases')
+PRESEED_TMPL_DIR = [os.path.join(TMPL_DIR, 'preseeds-common'), TEST_CASE_DIR]
+DNSMASQ_DIR = os.environ.get("DNSMASQ_DIR",
+ os.path.expanduser('~/dnsmasq.d'))
+TEST_DIR = os.environ.get("TEST_DIR",
+ os.path.expanduser('~/tests'))
+TEST_TRACKER = os.environ.get("TEST_TRACKER", "http://192.168.122.1:5984")
+TFTP_HOST = os.environ.get("TFTP_HOST", "192.168.122.1")
+TFTP_DIR = os.environ.get("TFTP_DIR",
+ os.path.expanduser('~/tftp'))
+TEST_DATABASE = os.environ.get("TEST_DATABASE", "tests")
+TEST_RESULTS = os.environ.get("TEST_RESULTS","test-results")
+APT_PROXY = os.environ.get("APT_PROXY","http://192.168.122.1:3142")
+
+# URL of Hudson CI Server
+HUDSON_URL = os.environ.get("HUDSON_URL", "")
+BUILD_NUMBER = os.environ.get("BUILD_NUMBER", "")
+ATTACHEMENT_EXCLUSIONS = ['pxe/kernel', 'pxe/initrd']
+
+# Default time to sleep for monitoring VM execution
+# configurable using environment variable.
+SLEEP_TIME = 30
+try:
+ TEST_TIMEOUT = int(os.environ.get("TEST_TIMEOUT",DEFAULT_TEST_TIMEOUT))
+except ValueError:
+ TEST_TIMEOUT = DEFAULT_TEST_TIMEOUT
+
logging.info("Preseed: %s" % (args[0]))
preseed= os.path.join(TEST_CASE_DIR,args[0])
@@ -107,6 +157,10 @@
os.makedirs(TEST_DIR)
server = couchdb.client.Server(TEST_TRACKER)
+# Create database if it does not exist.
+if TEST_DATABASE not in server:
+ server.create(TEST_DATABASE)
+
db = server[TEST_DATABASE]
# Check and Download ISO if need be.
@@ -114,16 +168,16 @@
# Create useful handles to ISO location
iso_name = options.release + '-' + options.variant + '-' + options.arch + '.iso'
iso_dir = options.flavor + '-' + options.variant
-iso_location = os.path.join(options.isoroot, iso_dir, iso_name)
-
+iso_location = os.path.join(options.isoroot, iso_dir, iso_name)
+
# Extract kernel and initrd from ISO to build new initrd including
# required preseed
logging.info("Extracting kernel and initrd from %s" % (iso_location))
iso_tmp_dir = tempfile.mkdtemp(prefix="%s-" % (os.path.basename(iso_location)))
-kernel = os.path.join(iso_tmp_dir, "install", 'vmlinuz')
-initrd = os.path.join(iso_tmp_dir, "install", "initrd.gz")
+kernel = os.path.join(iso_tmp_dir, KERNEL_DIR, KERNEL)
+initrd = os.path.join(iso_tmp_dir, KERNEL_DIR, INITRD)
cmd = ['bsdtar', '-xf', iso_location, '-C', iso_tmp_dir,
- "install/vmlinuz", "install/initrd.gz"]
+ KERNEL_DIR + "/" + KERNEL, KERNEL_DIR + "/" + INITRD]
logging.debug("Cmd: %s" % (cmd))
subprocess.check_call(cmd)
@@ -131,6 +185,7 @@
logging.info("Generating %s configuration" % (t_preseed))
old_wd = os.getcwd()
+mac_address = random_mac_address()
test_uuid = str(uuid.uuid4())
db[test_uuid] = { "test_case": t_preseed,
"states": {
@@ -140,13 +195,14 @@
test_tmp_dir = tempfile.mkdtemp(prefix="%s-" % (t_preseed),
dir=iso_tmp_dir)
initrd_tmp_dir = tempfile.mkdtemp(prefix='initrd-', dir=test_tmp_dir)
-t_initrd = os.path.join(test_tmp_dir, 'initrd.gz')
+t_initrd = os.path.join(test_tmp_dir, INITRD)
logging.debug("Generate preseed file")
tmpl = preseed_templates.get_template("%s/preseed" % (t_preseed))
ctxt = { 'hostname': test_uuid,
'test_case_url': "%s/%s/%s" % (TEST_TRACKER, TEST_DATABASE,
- test_uuid)}
+ test_uuid),
+ 'proxyurl': APT_PROXY }
preseed_file = os.path.join(test_tmp_dir, 'preseed')
logging.debug("will preseed %s" % preseed_file)
tmpl.stream(ctxt).dump(preseed_file)
@@ -155,7 +211,7 @@
logging.debug("Initrd file: %s" % (initrd))
os.chdir(initrd_tmp_dir)
t = pipes.Template()
-t.prepend("zcat $IN", "f-")
+t.prepend(UNCOMPRESS_CMD + " $IN", "f-")
t.append("cpio -ivd 2>/dev/null", "-.")
t.copy(initrd, '/dev/null')
@@ -164,6 +220,13 @@
test_case_doc = db[test_uuid]
db.put_attachment(test_case_doc, open(preseed_file), "preseed")
+# Create location for TFTP setup
+test_tftp_dir = os.path.join(TFTP_DIR,test_uuid)
+os.makedirs(test_tftp_dir)
+
+logging.debug("Copying preseed to tftp root")
+shutil.copy(preseed_file,test_tftp_dir)
+
logging.info("Copying run_test")
# Put run_test in the initrd so that the installer can copy it
# into the target system at late_command time
@@ -172,12 +235,38 @@
test_case_doc = db[test_uuid]
db.put_attachment(test_case_doc, open(RUN_TEST), "run_test")
-logging.info("Compresssing initrd")
+if options.variant == 'desktop':
+ # Specific bits for Desktop
+ # Put run_test wrapper in the initrd too
+ RUN_TEST_WRAPPER = os.path.join(TMPL_DIR, 'run_test.wrapper')
+ shutil.copy(RUN_TEST_WRAPPER, os.path.join(initrd_tmp_dir, 'run_test.wrapper'))
+ # Keep a copy in test case doc
+ test_case_doc = db[test_uuid]
+ db.put_attachment(test_case_doc, open(RUN_TEST_WRAPPER), "run_test.wrapper")
+
+ logging.info("Copying casper hook")
+ casper_hook = os.path.join(TMPL_DIR, 'casper.99custom')
+ casper_file = os.path.join(initrd_tmp_dir, 'scripts/casper-bottom/99custom')
+ logging.debug("'%s' -> '%s'" % (casper_hook, casper_file))
+ tmpl = templates.get_template("casper.99custom")
+ ctxt = { 'hostname': test_uuid,
+ 'test_case_url': "%s/%s/%s" % (TEST_TRACKER, TEST_DATABASE,
+ test_uuid)}
+ tmpl.stream(ctxt).dump(casper_file)
+ # Casper hook needs to be executable
+ os.chmod(casper_file, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+
+ logging.debug("Adding it to the list of known hooks")
+ co = open(os.path.join(initrd_tmp_dir, 'scripts/casper-bottom/ORDER'), 'a')
+ co.write('/scripts/casper-bottom/99custom\n[ -e /conf/param.conf ] && . /conf/param.conf\n')
+ co.close()
+
+logging.info("Compressing initrd")
os.chdir(initrd_tmp_dir)
t = pipes.Template()
t.prepend("find .", ".-")
t.append("cpio --quiet -o -H newc", '--')
-t.append('gzip -9fc ', '--')
+t.append(COMPRESS_CMD + ' -9fc ', '--')
t.copy("/dev/null", t_initrd)
# Done with the initrd - chdir to old working dir
@@ -189,24 +278,39 @@
open(t_initrd),
'pxe/initrd')
+logging.debug("Copying initrd to tftp root")
+shutil.copy(t_initrd,os.path.join(test_tftp_dir,'initrd'))
+
logging.debug("Attaching kernel")
test_case_doc = db[test_uuid]
db.put_attachment(test_case_doc,
open(kernel),
'pxe/kernel')
+logging.debug("Copying kernel to tftp root")
+shutil.copy(kernel,os.path.join(test_tftp_dir,'kernel'))
+
logging.debug("Attaching pxelinux.0")
test_case_doc = db[test_uuid]
db.put_attachment(test_case_doc,
open(os.path.join(TMPL_DIR, 'pxelinux.0')),
'pxe/pxelinux.0')
+logging.debug("Copying pxelinux.0 to tftp root")
+shutil.copy(os.path.join(TMPL_DIR, 'pxelinux.0'),test_tftp_dir)
+
logging.debug("Attaching pxelinux config")
test_case_doc = db[test_uuid]
db.put_attachment(test_case_doc,
open(os.path.join(TMPL_DIR, 'pxelinuxcfg.install')),
"pxe/pxelinux.cfg/%s" % (test_uuid))
+logging.debug("Copying pxelinux config to tftp root")
+pxelinux_cfg = os.path.join(test_tftp_dir,'pxelinux.cfg')
+os.makedirs(pxelinux_cfg)
+shutil.copy(os.path.join(TMPL_DIR, 'pxelinuxcfg.install'),
+ os.path.join(pxelinux_cfg,'default'))
+
logging.debug("Adding test script to test case document")
t_script = os.path.join(TEST_CASE_DIR, t_preseed, 'test')
logging.debug("Test script: %s" % (t_script))
@@ -223,7 +327,7 @@
'format': DISK_FORMAT,
'size': DISK_SIZE,
})
-mac_address = random_mac_address()
+
test_case_doc = db[test_uuid]
test_case_doc['disks'] = disks
test_case_doc['mac'] = mac_address
@@ -286,6 +390,7 @@
ctxt = { 'mac': test['mac'],
'test_tracker': TEST_TRACKER,
'test_db': TEST_DATABASE,
+ 'tftp_host' : TFTP_HOST,
'uuid': test['_id'],
}
logging.debug("Context: %s" % (ctxt))
@@ -340,8 +445,6 @@
# Decrement the timeout
l_timeout = l_timeout - SLEEP_TIME
-# Some issues with timeout on my box so wait for stuff to wake up
-time.sleep(SLEEP_TIME)
# Retrieve latest copy of data
test = db[test['_id']]
# Flag to indicate if tests successfully executed
@@ -381,6 +484,9 @@
subprocess.check_call(cmd)
# Remove VM config and disks - no longer required
shutil.rmtree(os.path.join(TEST_DIR, test['_id']))
+
+# Remove TFTP files - no longer required
+shutil.rmtree(test_tftp_dir)
# Remove dnsmasq configuration and restart dnsmasq
logging.debug("Removing dnsmasq configuration for %s" % (test['_id']))
=== modified file 'setup-hudson.py'
--- setup-hudson.py 2010-09-30 09:30:46 +0000
+++ setup-hudson.py 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
import hudson
import os
@@ -9,8 +28,8 @@
import glob
hudson_jobs= []
-TMPL_DIR="templates"
-TEST_CASE_DIR="templates/test_cases"
+TMPL_DIR="/usr/share/ubuntu-server-iso-testing/templates"
+TEST_CASE_DIR= os.path.join(TMPL_DIR,"test_cases")
DEFAULT_VARIANT = 'server'
DEFAULT_RELEASE = 'maverick'
DEFAULT_COUCHDB = 'http://192.168.122.1:5984'
=== added directory 'templates.desktop'
=== added file 'templates.desktop/casper.99custom'
--- templates.desktop/casper.99custom 1970-01-01 00:00:00 +0000
+++ templates.desktop/casper.99custom 2011-01-12 20:50:44 +0000
@@ -0,0 +1,61 @@
+#!/bin/sh
+# If you change this, please also change the copy in ubiquity-hooks/30accessibility.
+
+PREREQ=""
+DESCRIPTION="Running custom script..."
+
+prereqs()
+{
+ echo "$PREREQ"
+}
+
+case $1 in
+# get pre-requisites
+prereqs)
+ prereqs
+ exit 0
+ ;;
+esac
+
+. /scripts/casper-functions
+
+log_begin_msg "$DESCRIPTION"
+
+gconf_version=$(chroot /root /usr/bin/dpkg-query -W --showformat='${Version}' gconf2 2>/dev/null) || gconf_version=""
+
+gct() {
+ if [ "$gconf_version" ]; then
+ chroot /root sudo -u "$USERNAME" gconftool-2 "$@"
+ fi
+}
+
+create_desktopfile() {
+ AUTOSTART_DIR=/root/home/$USERNAME/.config/autostart
+ DESKTOP_FILE=smoketest.desktop
+ mkdir -p $AUTOSTART_DIR
+ cat > ${AUTOSTART_DIR}/${DESKTOP_FILE}<<EOF
+
+[Desktop Entry]
+Name=ISO SmokeTest
+Comment=ISO SmokeTest
+Exec=/usr/local/bin/run_test.wrapper --syslog --sleep 30 --test-dir=/home/${USERNAME}/tests {{ test_case_url }}
+OnlyShowIn=GNOME;
+NoDisplay=true
+Type=Application
+AutostartCondition=GNOME /desktop/gnome/interface/accessibility
+X-GNOME-Autostart-Phase=Applications
+X-GNOME-AutoRestart=true
+Name[en_US]=ISO SmokeTest
+Comment[en_US]=ISO SmokeTest
+X-GNOME-Autostart-enabled=true
+EOF
+}
+
+gct -s -t bool /desktop/gnome/interface/accessibility true
+create_desktopfile
+
+# Copy the test script which is run from the desktop file
+cp /run_test.wrapper /root/usr/local/bin/
+cp /run_test /root/usr/local/bin/
+
+log_end_msg
=== added file 'templates.desktop/config.xml'
--- templates.desktop/config.xml 1970-01-01 00:00:00 +0000
+++ templates.desktop/config.xml 2011-01-12 20:50:44 +0000
@@ -0,0 +1,93 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
+<project>
+ <actions/>
+ <description>Hudson wrapper to execute individual ISO build test.</description>
+ <keepDependencies>false</keepDependencies>
+ <properties>
+ <hudson.model.ParametersDefinitionProperty>
+ <parameterDefinitions>
+ <hudson.model.StringParameterDefinition>
+ <name>TEST_CASE</name>
+ <description>UUID of test case to execute</description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>TEST_TRACKER</name>
+ <description>Location of CouchDB to store configuration and test results.</description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>ISO_DIR</name>
+ <description>Location to store ISO images locally.</description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>RELEASE</name>
+ <description>Release to download from image archive (i.e. maverick, lucid etc).</description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>VARIANT</name>
+ <description>Variant to download from image archive (i.e server).</description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>BUILD_VERSION</name>
+ <description>Build version to download from image archive (i.e current, 20100923).</description>
+ <defaultValue></defaultValue>
+ </hudson.model.StringParameterDefinition>
+ </parameterDefinitions>
+ </hudson.model.ParametersDefinitionProperty>
+ <hudson.plugins.disk__usage.DiskUsageProperty/>
+ </properties>
+ <scm class="hudson.scm.NullSCM"/>
+ <assignedNode>!master</assignedNode>
+ <canRoam>true</canRoam>
+ <disabled>false</disabled>
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
+ <triggers class="vector"/>
+ <concurrentBuild>false</concurrentBuild>
+ <builders>
+ <hudson.tasks.Shell>
+ <command>#!/bin/bash
+
+${HOME}/reference/iso-testing/download-latest-test-iso.py --release=${RELEASE} --variant=${VARIANT} --isoroot=${ISO_DIR}</command>
+ </hudson.tasks.Shell>
+ <hudson.tasks.Shell>
+ <command>#/bin/bash
+
+${HOME}/reference/iso-testing/configure_and_run_test_by_uuid.py -d ${TEST_CASE}</command>
+ </hudson.tasks.Shell>
+ </builders>
+ <publishers>
+ <hudson.tasks.ArtifactArchiver>
+ <artifacts>**/*</artifacts>
+ <latestOnly>false</latestOnly>
+ </hudson.tasks.ArtifactArchiver>
+ <hudson.tasks.junit.JUnitResultArchiver>
+ <testResults>**/test-results/*.xml</testResults>
+ <keepLongStdio>false</keepLongStdio>
+ <testDataPublishers/>
+ </hudson.tasks.junit.JUnitResultArchiver>
+ </publishers>
+ <buildWrappers/>
+</project>
=== added file 'templates.desktop/dnsmasq-iso-testing.conf'
--- templates.desktop/dnsmasq-iso-testing.conf 1970-01-01 00:00:00 +0000
+++ templates.desktop/dnsmasq-iso-testing.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Additional configuration directory for ubuntu server iso testing
+conf-dir=/var/lib/ubuntu-server-iso-testing/dnsmasq.d
=== added file 'templates.desktop/dnsmasq.conf'
--- templates.desktop/dnsmasq.conf 1970-01-01 00:00:00 +0000
+++ templates.desktop/dnsmasq.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+dhcp-host={{ mac }},net:{{ mac }}
+dhcp-boot=net:{{ mac }},{{ uuid }}/pxelinux.0,{{ tftp_host }}
=== added file 'templates.desktop/iso-testing-initiator-config.xml'
--- templates.desktop/iso-testing-initiator-config.xml 1970-01-01 00:00:00 +0000
+++ templates.desktop/iso-testing-initiator-config.xml 2011-01-12 20:50:44 +0000
@@ -0,0 +1,83 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
+<project>
+ <actions/>
+ <description>Initiator job which monitors cdimage.ubuntu.com, sets up tests and then kickoff automated ISO testing process</description>
+ <keepDependencies>false</keepDependencies>
+ <properties>
+ <hudson.model.ParametersDefinitionProperty>
+ <parameterDefinitions>
+ <hudson.model.StringParameterDefinition>
+ <name>ISO_DIR</name>
+ <description>Directory containing .iso images to be tested or a specific path to a individual iso</description>
+ <defaultValue>${HOME}/reference/isos</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>TEST_CASES</name>
+ <description>Test cases to execute. Comma separated list of test cases or empty = run all tests.</description>
+ <defaultValue>openssh-server</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>TEST_TRACKER</name>
+ <description>Location of CouchDB to store configuration and test results.</description>
+ <defaultValue>http://192.168.122.112:5984</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>RELEASE</name>
+ <description>Release to download from image archive (i.e. maverick, lucid etc).</description>
+ <defaultValue>maverick</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>VARIANT</name>
+ <description>Variant to download from image archive (i.e server).</description>
+ <defaultValue>server</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ </parameterDefinitions>
+ </hudson.model.ParametersDefinitionProperty>
+ <hudson.plugins.disk__usage.DiskUsageProperty/>
+ </properties>
+ <scm class="hudson.scm.NullSCM"/>
+ <assignedNode>master</assignedNode>
+ <canRoam>true</canRoam>
+ <disabled>true</disabled>
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
+ <triggers class="vector">
+ <com.redfin.hudson.UrlChangeTrigger>
+ <spec></spec>
+ <url>http://cdimage.ubuntu.com/ubuntu-server/daily/current/SHA256SUMS</url>
+ </com.redfin.hudson.UrlChangeTrigger>
+ </triggers>
+ <concurrentBuild>false</concurrentBuild>
+ <builders>
+ <hudson.tasks.Shell>
+ <command>#!/bin/bash
+
+${HOME}/reference/iso-testing/download-latest-test-iso.py --release=${RELEASE} --variant=${VARIANT} --isoroot=${ISO_DIR}</command>
+ </hudson.tasks.Shell>
+ <hudson.tasks.Shell>
+ <command>#!/bin/bash
+
+${HOME}/reference/iso-testing/setup_iso_test.py ${ISO_DIR}/ubuntu-server ${TEST_CASES}</command>
+ </hudson.tasks.Shell>
+ </builders>
+ <publishers/>
+ <buildWrappers/>
+</project>
=== added file 'templates.desktop/iso-testing.ini'
--- templates.desktop/iso-testing.ini 1970-01-01 00:00:00 +0000
+++ templates.desktop/iso-testing.ini 2011-01-12 20:50:44 +0000
@@ -0,0 +1,25 @@
+;
+; Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+;
+; This file is part of ubuntu-server-iso-testing.
+;
+; ubuntu-server-iso-testing is free software: you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation, either version 3 of
+; the License, or (at your option) any later version.
+;
+; ubuntu-server-iso-testing is distributed in the hope that it will
+; be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with ubuntu-server-iso-testing. If not, see
+; <http://www.gnu.org/licenses/>.
+;
+
+; Bind couchdb onto all IP addresses
+[httpd]
+bind_address = 0.0.0.0
+
+
=== added file 'templates.desktop/libvirt.xml'
--- templates.desktop/libvirt.xml 1970-01-01 00:00:00 +0000
+++ templates.desktop/libvirt.xml 2011-01-12 20:50:44 +0000
@@ -0,0 +1,56 @@
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
+<domain type='kvm'>
+ <name>{{ name }}</name>
+ <uuid>{{ uuid }}</uuid>
+ <memory>1024000</memory>
+ <vcpu>1</vcpu>
+ <features>
+ <acpi/>
+ </features>
+ <os>
+ <type>hvm</type>
+ <boot dev='hd' />
+ <boot dev='network' />
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+{% for disk in disks %}
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='{{ disk.source }}'/>
+ <target dev='{{ disk.target }}' bus='{{ disk.bus }}'/>
+ </disk>
+{% endfor %}
+ <disk type='file' device='cdrom'>
+ <source file='{{ iso_file }}'/>
+ <target dev='hdc'/><readonly/>
+ </disk>
+ <interface type='network'>
+ <mac address='{{ mac }}'/>
+ <source network='default' />
+ <model type='virtio'/>
+ </interface>
+ <graphics type='vnc' listen='0.0.0.0'/>
+ </devices>
+</domain>
=== added file 'templates.desktop/libvirtd-iso-testing.conf'
--- templates.desktop/libvirtd-iso-testing.conf 1970-01-01 00:00:00 +0000
+++ templates.desktop/libvirtd-iso-testing.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Setup replacement configuration for dnsmasq used by libvirtd
+dhcp-no-override
+strict-order
+bind-interfaces
+listen-address=192.168.122.1
+except-interface=lo
+dhcp-range=192.168.122.100,192.168.122.254
+dhcp-lease-max=25
=== added file 'templates.desktop/preseed-config.xml'
--- templates.desktop/preseed-config.xml 1970-01-01 00:00:00 +0000
+++ templates.desktop/preseed-config.xml 2011-01-12 20:50:44 +0000
@@ -0,0 +1,87 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
+<project>
+ <actions/>
+ <description>Automated {{ release }} {{ arch }} {{ variant }} ISO test for {{ preseed }}</description>
+ <keepDependencies>false</keepDependencies>
+ <properties>
+ <hudson.model.ParametersDefinitionProperty>
+ <parameterDefinitions>
+ <hudson.model.StringParameterDefinition>
+ <name>RELEASE</name>
+ <description>Release name of ISO image to execute test against</description>
+ <defaultValue>{{ release }}</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>VARIANT</name>
+ <description>Variant of ISO image to execute test against</description>
+ <defaultValue>{{ variant }}</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>ARCH</name>
+ <description>Architecture of ISO image to execute test against</description>
+ <defaultValue>{{ arch }}</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ <hudson.model.StringParameterDefinition>
+ <name>PRESEED</name>
+ <description>Name of test preseed to execute</description>
+ <defaultValue>{{ preseed }}</defaultValue>
+ </hudson.model.StringParameterDefinition>
+ </parameterDefinitions>
+ </hudson.model.ParametersDefinitionProperty>
+ </properties>
+ <scm class="hudson.scm.NullSCM"/>
+ <assignedNode>virtual-host&&{{ arch }}</assignedNode>
+ <canRoam>false</canRoam>
+ <disabled>false</disabled>
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
+ <triggers class="vector">
+ <com.redfin.hudson.UrlChangeTrigger>
+ <spec></spec>
+ <url>http://cdimage.ubuntu.com/ubuntu-server/daily/current/SHA256SUMS</url>
+ </com.redfin.hudson.UrlChangeTrigger>
+ </triggers>
+ <concurrentBuild>false</concurrentBuild>
+ <builders>
+ <hudson.tasks.Shell>
+ <command>#!/bin/bash
+download-latest-test-iso --release=${RELEASE} --variant=${VARIANT} --arch=${ARCH}
+</command>
+ </hudson.tasks.Shell>
+ <hudson.tasks.Shell>
+ <command>#!/bin/bash
+run-test --release=${RELEASE} --variant=${VARIANT} --arch=${ARCH} ${PRESEED}
+</command>
+ </hudson.tasks.Shell>
+ </builders>
+ <publishers>
+ <hudson.tasks.ArtifactArchiver>
+ <artifacts>**/*</artifacts>
+ <latestOnly>false</latestOnly>
+ </hudson.tasks.ArtifactArchiver>
+ <hudson.tasks.junit.JUnitResultArchiver>
+ <testResults>**/test-results/*.xml</testResults>
+ <keepLongStdio>false</keepLongStdio>
+ <testDataPublishers/>
+ </hudson.tasks.junit.JUnitResultArchiver>
+ </publishers>
+ <buildWrappers/>
+</project>
=== added directory 'templates.desktop/preseeds-common'
=== added file 'templates.desktop/preseeds-common/base'
--- templates.desktop/preseeds-common/base 1970-01-01 00:00:00 +0000
+++ templates.desktop/preseeds-common/base 2011-01-12 20:50:44 +0000
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+### Localization
+# Locale sets language and country.
+d-i debian-installer/locale string en_CA.UTF-8
+
+# Keyboard selection.
+# Disable automatic (interactive) keymap detection.
+d-i console-setup/ask_detect boolean false
+#d-i console-setup/modelcode string pc105
+d-i console-setup/layoutcode string ca
+# To select a variant of the selected layout (if you leave this out, the
+# basic form of the layout will be used):
+#d-i console-setup/variantcode string dvorak
+
+
+
+
+{% block preseed_extra %}
+{% endblock %}
=== added file 'templates.desktop/pxelinux.0'
Binary files templates.desktop/pxelinux.0 1970-01-01 00:00:00 +0000 and templates.desktop/pxelinux.0 2011-01-12 20:50:44 +0000 differ
=== added file 'templates.desktop/pxelinuxcfg.install'
--- templates.desktop/pxelinuxcfg.install 1970-01-01 00:00:00 +0000
+++ templates.desktop/pxelinuxcfg.install 2011-01-12 20:50:44 +0000
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+prompt 0
+timeout 10
+default install
+
+label install
+kernel kernel
+initrd initrd
+append boot=casper -- locale=en_US console-setup/ask_detect=false console-setup/layoutcode=us
+
=== added file 'templates.desktop/rc.local'
--- templates.desktop/rc.local 1970-01-01 00:00:00 +0000
+++ templates.desktop/rc.local 2011-01-12 20:50:44 +0000
@@ -0,0 +1,17 @@
+#!/bin/sh -e
+#
+# rc.local
+#
+# This script is executed at the end of each multiuser runlevel.
+# Make sure that the script will "exit 0" on success or any other
+# value on error.
+#
+# In order to enable or disable this script just change the execution
+# bits.
+#
+
+# Kill libvirt dnsmasq
+pkill dnsmasq
+service dnsmasq restart
+
+exit 0
=== added file 'templates.desktop/run_test'
--- templates.desktop/run_test 1970-01-01 00:00:00 +0000
+++ templates.desktop/run_test 2011-01-12 20:50:44 +0000
@@ -0,0 +1,170 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+import datetime
+import json
+import logging, logging.handlers
+import optparse
+import os, os.path
+import subprocess
+import sys
+import time
+import urllib
+import urlparse
+
+import couchdb
+
+parser = optparse.OptionParser()
+parser.add_option("", "--sleep", type="float",
+ help="Sleep before starting (in seconds)")
+parser.add_option("", "--syslog",
+ dest="syslog", default=False, action="store_true",
+ help="Log to syslog")
+parser.add_option("", "--debug",
+ dest="debug", default=False, action="store_true",
+ help="Turn debugging on")
+parser.add_option("", "--test-dir",
+ default="/var/lib/tests",
+ help="Directory to store tests data")
+(options, args) = parser.parse_args()
+
+LOG_LEVEL = logging.INFO
+if options.debug:
+ LOG_LEVEL = logging.DEBUG
+
+# set up logging to file by default
+TEST_DIR = options.test_dir
+if not os.path.exists(TEST_DIR):
+ os.makedirs(TEST_DIR)
+
+logger = logging.getLogger(os.path.basename(sys.argv[0]))
+logger.setLevel(LOG_LEVEL)
+file_hdlr = logging.FileHandler(mode='a',
+ filename=os.path.join(options.test_dir,
+ 'run.log'))
+fmt = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')
+file_hdlr.setFormatter(fmt)
+logger.addHandler(file_hdlr)
+if options.debug:
+ logger.debug("Adding console logger")
+ console_hdlr = logging.StreamHandler()
+ fmt = logging.Formatter('%(levelname)s %(message)s')
+ console_hdlr.setFormatter(fmt)
+ logger.addHandler(console_hdlr)
+if options.syslog:
+ logger.debug("Adding syslog logger")
+ syslog_hdlr = logging.handlers.SysLogHandler(address='/dev/log',
+ facility=logging.handlers.SysLogHandler.LOG_DAEMON)
+ fmt = logging.Formatter('%(name)s %(levelname)s %(message)s')
+ syslog_hdlr.setFormatter(fmt)
+ logger.addHandler(syslog_hdlr)
+
+logger.debug("Options: %s" % (options))
+logger.debug("Args: %s" % (args))
+
+if options.sleep:
+ logger.info("Sleeping %s" % (options.sleep))
+ time.sleep(options.sleep)
+
+logger.info("Starting test run")
+test_docname = args[0]
+logger.debug("Getting test script from %s" % (test_docname))
+(s, n, p, q, f) = urlparse.urlsplit(test_docname)
+server_url = "%s://%s/" % (s, n)
+logger.debug("Testracker server: %s" % (server_url))
+server = couchdb.client.Server(server_url)
+db_name = p.split('/')[1]
+logger.debug("Testracker db: %s" % (db_name))
+db = server[db_name]
+test_id = p.split('/')[2]
+logger.debug("Test id: %s" % (test_id))
+test_scripts = filter(lambda n: n.startswith('tests/'),
+ db[test_id]['_attachments'].keys())
+logger.debug("Test scripts: %s" % (test_scripts))
+test_doc = db[test_id]
+test_doc['results'] = {}
+if test_doc['states'].has_key('testing'):
+ logging.warning('Test already run. Aborting.')
+ sys.exit(0)
+test_doc['states']['testing'] = datetime.datetime.utcnow().isoformat()
+db[test_id] = test_doc
+l_cwd = os.getcwd()
+
+for t in test_scripts:
+ logger.info("Running test %s" % (t))
+ report = { "started": datetime.datetime.utcnow().isoformat() }
+ test_doc = db[test_id]
+ test_doc['results'][os.path.basename(t)] = report
+ db[test_id] = test_doc
+ t_url = "%s/%s" % (test_docname, t)
+ logger.debug("Retrieving test script %s" % (t_url))
+ t_dir = os.path.join(TEST_DIR, t)
+ if not os.path.exists(t_dir):
+ os.makedirs(t_dir)
+ filename = os.path.join(t_dir, 'test.py')
+ (filename, headers) = urllib.urlretrieve(t_url, filename=filename)
+ os.chmod(filename, 0755)
+
+ logger.debug("Creating test stdout and stderr files")
+ test_stdout_fh = open(os.path.join(t_dir, "log.out"), mode='w+')
+ test_stderr_fh = open(os.path.join(t_dir, "log.err"), mode='w+')
+
+ logger.debug("Running script")
+ os.chdir(t_dir)
+ cmd = ['python','-m','subunit.run','test']
+ logger.debug("Cmd: %s" % (cmd))
+
+ testrun = subprocess.Popen(cmd,stdout=subprocess.PIPE,
+ stderr=test_stderr_fh)
+
+ cmd2 = ['subunit2junitxml']
+ logger.debug("Cmd: %s" % (cmd2))
+ subjunit = subprocess.Popen(cmd2, stdin=testrun.stdout,
+ stdout=test_stdout_fh)
+ testrun.wait()
+ subjunit.wait()
+
+ os.chdir(l_cwd)
+
+ logger.debug("Generating report")
+ test_stdout_fh.seek(0)
+ test_stderr_fh.seek(0)
+ test_doc = db[test_id]
+ report = test_doc['results'][os.path.basename(t)]
+ report["returncode"] = subjunit.returncode
+ report["script_stdout"] = test_stdout_fh.read()
+ report["script_stderr"] = test_stderr_fh.read()
+ report["finished"] = datetime.datetime.utcnow().isoformat()
+ logger.debug("Report: %s" % (report))
+ local_report_fh = open(os.path.join(t_dir, 'report'), 'w')
+ json.dump(report, local_report_fh)
+ local_report_fh.close()
+ test_doc = db[test_id]
+ test_doc['results'][os.path.basename(t)] = report
+ db[test_id] = test_doc
+
+test_doc = db[test_id]
+test_doc['states']['tested'] = datetime.datetime.utcnow().isoformat()
+db[test_id] = test_doc
+
+cmd = ["poweroff"]
+logger.debug("Cmd: %s" % (cmd))
+subprocess.check_call(cmd)
=== added file 'templates.desktop/run_test.wrapper'
--- templates.desktop/run_test.wrapper 1970-01-01 00:00:00 +0000
+++ templates.desktop/run_test.wrapper 2011-01-12 20:50:44 +0000
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# Description:
+# This script checks prerequisites before executing the main python script
+# Since we are installing packages from the network it requires a working network :-)
+#
+
+check_prerequisites() {
+ # Required packages
+ local packages="python-couchdb subunit python-subunit python-junitxml ldtp python-ldtp"
+
+ MISSING=""
+ for pkg in $packages; do
+ if ! dpkg-query -W -f '${Status}' $pkg 2>/dev/null|grep -qw ^install 2>&1; then
+ MISSING="$MISSING $pkg"
+ fi
+ done
+
+ if [ ! -z "$MISSING" ]; then
+ sudo sh -c "echo deb http://archive.ubuntu.com/ubuntu/ natty universe > /etc/apt/sources.list.d/universe.list"
+ sudo apt-get update
+ sudo apt-get install -qy $MISSING
+
+ # Free some space on the livecd
+ sudo apt-get clean
+ sudo rm /etc/apt/sources.list.d/universe.list
+ sudo apt-get update
+ fi
+
+}
+
+check_prerequisites
+
+RUNTEST=/usr/local/bin/run_test
+
+if [ -x "$RUNTEST" ]; then
+ sleep 30
+ $RUNTEST $@
+fi
=== added directory 'templates.desktop/test_cases'
=== added directory 'templates.desktop/test_cases/default'
=== added file 'templates.desktop/test_cases/default/preseed'
--- templates.desktop/test_cases/default/preseed 1970-01-01 00:00:00 +0000
+++ templates.desktop/test_cases/default/preseed 2011-01-12 20:50:44 +0000
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+{% extends "base" %}
=== added file 'templates.desktop/test_cases/default/test'
--- templates.desktop/test_cases/default/test 1970-01-01 00:00:00 +0000
+++ templates.desktop/test_cases/default/test 2011-01-12 20:50:44 +0000
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+import logging
+import os.path
+import unittest
+import ldtp, ooldtp
+
+logging.basicConfig(level=logging.DEBUG)
+
+class DefaultTest(unittest.TestCase):
+ main_window = 'frmInstall'
+ btn_forward = 'btnForward'
+ btn_installnow = 'btnInstallNow'
+ rbtn_useentiredisk = 'rbtnEraseandusetheentiredisk'
+ rbtn_loginautomatically = 'rbtnLoginautomatically'
+
+ txt_location = 'txt1' # Timezone selector
+ txt_fullname = 'txt5'
+ txt_hostname = 'txt3'
+ txt_username = 'txt4'
+ txt_password1 = 'txt7' # Password
+ txt_password2 = 'txt6' # Password confirmation
+
+ def _waittillenabled(self, ui, component_name, timeout = 300):
+ ldtp.wait(5) # UI is slow to react sometimes
+ component = ui.getchild(component_name)
+ while not component.stateenabled():
+ logging.debug("SMOKETEST: Waiting for %s. Till %d to go" % (component_name, timeout))
+ ldtp.wait(1)
+ timeout =- 1
+ if timeout < 0: return False
+ #ldtp.wait(2)
+ return True
+
+ def test_01Ubiquity(self):
+ # Content to fill the forms with
+ data = {
+ 'location':'London',
+ 'fullname':'Ubuntu Smoke Test User',
+ 'hostname':'smoketest',
+ 'username':'ubuntu',
+ 'password1':'ubuntu',
+ 'password2':'ubuntu'
+ }
+
+ logging.info("SMOKETEST: Launching Ubiquity")
+ ldtp.launchapp('ubiquity', ['gtk_ui'])
+ ldtp.waittillguiexist(self.main_window)
+ ui = ooldtp.context(self.main_window)
+
+ # First Screen
+ logging.info("SMOKETEST: Welcome Screen")
+ ldtp.wait(5)
+ ui.click(self.btn_forward)
+ self._waittillenabled(ui, self.btn_forward)
+
+ # Choose here if you want to install stuff from network
+ logging.info("SMOKETEST: Preparing to install Ubuntu")
+ logging.info("SMOKETEST: Leave defaults")
+ ui.click(self.btn_forward)
+ self._waittillenabled(ui, self.btn_forward)
+
+ # Drive setup
+ logging.info("SMOKETEST: Allocate Disk Drive")
+ logging.info("SMOKETEST: Use entire partition")
+ ui.click(self.rbtn_useentiredisk)
+ ui.click(self.btn_forward)
+ ldtp.wait(5)
+ ui.remap()
+ ldtp.wait(2)
+ self._waittillenabled(ui, self.btn_installnow)
+
+ logging.info("SMOKETEST: Allocate Drive Space")
+ logging.info("SMOKETEST: Leave defaults")
+ ui.click(self.btn_installnow)
+ ui.remap()
+ ldtp.wait(30)
+
+ # Location
+ logging.info("SMOKETEST: Where are you")
+ #self._waittillenabled(ui, self.btn_forward)
+ ui.settextvalue(self.txt_location, data['location'])
+ ui.click(self.btn_forward)
+ self._waittillenabled(ui, self.btn_forward)
+
+ # Keyboard
+ logging.info("SMOKETEST: Keyboard Layout")
+ ui.click(self.btn_forward)
+ self._waittillenabled(ui, self.btn_forward)
+
+ # User Identity
+ logging.debug("SMOKETEST: Who are you?")
+ ui.settextvalue(self.txt_fullname, data['fullname'])
+ ui.settextvalue(self.txt_hostname, data['hostname'])
+ ui.settextvalue(self.txt_username, data['username'])
+ ui.settextvalue(self.txt_password1, data['password1'])
+ ui.settextvalue(self.txt_password2, data['password2'])
+ ui.click(self.rbtn_loginautomatically)
+ ldtp.wait(2)
+ ui.click(self.btn_forward)
+
+ def test_10ReadWrite(self):
+ t_fh = open(os.path.join('/tmp', 'a'), 'w')
+ self.assertNotEqual(t_fh, None)
+ self.assertEqual(t_fh.write('a'), None)
+ self.assertEqual(t_fh.close(), None)
+
+if __name__ == '__main__':
+ unittest.main()
=== added file 'templates.desktop/tftp-iso-testing.conf'
--- templates.desktop/tftp-iso-testing.conf 1970-01-01 00:00:00 +0000
+++ templates.desktop/tftp-iso-testing.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Enable dnsmasq's built-in TFTP server
+enable-tftp
+
+# Set the root directory for files availble via TFTP.
+tftp-root=/var/lib/ubuntu-server-iso-testing/tftp
+
+# Make the TFTP server more secure: with this set, only files owned by
+# the user dnsmasq is running as will be send over the net.
+# tftp-secure
+
+# This option stops dnsmasq from negotiating a larger blocksize for TFTP
+# transfers. It will slow things down, but may rescue some broken TFTP
+# clients.
+# tftp-no-blocksize
+
=== added file 'templates.desktop/usit-dnsmasq'
--- templates.desktop/usit-dnsmasq 1970-01-01 00:00:00 +0000
+++ templates.desktop/usit-dnsmasq 2011-01-12 20:50:44 +0000
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Allow ubuntu-server-iso-testing to restart dnsmasq
+usit ALL=NOPASSWD: /usr/sbin/service dnsmasq restart
=== modified file 'templates/config.xml'
--- templates/config.xml 2010-09-28 11:57:23 +0000
+++ templates/config.xml 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
<project>
<actions/>
<description>Hudson wrapper to execute individual ISO build test.</description>
=== added file 'templates/dnsmasq-iso-testing.conf'
--- templates/dnsmasq-iso-testing.conf 1970-01-01 00:00:00 +0000
+++ templates/dnsmasq-iso-testing.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Additional configuration directory for ubuntu server iso testing
+conf-dir=/var/lib/ubuntu-server-iso-testing/dnsmasq.d
=== modified file 'templates/dnsmasq.conf'
--- templates/dnsmasq.conf 2010-08-27 19:52:09 +0000
+++ templates/dnsmasq.conf 2011-01-12 20:50:44 +0000
@@ -1,3 +1,22 @@
-dhcp-match=gpxe,175 # gPXE sends a 175 option.
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
dhcp-host={{ mac }},net:{{ mac }}
-dhcp-boot=net:{{ mac }},net:gpxe,{{ test_tracker }}/{{ test_db }}/{{ uuid }}/pxe/pxelinux.0
+dhcp-boot=net:{{ mac }},{{ uuid }}/pxelinux.0,{{ tftp_host }}
=== modified file 'templates/iso-testing-initiator-config.xml'
--- templates/iso-testing-initiator-config.xml 2010-09-28 12:50:20 +0000
+++ templates/iso-testing-initiator-config.xml 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
<project>
<actions/>
<description>Initiator job which monitors cdimage.ubuntu.com, sets up tests and then kickoff automated ISO testing process</description>
=== added file 'templates/iso-testing.ini'
--- templates/iso-testing.ini 1970-01-01 00:00:00 +0000
+++ templates/iso-testing.ini 2011-01-12 20:50:44 +0000
@@ -0,0 +1,25 @@
+;
+; Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+;
+; This file is part of ubuntu-server-iso-testing.
+;
+; ubuntu-server-iso-testing is free software: you can redistribute it
+; and/or modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation, either version 3 of
+; the License, or (at your option) any later version.
+;
+; ubuntu-server-iso-testing is distributed in the hope that it will
+; be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with ubuntu-server-iso-testing. If not, see
+; <http://www.gnu.org/licenses/>.
+;
+
+; Bind couchdb onto all IP addresses
+[httpd]
+bind_address = 0.0.0.0
+
+
=== modified file 'templates/libvirt.xml'
--- templates/libvirt.xml 2010-11-22 20:56:47 +0000
+++ templates/libvirt.xml 2011-01-12 20:50:44 +0000
@@ -1,3 +1,22 @@
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
<domain type='kvm'>
<name>{{ name }}</name>
<uuid>{{ uuid }}</uuid>
=== added file 'templates/libvirtd-iso-testing.conf'
--- templates/libvirtd-iso-testing.conf 1970-01-01 00:00:00 +0000
+++ templates/libvirtd-iso-testing.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Setup replacement configuration for dnsmasq used by libvirtd
+dhcp-no-override
+strict-order
+bind-interfaces
+listen-address=192.168.122.1
+except-interface=lo
+dhcp-range=192.168.122.100,192.168.122.254
+dhcp-lease-max=25
=== modified file 'templates/preseed-config.xml'
--- templates/preseed-config.xml 2010-10-01 15:53:16 +0000
+++ templates/preseed-config.xml 2011-01-12 20:50:44 +0000
@@ -1,7 +1,26 @@
<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+
+ This file is part of ubuntu-server-iso-testing.
+
+ ubuntu-server-iso-testing is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ ubuntu-server-iso-testing is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ubuntu-server-iso-testing. If not, see
+ <http://www.gnu.org/licenses/>.
+-->
<project>
<actions/>
- <description></description>
+ <description>Automated {{ release }} {{ arch }} {{ variant }} ISO test for {{ preseed }}</description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.model.ParametersDefinitionProperty>
@@ -22,21 +41,15 @@
<defaultValue>{{ arch }}</defaultValue>
</hudson.model.StringParameterDefinition>
<hudson.model.StringParameterDefinition>
- <name>ISO_DIR</name>
- <description>Location of ISO directory to be used to store ISO images downloaded by dl-ubuntu-test-iso</description>
- <defaultValue>${HOME}/reference/isos</defaultValue>
- </hudson.model.StringParameterDefinition>
- <hudson.model.StringParameterDefinition>
<name>PRESEED</name>
<description>Name of test preseed to execute</description>
<defaultValue>{{ preseed }}</defaultValue>
</hudson.model.StringParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
- <hudson.plugins.disk__usage.DiskUsageProperty/>
</properties>
<scm class="hudson.scm.NullSCM"/>
- <assignedNode>virtual-host</assignedNode>
+ <assignedNode>virtual-host&&{{ arch }}</assignedNode>
<canRoam>false</canRoam>
<disabled>false</disabled>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
@@ -50,12 +63,13 @@
<builders>
<hudson.tasks.Shell>
<command>#!/bin/bash
-${HOME}/reference/iso-testing/download-latest-test-iso.py --release=${RELEASE} --variant=${VARIANT} --arch=${ARCH} --isoroot=${ISO_DIR}
+download-latest-test-iso --release=${RELEASE} --variant=${VARIANT} --arch=${ARCH}
</command>
</hudson.tasks.Shell>
<hudson.tasks.Shell>
<command>#!/bin/bash
-${HOME}/reference/iso-testing/run-test.py --release=${RELEASE} --variant=${VARIANT} --arch=${ARCH} --isoroot=${ISO_DIR} ${PRESEED}</command>
+run-test --release=${RELEASE} --variant=${VARIANT} --arch=${ARCH} ${PRESEED}
+</command>
</hudson.tasks.Shell>
</builders>
<publishers>
=== modified file 'templates/preseeds-common/base'
--- templates/preseeds-common/base 2010-12-13 20:26:34 +0000
+++ templates/preseeds-common/base 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
### Localization
# Locale sets language and country.
d-i debian-installer/locale string en_CA.UTF-8
@@ -55,10 +75,10 @@
### Mirror settings
-d-i mirror/country string enter information manually
-d-i mirror/http/hostname string mirror:3142
-d-i mirror/http/directory string /ubuntu
-d-i mirror/http/proxy string
+#d-i mirror/country string enter information manually
+#d-i mirror/http/hostname string mirror:3142
+#d-i mirror/http/directory string /ubuntu
+d-i mirror/http/proxy string {{ proxyurl }}
# Suite to install.
#d-i mirror/suite string feisty
@@ -159,6 +179,8 @@
d-i passwd/user-password password !ubuntu123
d-i passwd/user-password-again password !ubuntu123
+# No boot splash screen.
+d-i debian-installer/splash boolean false
### Base system installation
# Select the initramfs generator used to generate the initrd for 2.6 kernels.
@@ -166,7 +188,7 @@
# Install the different kernel flavor.
{% block kernel_flavor %}
-d-i base-installer/kernel/override-image string linux-server
+d-i base-installer/kernel/override-image string linux-generic-pae
{% endblock %}
{% block anna_modules %}
@@ -191,6 +213,8 @@
#d-i grub-installer/only_debian boolean false
#d-i grub-installer/with_other_os boolean false
+# Wait for two seconds in grub
+d-i grub-installer/timeout string 2
### Package selection
=== modified file 'templates/pxelinuxcfg.install'
--- templates/pxelinuxcfg.install 2010-12-15 22:26:56 +0000
+++ templates/pxelinuxcfg.install 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
prompt 0
timeout 10
default install
=== added file 'templates/rc.local'
--- templates/rc.local 1970-01-01 00:00:00 +0000
+++ templates/rc.local 2011-01-12 20:50:44 +0000
@@ -0,0 +1,17 @@
+#!/bin/sh -e
+#
+# rc.local
+#
+# This script is executed at the end of each multiuser runlevel.
+# Make sure that the script will "exit 0" on success or any other
+# value on error.
+#
+# In order to enable or disable this script just change the execution
+# bits.
+#
+
+# Kill libvirt dnsmasq
+pkill dnsmasq
+service dnsmasq restart
+
+exit 0
=== modified file 'templates/run_test' (properties changed: -x to +x)
--- templates/run_test 2010-10-06 15:00:33 +0000
+++ templates/run_test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
import datetime
import json
=== modified file 'templates/test_cases/default/preseed'
--- templates/test_cases/default/preseed 2010-08-27 23:49:43 +0000
+++ templates/test_cases/default/preseed 2011-01-12 20:50:44 +0000
@@ -1,1 +1,21 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
=== modified file 'templates/test_cases/default/test'
--- templates/test_cases/default/test 2010-08-28 02:03:05 +0000
+++ templates/test_cases/default/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
import logging
import os.path
=== modified file 'templates/test_cases/dns-server/preseed'
--- templates/test_cases/dns-server/preseed 2010-08-30 18:17:09 +0000
+++ templates/test_cases/dns-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, DNS server
=== modified file 'templates/test_cases/dns-server/test'
--- templates/test_cases/dns-server/test 2010-12-02 14:40:57 +0000
+++ templates/test_cases/dns-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,23 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
import logging
import os.path
=== modified file 'templates/test_cases/lamp/preseed'
--- templates/test_cases/lamp/preseed 2010-08-27 23:52:30 +0000
+++ templates/test_cases/lamp/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, LAMP server
=== modified file 'templates/test_cases/lamp/test'
--- templates/test_cases/lamp/test 2010-08-28 01:29:23 +0000
+++ templates/test_cases/lamp/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== modified file 'templates/test_cases/lvm/preseed'
--- templates/test_cases/lvm/preseed 2010-08-27 23:51:45 +0000
+++ templates/test_cases/lvm/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block partman_auto_method %}
d-i partman-auto/method string lvm
=== modified file 'templates/test_cases/lvm/test'
--- templates/test_cases/lvm/test 2010-08-28 02:03:05 +0000
+++ templates/test_cases/lvm/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== modified file 'templates/test_cases/mail-server/preseed'
--- templates/test_cases/mail-server/preseed 2010-08-30 18:17:21 +0000
+++ templates/test_cases/mail-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, Mail server
=== modified file 'templates/test_cases/mail-server/test'
--- templates/test_cases/mail-server/test 2010-08-31 01:24:57 +0000
+++ templates/test_cases/mail-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import email.mime.text
import logging
=== modified file 'templates/test_cases/minimal-virtual/preseed'
--- templates/test_cases/minimal-virtual/preseed 2010-08-27 23:53:10 +0000
+++ templates/test_cases/minimal-virtual/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/skip-tasks string standard
=== modified file 'templates/test_cases/minimal-virtual/test'
--- templates/test_cases/minimal-virtual/test 2010-08-28 02:09:24 +0000
+++ templates/test_cases/minimal-virtual/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
@@ -50,7 +70,8 @@
lines = output.split("\n")
self.assertEqual(len(lines), 3)
used = int(lines[1].split()[2])
- self.assertTrue( used < 550000, "Used: %s" % (used))
+ # Increased +25MB to accomodate test overlay
+ self.assertTrue( used < 575000, "Used: %s" % (used))
if __name__ == '__main__':
unittest.main()
=== modified file 'templates/test_cases/openssh-server/preseed'
--- templates/test_cases/openssh-server/preseed 2010-08-30 18:17:35 +0000
+++ templates/test_cases/openssh-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, OpenSSH server
=== modified file 'templates/test_cases/openssh-server/test'
--- templates/test_cases/openssh-server/test 2010-08-30 18:17:35 +0000
+++ templates/test_cases/openssh-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== modified file 'templates/test_cases/postgresql-server/preseed'
--- templates/test_cases/postgresql-server/preseed 2010-08-30 18:17:58 +0000
+++ templates/test_cases/postgresql-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, PostgreSQL database
=== modified file 'templates/test_cases/postgresql-server/test'
--- templates/test_cases/postgresql-server/test 2010-09-29 20:47:55 +0000
+++ templates/test_cases/postgresql-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== modified file 'templates/test_cases/print-server/preseed'
--- templates/test_cases/print-server/preseed 2010-08-30 18:18:10 +0000
+++ templates/test_cases/print-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, Print server
=== modified file 'templates/test_cases/print-server/test'
--- templates/test_cases/print-server/test 2010-08-30 18:18:10 +0000
+++ templates/test_cases/print-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== modified file 'templates/test_cases/samba-server/preseed'
--- templates/test_cases/samba-server/preseed 2010-08-30 18:18:20 +0000
+++ templates/test_cases/samba-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, Samba file server
=== modified file 'templates/test_cases/samba-server/test'
--- templates/test_cases/samba-server/test 2010-10-08 10:33:25 +0000
+++ templates/test_cases/samba-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
@@ -32,18 +52,19 @@
self.assertNotEquals(output, "")
def testDefaultWorkgroup(self):
- cmd = ["net", "getlocalsid"]
+ cmd = ["sudo","net", "getlocalsid"]
logging.debug("Cmd: %s" % (cmd))
output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
logging.debug("Cmd output: %s" % (output))
self.assertTrue("SID for domain" in output)
- def testUserSidList(self):
- cmd = ["net", "usersidlist"]
+ def testWbinfoMinusU(self):
+ # Replaces net usersidlist as this sigsevs
+ cmd = ["wbinfo", "-u"]
logging.debug("Cmd: %s" % (cmd))
output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
logging.debug("Cmd output: %s" % (output))
- self.assertTrue("\ubuntu" in output)
+ self.assertTrue("ubuntu" in output)
if __name__ == '__main__':
unittest.main()
=== modified file 'templates/test_cases/tomcat-server/preseed'
--- templates/test_cases/tomcat-server/preseed 2010-08-30 18:18:31 +0000
+++ templates/test_cases/tomcat-server/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, Tomcat Java server
=== modified file 'templates/test_cases/tomcat-server/test'
--- templates/test_cases/tomcat-server/test 2010-09-27 11:28:14 +0000
+++ templates/test_cases/tomcat-server/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== modified file 'templates/test_cases/virtual-host/preseed'
--- templates/test_cases/virtual-host/preseed 2010-08-30 18:18:41 +0000
+++ templates/test_cases/virtual-host/preseed 2011-01-12 20:50:44 +0000
@@ -1,3 +1,23 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
{% extends "base" %}
{% block tasksel_first %}
tasksel tasksel/first multiselect Basic Ubuntu server, Virtual Machine host
=== modified file 'templates/test_cases/virtual-host/test'
--- templates/test_cases/virtual-host/test 2010-08-30 18:18:41 +0000
+++ templates/test_cases/virtual-host/test 2011-01-12 20:50:44 +0000
@@ -1,4 +1,24 @@
#!/usr/bin/python
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
import logging
import os.path
=== added file 'templates/tftp-iso-testing.conf'
--- templates/tftp-iso-testing.conf 1970-01-01 00:00:00 +0000
+++ templates/tftp-iso-testing.conf 2011-01-12 20:50:44 +0000
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Enable dnsmasq's built-in TFTP server
+enable-tftp
+
+# Set the root directory for files availble via TFTP.
+tftp-root=/var/lib/ubuntu-server-iso-testing/tftp
+
+# Make the TFTP server more secure: with this set, only files owned by
+# the user dnsmasq is running as will be send over the net.
+# tftp-secure
+
+# This option stops dnsmasq from negotiating a larger blocksize for TFTP
+# transfers. It will slow things down, but may rescue some broken TFTP
+# clients.
+# tftp-no-blocksize
+
=== added file 'templates/usit-dnsmasq'
--- templates/usit-dnsmasq 1970-01-01 00:00:00 +0000
+++ templates/usit-dnsmasq 2011-01-12 20:50:44 +0000
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2010, Canonical Ltd (http://www.canonical.com/)
+#
+# This file is part of ubuntu-server-iso-testing.
+#
+# ubuntu-server-iso-testing is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# ubuntu-server-iso-testing is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ubuntu-server-iso-testing. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Allow ubuntu-server-iso-testing to restart dnsmasq
+usit ALL=NOPASSWD: /usr/sbin/service dnsmasq restart
Follow ups