=== removed file 'COPYING.AGPL-3'
--- COPYING.AGPL-3	2011-06-23 18:32:55 +0000
+++ COPYING.AGPL-3	1970-01-01 00:00:00 +0000
@@ -1,661 +0,0 @@
-                    GNU AFFERO GENERAL PUBLIC LICENSE
-                       Version 3, 19 November 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 Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-our General Public Licenses are 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.
-
-  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.
-
-  Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
-  A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate.  Many developers of free software are heartened and
-encouraged by the resulting cooperation.  However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
-  The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community.  It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server.  Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
-  An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals.  This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
-  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 Affero 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. Remote Network Interaction; Use with the GNU General Public License.
-
-  Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software.  This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
-  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 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 work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details.
-
-    You should have received a copy of the GNU Affero 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 your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source.  For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code.  There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
-  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 AGPL, see
-<http://www.gnu.org/licenses/>.

=== removed file 'MANIFEST.in'
--- MANIFEST.in	2012-05-14 03:00:05 +0000
+++ MANIFEST.in	1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-recursive-include lava_scheduler_app/templates *.html *.txt
-recursive-include lava_scheduler_app/static *.js *.css *.gif

=== added file 'README.obsolete.txt'
--- README.obsolete.txt	1970-01-01 00:00:00 +0000
+++ README.obsolete.txt	2013-09-19 17:47:40 +0000
@@ -0,0 +1,3 @@
+This package is obsolete.
+
+See http://git.linaro.org/gitweb?p=lava/lava-scheduler.git instead

=== removed directory 'doc'
=== removed file 'doc/changes.rst'
--- doc/changes.rst	2013-01-30 04:38:16 +0000
+++ doc/changes.rst	1970-01-01 00:00:00 +0000
@@ -1,259 +0,0 @@
-Version History
-***************
-
-.. _version_0_28:
-
-Version 0.28
-============
-* remove oob-fd hack
-
-.. _version_0_27:
-
-Version 0.27
-============
-* prevent offline admin action from touching RETIRED boards
-* add a re-submit button
-
-.. _version_0_26:
-
-Version 0.26
-============
-* Added ability to annotate failures
-
-.. _version_0_25:
-
-Version 0.25
-============
-* proper remote worker support (without celery)
-
-.. _version_0_24_1:
-
-Version 0.24.1
-==============
-* Reject jobs with invalid server urls at submission time
-
-.. _version_0_24:
-
-Version 0.24
-============
-* Added job priority support
-
-.. _version_0_23:
-
-Version 0.23
-============
-* device version support
-* show more than 10 device types in main view
-
-.. _version_0_22_1:
-
-Version 0.22.1
-==============
-* A little more logging to try to diagnose #1043059.
-
-.. _version_0_22:
-
-Version 0.22
-============
-* Fix the tests.
-* Improve logging in scheduler daemon.
-* Make a few fkeys ON DELETE SET NULL.
-* Fix job page for jobs with no log file (as opposed to a missing log file).
-* update usage doc
-
-.. _version_0_21:
-
-Version 0.21
-============
-* Ability to hide a device type
-* Don't throw errors when job files are missing
-
-.. _version_0_20:
-
-Version 0.20
-============
-* improved jobs report charting visualization
-
-.. _version_0_19:
-
-Version 0.19
-============
-
-* make health job creation more like regular job creation
-* updates to support running jobs via celery
-* make admin page load faster for editing devices
-* add a link on job page to actual device it ran on
-* add a report for 5 longest running jobs
-
-.. _version_0_18:
-
-Version 0.18
-============
-
-* support linking job details to dashboard bundles
-
-.. _version_0_17_1:
-
-Version 0.17.1
-==============
-
-* version .17 didn't have the proper flot libraries in place for the new report
-
-.. _version_0_17:
-
-Version 0.17
-============
-
-* Use a more efficient query for the device type overview.
-* Add a reports page, with the first reports showing passing/failing
-  health jobs & all jobs.
-
-.. _version_0_16:
-
-Version 0.16
-============
-
-* Add a RETIRED status for boards.
-* Return a HTTP 403 not 404 when accessing a job that the logged in
-  user does not have permission to see.
-
-.. _version_0_15:
-
-Version 0.15
-============
-
-* Add a view showing the status of each device type.
-
-.. _version_0_14:
-
-Version 0.14
-============
-
-* Add resubmit_job to the API
-* Add support for looping of health care jobs
-
-.. _version_0_13:
-
-Version 0.13
-============
-
-* Allow job files to specify addresses to email on completion
-  (possibly only unsuccessful completion).
-
-.. _version_0_12_1:
-
-Version 0.12.1
-==============
-
-* Enforce limits on how long jobs can run for and how large log files
-  can grow to in the scheduler monitor.
-* When killing off a process, escalate through SIGINT, SIGTERM,
-  SIGKILL signals.
-
-.. _version_0_12:
-
-Version 0.12
-============
-* Two fixes around job privacy:
-  * Display ValueErrors raised by from_json_and_user nicely to API users.
-  * Allow submission to anonymous streams again.
-* Job view improvements:
-  * Show all dispatcher logs.
-  * Highlight action lines.
-  * Add link to download log file in summary page.
-  * If the job log view is scrolled to the bottom when new output arrives, keep
-    the view at the bottom.
-
-.. _version_0_11:
-
-Version 0.11
-============
-* Improvements to the magic ajax tables -- render the initial content
-  of the table in the html to avoid requiring several requests to load
-  one page.
-* Make TestJob a restricted resource, and update views to reflect
-  restrictions.
-* Add admin action to set the health_status of all boards with pass
-  status to unknown status -- for use after a rollout.
-* Update to use the version of the ajax tables code that has been
-  moved to lava-server.
-* Validate the job file much more thoroughly when it is submitted.
-* Allow for the creation of private jobs by copying the access data
-  from the target bundle stream over to the created job at submit
-  time.
-
-.. _version_0_10.1:
-
-Version 0.10.1
-==============
-* fix duplicate names for some views
-
-.. _version_0_10:
-
-Version 0.10
-============
-* Introduce health check jobs
-  * These are defined on the device type and run when a board is put
-    online or when no health check job has run for 24 hours
-  * There are also views to just look at the health status of a board
-    or the lab as a whole.
-* The scheduler monitor is more reliably told where to log.
-* Make all tables paginated via server-side ajax magic.
-
-.. _version_0_9:
-
-Version 0.9
-===========
-* Make alljobs paginated so that it will load very quickly
-* handle invalid values for start in job_output
-* record device status transitions
-* ask for a reason when offlining/onlining a board
-* display transitions on the device page
-
-.. _version_0_8:
-
-Version 0.8
-===========
-* improvements to the docs from Adam Konarski
-* make submit_job give slightly more useful permission errors
-* restore code to allow submission of results to a private bundle
-* reject unknown jobs at submit time
-
-.. _version_0_7_3:
-
-Version 0.7.3
-=============
-* Don't assume dispatcher log files contain valid unicode (#918954)
-* Include static assets in the sdist (multiply reported as: #919079,
-  #919047, #917393)
-
-.. _version_0_7_2:
-
-Version 0.7.2
-=============
-* Revert 'allow results to be submitted to non-anonymous bundle streams' as it
-  caused the entire job to be deleted when it completed.
-
-.. _version_0_7_1:
-
-Version 0.7.1
-=============
-* Allow results to be submitted to non-anonymous bundle streams
-* Improved job view when log files are missing
-* Fixed some issues with device tags and postgres
-
-.. _version_0_7_0:
-
-Version 0.7.0
-=============
-
-*  Add support for device tags in the scheduler
-*  Overhaul of the job view
-*  Fix unit tests
-
-.. _version_0_5_5:
-
-Version 0.5.5
-=============
-
-* Add some docs for lava-scheduler

=== removed file 'doc/conf.py'
--- doc/conf.py	2013-08-28 15:13:07 +0000
+++ doc/conf.py	1970-01-01 00:00:00 +0000
@@ -1,204 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# LAVA Dashboard documentation build configuration file, created by
-# sphinx-quickstart on Mon Dec 27 16:39:47 2010.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys
-import os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append(os.path.abspath('..'))
-
-# -- General configuration -----------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage']
-
-# Configuration for sphinx.ext.todo
-todo_include_todos = True
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = []
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'LAVA Scheduler'
-copyright = u'2010-2011, Linaro Limited'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-import versiontools
-import lava_scheduler_app
-version = "%d.%d" % lava_scheduler_app.__version__[0:2]
-# The full version, including alpha/beta/rc tags.
-release = versiontools.format_version(lava_scheduler_app.__version__)
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directory, that shouldn't be searched
-# for source files.
-exclude_trees = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  Major themes that come with
-# Sphinx are currently 'default' and 'sphinxdoc'.
-html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = []
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_use_modindex = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'LAVADocumentation'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-    ('index', 'LAVAScheduler.tex', u'LAVA Scheduler Documentation',
-     u'Linaro Validation Team', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_use_modindex = True
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'http://docs.python.org/': None}

=== removed file 'doc/index.rst'
--- doc/index.rst	2012-01-28 17:44:18 +0000
+++ doc/index.rst	1970-01-01 00:00:00 +0000
@@ -1,49 +0,0 @@
-============================
-LAVA Scheduler Documentation
-============================
-
-.. warning::
-    This document is *work in progress*.
-
-Features
-========
-The LAVA Scheduler is an extension to LAVA Server that handles
-scheduling of test resources, accepts jobs, and dispatches them on
-systems while monitoring the job.
-
-
-Indices and tables
-==================
-
-.. toctree::
-    :maxdepth: 2
-    
-    installation.rst
-    running.rst
-    usage.rst
-    process.rst
-    changes.rst
-
-* :ref:`search`
-
-
-TODO List
-=========
-
-This documentation is not finished (not even close yet). The following list
-contains items that need more work.
-
-.. note::
-    The source code for this document can be found in the lp:lava-project
-    branch. Please contribute patches to make the TODO list shorter.
-
-.. todolist::
-
-.. _questions:
-
-Questions
-^^^^^^^^^
-
-If you have any questions, including to the content of this document, feel free
-to ask them here: https://answers.launchpad.net/lava-project
-

=== removed file 'doc/installation.rst'
--- doc/installation.rst	2013-09-11 15:55:32 +0000
+++ doc/installation.rst	1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-Installation
-^^^^^^^^^^^^
-
-The scheduler should be installed along with all other LAVA components and
-prerequisites by using the `lava-deployment-tool </static/docs/deployment-tool.html>`_
-documentation on any LAVA instance.

=== removed file 'doc/process.rst'
--- doc/process.rst	2011-11-16 21:02:31 +0000
+++ doc/process.rst	1970-01-01 00:00:00 +0000
@@ -1,64 +0,0 @@
-Development process
-===================
-
-LAVA development process is based on Launchpad. If you are not familiar with
-that system you should read the https://help.launchpad.net/ guide first. This
-guide also includes the basics of Bazaar, our version control system of choice.
-
-Most of the work is done by the members of the Linaro Validation Team (you can
-learn more about this team, in particular here:
-launchpad.net/~linaro-validation). Having said that, the code is free and open
-source software, we welcome third party contributions and new team members.
-
-Our team is spread geographically around the world, with some members in
-Europe, America, Asia and Oceania. We are usually talking on our IRC channel
-#linaro. 
-
-
-Release process 
-^^^^^^^^^^^^^^^
-
-LAVA is being developed on a monthly release schedule. Each release is tagged
-around 20th of each month. We publish all our releases on pypi (for actual
-consumption, packaging, installation, etc.) and Launchpad (for reference).
-
-Launchpad release tarballs are following our YYYY.MM (year, month) pattern.
-Should we need to release an upgrade to any existing release (such as a
-critical bug fix) we append a sequential number preceded by a dash
-(YYYY.MM-NN).
-
-Our PyPi releases use sensible version numbers instead. In general we use
-MAJOR.MINOR.MICRO pattern (where MICRO is omitted when zero). Some components
-are post 1.0, that is they have a major version greater than zero. For such
-components we take extra care to ensure API stability, with sensible transition
-periods, deprecation warnings and more. For other components (that have zero as
-a major release number) our strategy is to keep them compatible as much as
-possible but without ensuring a third party developer code would still work on
-each upgrade.
-
-
-Reporting Bugs
-^^^^^^^^^^^^^^
-
-New bugs can be reported here https://bugs.launchpad.net/lava/+filebug.
-
-If you are not sure which component is affected simply report it to any of the
-LAVA sub-projects and let us handle the rest. As with any bug reports please
-describe the problem and the version of LAVA you ware using.
-
-If you were using our public LAVA instance, the one used by Linaro for daily
-activities (http://validation.linaro.org) try to include a link to a page
-that manifests the problem as that makes debugging easier.
-
-
-Patches, fixes and code
-^^^^^^^^^^^^^^^^^^^^^^^
-
-If you'd like to offer a patch (whether it is a bug fix, documentation update,
-new feature or even a simple typo) it is best to follow this simple check-list:
-
-1. Download the trunk of the correct project
-2. Add your code, change any existing files as needed
-3. Commit in your local branch
-4. Push to launchpad (to the public copy of your branch)
-5. Propose a merge request

=== removed file 'doc/running.rst'
--- doc/running.rst	2011-12-01 03:31:16 +0000
+++ doc/running.rst	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-Running LAVA Scheduler
-^^^^^^^^^^^^^^^^^^^^^^
-
-LAVA Scheduler has two main components, the web application and the
-daemon.  To process jobs, the scheduler daemon must be running.  Jobs
-are accepted via the xmlrpc API on the web application.
-
-Adding Devices
-**************
-Before jobs can be submitted or processed, devices must exist to run
-them on.  To do this, login as an admin user in LAVA Server.
-
-First, create a device type unless you are just adding a device for
-which you have already created a type.  To create a device type from the
-admin console, click the *Add* button next to *Device types* under the
-*Lava_Scheduler_App* section.  You only need to provide the name.  Other
-attributes of the device type such as default boot parameters will be
-defined in the LAVA Dispatcher configuration files.
-
-Once you have at least one device type, devices can be added from the
-admin console as well.  To add a device, click the *Add* button next to
-*Devices* under the *Lava_Scheduler_App* section.  Select the device
-type and add the name of the device you wish to add.  The name given
-here needs to correspond to the name of the device in the LAVA
-Dispatcher config.
-
-Running the Scheduler Daemon
-****************************
-
-If you installed from source or from pypi, you can start it manually
-by simply running *lava-server manage lava-scheduler*, or by adding an
-init script for it.

=== removed file 'doc/usage.rst'
--- doc/usage.rst	2012-10-23 07:12:53 +0000
+++ doc/usage.rst	1970-01-01 00:00:00 +0000
@@ -1,77 +0,0 @@
-Using LAVA Scheduler
-^^^^^^^^^^^^^^^^^^^^
-
-Submitting Jobs
-***************
-Jobs can currently be submitted to the scheduler in one of two ways:
-through the *lava-scheduler-tool* command line tool, or directly via
-xmlrpc API.
-
-Generating a Token
-==================
-Before a job can be submitted, a token must be generated. You can create a
-token from the *API* menu at the top, then select *Authentication
-Tokens*. From this page, click on *Create a new token*.  Once you have
-created at least one token, you can click *Display this token* to show
-it.  The token string can be copied from the browser for pasting into a
-tool later, or saved to a file.
-
-*NOTE*: Your user account may need the proper permission to allow it to
-submit jobs. The user account will need two permissions::
-
-  lava_scheduler_app | test job | Can add test job
-  linaro_django_xmlrpc | auth token | Can add auth token
-
-added to it via the Django admin panel.
-
-Configuring lava-scheduler-tool
-===============================
-There are 3 ways to install the tool::
-
-  # easiest
-  sudo add-apt-repository ppa:linaro-maintainers/tools
-  sudo apt-get update
-  sudo apt-get install lava-scheduler-tool
-
-  # from pypi
-  pip install lava-scheduler-tool
-
-  # from source for development with:
-  bzr branch lp:lava-scheduler-tool
-  cd lava-scheduler-tool ; ./setup.py develop
-
-You'll probaly also want the lava-dashboard-tool installed as well. This can
-be done using the same steps as outlined above.
-
-To submit jobs using the scheduler, you should first set up the server
-to which you will be submitting jobs::
-
- $ lava-tool auth-add https://user@example.com/RPC2/
-
-In this example, *user@example.com* should be replaced with your userid
-and webserver.  Using https is *highly* recommended since it will ensure
-the token is passed to the server using ssl, but http will work if your
-web server is not configured for ssl.
-
-When entering this command, you will be prompted to enter the token.
-Copy/paste the text of the token from your browser window here; it will
-not be echoed to the screen.  Alternatively, you can also save the token
-to a file and use the --token-file parameter to specify the file
-containing your token.
-
-Using lava-scheduler-tool
-=========================
-
-The first thing you may want to do is create a bundle stream in the LAVA
-dashboard where you'll put your bundles. This is done with::
-
-  lava-dashboard-tool make-stream --dashboard-url http://example.com/RPC2/ /anonymous/USERNAME/
-
-Next you'll need a job file. You can read about an example job file `here`_
-
-.. _here: http://lava.readthedocs.org/en/latest/qemu-deploy.html
-
-You can now submit jobs by running ::
-
- $ lava scheduler submit-job http://user@example.com/RPC2/ jobfile.json
-

=== removed file 'fake-dispatcher'
--- fake-dispatcher	2013-01-15 02:23:49 +0000
+++ fake-dispatcher	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-# This is just a silly fake dispatcher script that can be used to test
-# the scheduler without requiring real hardware to be present.  To use
-# it, run "lava-scheduler manage scheduler --use-fake".  If you want
-# to test something in particular, just hack it as required...
-
-# This makes this script not exit when sent SIGINT, to test the
-# killing of jobs that do not die easily.
-trap "" 2
-
-echo starting processing $1
-echo error >&2
-for i in `seq 10`; do
-echo p $i
-sleep 1
-done

=== removed directory 'lava_scheduler_app'
=== removed file 'lava_scheduler_app/__init__.py'
--- lava_scheduler_app/__init__.py	2013-01-30 04:38:16 +0000
+++ lava_scheduler_app/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-
-__version__ = (0, 28, 0, "final", 0)

=== removed file 'lava_scheduler_app/admin.py'
--- lava_scheduler_app/admin.py	2013-09-02 15:14:15 +0000
+++ lava_scheduler_app/admin.py	1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
-from django.contrib import admin
-from lava_scheduler_app.models import (
-    Device, DeviceStateTransition, DeviceType, TestJob, Tag, JobFailureTag,
-)
-
-# XXX These actions should really go to another screen that asks for a reason.
-# Sounds tedious to implement though.
-
-
-def offline_action(modeladmin, request, queryset):
-    for device in queryset.filter(status__in=[Device.IDLE, Device.RUNNING, Device.RESERVED]):
-        if device.can_admin(request.user):
-            device.put_into_maintenance_mode(request.user, "admin action")
-offline_action.short_description = "take offline"
-
-
-def online_action(modeladmin, request, queryset):
-    for device in queryset.filter(status__in=[Device.OFFLINE, Device.OFFLINING]):
-        if device.can_admin(request.user):
-            device.put_into_online_mode(request.user, "admin action")
-online_action.short_description = "take online"
-
-
-def retire_action(modeladmin, request, queryset):
-    for device in queryset:
-        if device.can_admin(request.user):
-            new_status = device.RETIRED
-            DeviceStateTransition.objects.create(
-                created_by=request.user, device=device, old_state=device.status,
-                new_state=new_status, message="retiring", job=None).save()
-            device.status = new_status
-            device.save()
-retire_action.short_description = "retire"
-
-
-def health_unknown(modeladmin, request, queryset):
-    for device in queryset.filter(health_status=Device.HEALTH_PASS):
-        device.health_status = Device.HEALTH_UNKNOWN
-        device.save()
-health_unknown.short_description = "set health_status to unknown"
-
-
-class DeviceAdmin(admin.ModelAdmin):
-    actions = [online_action, offline_action, health_unknown, retire_action]
-    list_filter = ['device_type', 'status']
-    raw_id_fields = ['current_job', 'last_health_report_job']
-
-
-class TestJobAdmin(admin.ModelAdmin):
-    list_filter = ['status']
-    raw_id_fields = ['_results_bundle']
-
-
-class DeviceStateTransitionAdmin(admin.ModelAdmin):
-    raw_id_fields = ['job']
-
-
-admin.site.register(Device, DeviceAdmin)
-admin.site.register(DeviceStateTransition, DeviceStateTransitionAdmin)
-admin.site.register(DeviceType)
-admin.site.register(TestJob, TestJobAdmin)
-admin.site.register(Tag)
-admin.site.register(JobFailureTag)

=== removed file 'lava_scheduler_app/api.py'
--- lava_scheduler_app/api.py	2013-09-13 11:39:18 +0000
+++ lava_scheduler_app/api.py	1970-01-01 00:00:00 +0000
@@ -1,304 +0,0 @@
-import xmlrpclib
-from simplejson import JSONDecodeError
-from django.db.models import Count
-from linaro_django_xmlrpc.models import ExposedAPI
-from lava_scheduler_app.models import (
-    Device,
-    DeviceType,
-    JSONDataError,
-    DevicesUnavailableException,
-    TestJob,
-)
-from lava_scheduler_app.views import (
-    SumIf
-)
-
-
-class SchedulerAPI(ExposedAPI):
-
-    def submit_job(self, job_data):
-        if not self.user:
-            raise xmlrpclib.Fault(
-                401, "Authentication with user and token required for this "
-                "API.")
-        if not self.user.has_perm('lava_scheduler_app.add_testjob'):
-            raise xmlrpclib.Fault(
-                403, "Permission denied.  User %r does not have the "
-                "'lava_scheduler_app.add_testjob' permission.  Contact "
-                "the administrators." % self.user.username)
-        try:
-            job = TestJob.from_json_and_user(job_data, self.user)
-        except JSONDecodeError as e:
-            raise xmlrpclib.Fault(400, "Decoding JSON failed: %s." % e)
-        except (JSONDataError, ValueError) as e:
-            raise xmlrpclib.Fault(400, str(e))
-        except Device.DoesNotExist:
-            raise xmlrpclib.Fault(404, "Specified device not found.")
-        except DeviceType.DoesNotExist:
-            raise xmlrpclib.Fault(404, "Specified device type not found.")
-        except DevicesUnavailableException as e:
-            raise xmlrpclib.Fault(400, str(e))
-        if isinstance(job, type(list())):
-            return job
-        else:
-            return job.id
-
-    def resubmit_job(self, job_id):
-        try:
-            job = TestJob.objects.accessible_by_principal(self.user).get(pk=job_id)
-        except TestJob.DoesNotExist:
-            raise xmlrpclib.Fault(404, "Specified job not found.")
-        if job.is_multinode:
-            return self.submit_job(job.multinode_definition)
-        else:
-            return self.submit_job(job.definition)
-
-    def cancel_job(self, job_id):
-        if not self.user:
-            raise xmlrpclib.Fault(401, "Authentication required.")
-        job = TestJob.objects.get(pk=job_id)
-        if not job.can_cancel(self.user):
-            raise xmlrpclib.Fault(403, "Permission denied.")
-        if job.is_multinode:
-            multinode_jobs = TestJob.objects.all().filter(
-                target_group=job.target_group)
-            for multinode_job in multinode_jobs:
-                multinode_job.cancel()
-        else:
-            job.cancel()
-        return True
-
-    def job_output(self, job_id):
-        """
-        Name
-        ----
-        `job_output` (`job_id`)
-
-        Description
-        -----------
-        Get the output of given job id.
-
-        Arguments
-        ---------
-        `job_id`: string
-            Job id for which the output is required.
-
-        Return value
-        ------------
-        This function returns an XML-RPC binary data of output file, provided
-        the user is authenticated with an username and token.
-        """
-
-        if not self.user:
-            raise xmlrpclib.Fault(
-                401, "Authentication with user and token required for this "
-                "API.")
-
-        try:
-            job = TestJob.objects.accessible_by_principal(self.user).get(
-                pk=job_id)
-        except TestJob.DoesNotExist:
-            raise xmlrpclib.Fault(404, "Specified job not found.")
-
-        return xmlrpclib.Binary(job.output_file().read())
-
-    def all_devices(self):
-        """
-        Name
-        ----
-        `all_devices` ()
-
-        Description
-        -----------
-        Get all the available devices with their state and type information.
-
-        Arguments
-        ---------
-        None
-
-        Return value
-        ------------
-        This function returns an XML-RPC array in which each item is a list of
-        device hostname, device type and device state. For example:
-
-        [['panda01', 'panda', 'running'], ['qemu01', 'qemu', 'idle']]
-        """
-
-        devices = Device.objects.values_list('hostname',
-                                             'device_type__name',
-                                             'status')
-        devices = [list((x[0], x[1], Device.STATUS_CHOICES[x[2]][1].lower()))
-                   for x in devices]
-
-        return devices
-
-    def all_device_types(self):
-        """
-        Name
-        ----
-        `all_device_types` ()
-
-        Description
-        -----------
-        Get all the available device types with their state and count
-        information.
-
-        Arguments
-        ---------
-        None
-
-        Return value
-        ------------
-        This function returns an XML-RPC array in which each item is a dict
-        which contains name (device type), idle, busy, offline counts.
-        For example:
-
-        [{'idle': 1, 'busy': 0, 'name': 'panda', 'offline': 0},
-        {'idle': 1, 'busy': 0, 'name': 'qemu', 'offline': 0}]
-        """
-
-        device_type_list = []
-        keys = ['busy', 'name', 'idle', 'offline']
-
-        device_types = DeviceType.objects.filter(display=True)\
-            .annotate(idle=SumIf('device', condition='status=%s' % Device.IDLE),
-                      offline=SumIf('device', condition='status in (%s,%s)'
-                                                        % (Device.OFFLINE, Device.OFFLINING)),
-                      busy=SumIf('device', condition='status in (%s,%s)'
-                                                     % (Device.RUNNING, Device.RESERVED)), ).order_by('name')
-
-        for dev_type in device_types:
-            device_type = {}
-            for key in keys:
-                device_type[key] = getattr(dev_type, key)
-            device_type_list.append(device_type)
-
-        return device_type_list
-
-    def pending_jobs_by_device_type(self):
-        """
-        Name
-        ----
-        `pending_jobs_by_device_type` ()
-
-        Description
-        -----------
-        Get number of pending jobs in each device type.
-
-        Arguments
-        ---------
-        None
-
-        Return value
-        ------------
-        This function returns a dict where the key is the device type and
-        the value is the number of jobs pending in that device type.
-        For example:
-
-        {'qemu': 0, 'panda': 3}
-        """
-
-        pending_jobs_by_device = {}
-
-        jobs_res = TestJob.objects.filter(status=TestJob.SUBMITTED)\
-            .values_list('requested_device_type_id')\
-            .annotate(pending_jobs=(Count('id')))
-        jobs = {}
-        jobs_hash = dict(jobs_res)
-        for job in jobs_hash:
-            if job:
-                jobs[job] = jobs_hash[job]
-        pending_jobs_by_device.update(jobs)
-
-        # Get rest of the devices and put number of pending jobs as 0.
-        device_types = DeviceType.objects.values_list('name', flat=True)
-        for device_type in device_types:
-            if device_type not in pending_jobs_by_device:
-                pending_jobs_by_device[device_type] = 0
-
-        return pending_jobs_by_device
-
-    def job_details(self, job_id):
-        """
-        Name
-        ----
-        `job_details` (`job_id`)
-
-        Description
-        -----------
-        Get the details of given job id.
-
-        Arguments
-        ---------
-        `job_id`: string
-            Job id for which the output is required.
-
-        Return value
-        ------------
-        This function returns an XML-RPC structures of job details, provided
-        the user is authenticated with an username and token.
-        """
-
-        if not self.user:
-            raise xmlrpclib.Fault(
-                401, "Authentication with user and token required for this "
-                "API.")
-
-        try:
-            job = TestJob.objects.accessible_by_principal(self.user).get(
-                pk=job_id)
-        except TestJob.DoesNotExist:
-            raise xmlrpclib.Fault(404, "Specified job not found.")
-
-        return job
-
-    def job_status(self, job_id):
-        """
-        Name
-        ----
-        `job_status` (`job_id`)
-
-        Description
-        -----------
-        Get the status of given job id.
-
-        Arguments
-        ---------
-        `job_id`: string
-            Job id for which the output is required.
-
-        Return value
-        ------------
-        This function returns an XML-RPC structures of job status with the follwing fields.
-        The user is authenticated with an username and token.
-
-        `job_status`: string
-                    ['Submitted'|'Running'|'Complete'|'Incomplete'|'Canceled'|'Canceling']
-
-        `bundle_sha1`: string
-                     The sha1 hash code of the bundle, if it existed. Otherwise it will be an empty string.
-        """
-
-        if not self.user:
-            raise xmlrpclib.Fault(
-                401, "Authentication with user and token required for this "
-                "API.")
-
-        try:
-            job = TestJob.objects.accessible_by_principal(self.user).get(
-                pk=job_id)
-        except TestJob.DoesNotExist:
-            raise xmlrpclib.Fault(404, "Specified job not found.")
-
-        bundle_sha1 = ""
-        try:
-            bundle_sha1 = job.results_link.split('/')[-2]
-        except:
-            pass
-
-        job_status = {
-            'job_status': job.get_status_display(),
-            'bundle_sha1': bundle_sha1
-        }
-
-        return job_status

=== removed file 'lava_scheduler_app/extension.py'
--- lava_scheduler_app/extension.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/extension.py	1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
-# Copyright (C) 2010, 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of LAVA Server.
-#
-# LAVA Server is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# LAVA Server 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 Affero General Public License
-# along with LAVA Server.  If not, see <http://www.gnu.org/licenses/>.
-
-from lava_server.extension import LavaServerExtension, Menu
-
-
-class SchedulerExtension(LavaServerExtension):
-    """
-    Demo extension that shows how to integrate third party
-    components into LAVA server.
-    """
-
-    @property
-    def app_name(self):
-        return "lava_scheduler_app"
-
-    @property
-    def api_class(self):
-        from lava_scheduler_app.api import SchedulerAPI
-        return SchedulerAPI
-
-    @property
-    def name(self):
-        return "Scheduler"
-
-    @property
-    def main_view_name(self):
-        return "lava_scheduler_app.views.index"
-
-    def get_menu(self):
-        from django.core.urlresolvers import reverse
-        menu = super(SchedulerExtension, self).get_menu()
-        menu.sub_menu = [
-            Menu("Status", reverse("lava.scheduler")),
-            Menu("Jobs", reverse("lava.scheduler.job.list")),
-            Menu("Reports", reverse("lava.scheduler.reports")),
-            Menu("Submit Job", reverse("lava.scheduler.job.submit")),
-        ]
-        return menu
-
-    @property
-    def description(self):
-        return "Scheduler application for LAVA server"
-
-    @property
-    def version(self):
-        import versiontools
-        import lava_scheduler_app
-        return versiontools.format_version(
-            lava_scheduler_app.__version__, lava_scheduler_app)
-
-    def contribute_to_settings(self, settings_module):
-        super(SchedulerExtension, self).contribute_to_settings(settings_module)
-        settings_module['INSTALLED_APPS'].append('django_tables2')
-        from_module = settings_module.get('SCHEDULER_DAEMON_OPTIONS', {})
-        settings_module['SCHEDULER_DAEMON_OPTIONS'] = {
-            'LOG_FILE_PATH': None,
-            'LOG_LEVEL': "WARNING",
-            # 500 megs should be enough for anyone
-            'LOG_FILE_SIZE_LIMIT': 500 * 1024 * 1024,
-            # Jobs always specify a timeout, but I suspect its often too low.
-            # So we don't let it go below this value, which defaults to a day.
-            'MIN_JOB_TIMEOUT': 24 * 60 * 60,
-        }
-        settings_module['SCHEDULER_DAEMON_OPTIONS'].update(from_module)
-        prepend_label_apps = settings_module.get('STATICFILES_PREPEND_LABEL_APPS', [])
-        if self.app_name in prepend_label_apps:
-            prepend_label_apps.remove(self.app_name)
-
-    def contribute_to_settings_ex(self, settings_module, settings_object):
-        super(SchedulerExtension, self).contribute_to_settings_ex(
-            settings_module, settings_object)
-        settings_module['SCHEDULER_DAEMON_OPTIONS'].update(
-            settings_object.get_setting('SCHEDULER_DAEMON_OPTIONS', {}))

=== removed file 'lava_scheduler_app/logfile_helper.py'
--- lava_scheduler_app/logfile_helper.py	2013-09-05 16:43:28 +0000
+++ lava_scheduler_app/logfile_helper.py	1970-01-01 00:00:00 +0000
@@ -1,91 +0,0 @@
-import re
-
-
-def getDispatcherErrors(logfile):
-    errors = ""
-    for line in logfile:
-        if line.find("CriticalError:") != -1 or \
-           line.find("OperationFailed:") != -1 or \
-           line.find("ErrorMessage:") != -1 or \
-           line.find("Lava failed on test:") != -1:
-            errors += line
-
-    return errors
-
-
-def getDispatcherLogMessages(logfile):
-    logs = []
-    log_prefix = '<LAVA_DISPATCHER>'
-    action_begin = '[ACTION-B]'
-    level_pattern = re.compile('....-..-.. (..:..:.. .. ([A-Z]+): .*)')
-    for line in logfile:
-        # log_prefix not always start at beginning of the line
-        pos = line.find(log_prefix)
-        if pos == -1:  # log_prefix not found
-            continue
-        if pos > 0:  # remove log_prefix leading characters
-            line = line[pos:-1]
-
-        line = line[len(log_prefix):].strip()
-        match = level_pattern.match(line)
-        if not match:
-            continue
-        line = match.group(1)
-        if len(line) > 120:
-            line = line[:120] + '...'
-        if line.find(action_begin) != -1:
-            logs.append((match.group(2), line, "action"))
-        else:
-            logs.append((match.group(2), line, ""))
-    return logs
-
-
-class Sections:
-    def __init__(self):
-        self.sections = []
-        self.cur_section_type = None
-        self.cur_section = []
-
-    def push(self, sect_type, line):
-        if sect_type != self.cur_section_type:
-            self.close()
-            self.cur_section_type = sect_type
-        self.cur_section.append(line)
-
-    def close(self):
-        if self.cur_section_type is not None:
-            self.sections.append(
-                (self.cur_section_type,
-                 len(self.cur_section),
-                 ''.join(self.cur_section)))
-        self.cur_section_type = None
-        self.cur_section = []
-
-
-def formatLogFile(logfile):
-    if not logfile:
-        return [('log', 1, "Log file is missing")]
-
-    sections = Sections()
-
-    for line in logfile:
-        line = line.replace('\r', '')
-        line = unicode(line, 'ascii', 'replace')
-        if not line:
-            continue
-        if line == 'Traceback (most recent call last):\n':
-            sections.push('traceback', line)
-        elif sections.cur_section_type == 'traceback':
-            sections.push('traceback', line)
-            if not line.startswith(' '):
-                sections.close()
-            continue
-        elif line.find("<LAVA_DISPATCHER>") != -1 \
-                or line.find("lava_dispatcher") != -1 \
-                or line.find("CriticalError:") != -1:
-            sections.push('log', line)
-        else:
-            sections.push('console', line)
-    sections.close()
-
-    return sections.sections

=== removed directory 'lava_scheduler_app/management'
=== removed file 'lava_scheduler_app/management/__init__.py'
=== removed directory 'lava_scheduler_app/management/commands'
=== removed file 'lava_scheduler_app/management/commands/__init__.py'
--- lava_scheduler_app/management/commands/__init__.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/management/commands/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,94 +0,0 @@
-import logging.config
-from optparse import make_option
-
-from django.core.management.base import BaseCommand
-
-
-class SchedulerCommand(BaseCommand):
-
-    option_list = BaseCommand.option_list + (
-        make_option('-l', '--loglevel',
-                    action='store',
-                    default=None,
-                    help="Log level, default is taken from settings."),
-        make_option('-f', '--logfile',
-                    action='store',
-                    default=None,
-                    help="Path to log file, default is taken from settings."),
-    )
-
-    log_prefix = ''
-
-    _DEFAULT_LOGGING = {
-        'version': 1,
-        'disable_existing_loggers': True,
-        'root': {
-            'level': None,
-            'handlers': ['default'],
-        },
-        'formatters': {
-            'default': {
-                'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
-            },
-        },
-        'handlers': {
-            'default': {
-                'level': 'DEBUG',
-                'class': 'logging.FileHandler',
-                'formatter': 'verbose'
-            }
-        },
-    }
-
-    def _configure(self, options):
-        from django.conf import settings
-
-        daemon_options = settings.SCHEDULER_DAEMON_OPTIONS.copy()
-        if options['logfile'] is not None:
-            daemon_options['LOG_FILE_PATH'] = options['logfile']
-        if options['loglevel'] is not None:
-            daemon_options['LOG_LEVEL'] = options['loglevel']
-
-        if daemon_options['LOG_FILE_PATH'] in [None, '-']:
-            handler = {
-                'level': 'DEBUG',
-                'class': 'logging.StreamHandler',
-                'formatter': 'default',
-            }
-        else:
-            handler = {
-                'level': 'DEBUG',
-                'class': 'logging.FileHandler',
-                'filename': daemon_options['LOG_FILE_PATH'],
-                'formatter': 'default'
-            }
-
-        fmt = "%(asctime)s [%(levelname)s] [%(name)s] %(message)s"
-        if self.log_prefix:
-            fmt = self.log_prefix + ' ' + fmt
-
-        LOGGING = {
-            'version': 1,
-            'disable_existing_loggers': True,
-            'root': {
-                'level': daemon_options['LOG_LEVEL'].upper(),
-                'handlers': ['default'],
-            },
-            'formatters': {'default': {'format': fmt}},
-            'handlers': {'default': handler}
-        }
-
-        try:
-            import lava.raven
-        except ImportError:
-            pass
-        else:
-            LOGGING['handlers']['sentry'] = {
-                'level': 'ERROR',
-                'class': 'raven.contrib.django.handlers.SentryHandler',
-            }
-            LOGGING['root']['handlers'].append('sentry')
-
-        logging.config.dictConfig(LOGGING)
-
-        return daemon_options

=== removed file 'lava_scheduler_app/management/commands/scheduler.py'
--- lava_scheduler_app/management/commands/scheduler.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/management/commands/scheduler.py	1970-01-01 00:00:00 +0000
@@ -1,64 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from optparse import make_option
-
-from lava_scheduler_app.management.commands import SchedulerCommand
-
-
-class Command(SchedulerCommand):
-
-    help = "Run the LAVA test job scheduler"
-    option_list = SchedulerCommand.option_list + (
-        make_option('--use-fake',
-                    action='store_true',
-                    dest='use_fake',
-                    default=False,
-                    help="Use fake dispatcher (for testing)"),
-        make_option('--dispatcher',
-                    action="store",
-                    dest="dispatcher",
-                    default="lava-dispatch",
-                    help="Dispatcher command to invoke"),
-    )
-
-    def handle(self, *args, **options):
-        import os
-
-        from twisted.internet import reactor
-
-        from lava_scheduler_daemon.service import JobQueue
-        from lava_scheduler_daemon.dbjobsource import DatabaseJobSource
-
-        daemon_options = self._configure(options)
-
-        source = DatabaseJobSource()
-
-        if options['use_fake']:
-            import lava_scheduler_app
-            opd = os.path.dirname
-            dispatcher = os.path.join(
-                opd(opd(os.path.abspath(lava_scheduler_app.__file__))),
-                'fake-dispatcher')
-        else:
-            dispatcher = options['dispatcher']
-        service = JobQueue(
-            source, dispatcher, reactor, daemon_options=daemon_options)
-        reactor.callWhenRunning(service.startService)
-        reactor.run()

=== removed file 'lava_scheduler_app/management/commands/schedulermonitor.py'
--- lava_scheduler_app/management/commands/schedulermonitor.py	2013-08-28 13:13:46 +0000
+++ lava_scheduler_app/management/commands/schedulermonitor.py	1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-import simplejson
-
-
-from lava_scheduler_app.management.commands import SchedulerCommand
-from lava_scheduler_daemon.dbjobsource import DatabaseJobSource
-
-
-class Command(SchedulerCommand):
-
-    help = "Run the LAVA test job scheduler"
-
-    log_prefix = 'M'
-
-    def handle(self, *args, **options):
-        from twisted.internet import reactor
-        from lava_scheduler_daemon.job import Job
-        daemon_options = self._configure(options)
-        source = DatabaseJobSource()
-        dispatcher, board_name, json_file = args
-
-        job = Job(
-            simplejson.load(open(json_file)), dispatcher,
-            source, board_name, reactor, daemon_options=daemon_options)
-
-        def run():
-            job.run().addCallback(lambda result: reactor.stop())
-        reactor.callWhenRunning(run)
-        reactor.run()

=== removed file 'lava_scheduler_app/management/commands/testjobmigrate.py'
--- lava_scheduler_app/management/commands/testjobmigrate.py	2012-06-22 01:57:03 +0000
+++ lava_scheduler_app/management/commands/testjobmigrate.py	1970-01-01 00:00:00 +0000
@@ -1,34 +0,0 @@
-import sys
-
-from django.core.management.base import BaseCommand
-from django.db.models import Q
-
-from dashboard_app.models import Bundle
-from lava_scheduler_app.models import TestJob
-
-
-class Command(BaseCommand):
-
-    help = "Fill out results_bundle on old testjobs."
-
-    option_list = BaseCommand.option_list
-
-    def handle(self, *args, **options):
-        count = 0
-        query = TestJob.objects.filter(
-            ~Q(_results_link=u''), _results_link__isnull=False,
-            _results_bundle__isnull=True)
-        print query.count()
-        for job in query.all():
-            count += 1
-            if count % 100 == 0:
-                sys.stdout.write('.')
-                sys.stdout.flush()
-            sha1 = job.results_link.strip('/').split('/')[-1]
-            try:
-                bundle = Bundle.objects.get(content_sha1=sha1)
-            except Bundle.DoesNotExist:
-                continue
-            job._results_bundle = bundle
-            job.save()
-        print

=== removed directory 'lava_scheduler_app/migrations'
=== removed file 'lava_scheduler_app/migrations/0001_initial.py'
--- lava_scheduler_app/migrations/0001_initial.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0001_initial.py	1970-01-01 00:00:00 +0000
@@ -1,112 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding model 'DeviceType'
-        db.create_table('lava_scheduler_app_devicetype', (
-            ('name', self.gf('django.db.models.fields.SlugField')(max_length=50, primary_key=True, db_index=True)),
-        ))
-        db.send_create_signal('lava_scheduler_app', ['DeviceType'])
-
-        # Adding model 'Device'
-        db.create_table('lava_scheduler_app_device', (
-            ('hostname', self.gf('django.db.models.fields.CharField')(max_length=200, primary_key=True)),
-            ('device_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.DeviceType'])),
-            ('current_job', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.TestJob'], unique=True, null=True, blank=True)),
-            ('status', self.gf('django.db.models.fields.IntegerField')(default=1)),
-        ))
-        db.send_create_signal('lava_scheduler_app', ['Device'])
-
-        # Adding model 'TestJob'
-        db.create_table('lava_scheduler_app_testjob', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('submitter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
-            ('target', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.Device'], null=True)),
-            ('device_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.DeviceType'])),
-            ('submit_time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
-            ('start_time', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
-            ('end_time', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
-            ('status', self.gf('django.db.models.fields.IntegerField')(default=0)),
-            ('definition', self.gf('django.db.models.fields.TextField')()),
-        ))
-        db.send_create_signal('lava_scheduler_app', ['TestJob'])
-
-    def backwards(self, orm):
-
-        # Deleting model 'DeviceType'
-        db.delete_table('lava_scheduler_app_devicetype')
-
-        # Deleting model 'Device'
-        db.delete_table('lava_scheduler_app_device')
-
-        # Deleting model 'TestJob'
-        db.delete_table('lava_scheduler_app_testjob')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.Device']", 'null': 'True'})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0002_auto__chg_field_testjob_device_type.py'
--- lava_scheduler_app/migrations/0002_auto__chg_field_testjob_device_type.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0002_auto__chg_field_testjob_device_type.py	1970-01-01 00:00:00 +0000
@@ -1,80 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'TestJob.device_type'
-        db.alter_column('lava_scheduler_app_testjob', 'device_type_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.DeviceType'], null=True))
-
-    def backwards(self, orm):
-
-        # User chose to not deal with backwards NULL issues for 'TestJob.device_type'
-        raise RuntimeError("Cannot reverse this migration. 'TestJob.device_type' and its values cannot be restored.")
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']", 'null': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.Device']", 'null': 'True'})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0003_auto__add_field_testjob_requested_device__add_field_testjob_requested_.py'
--- lava_scheduler_app/migrations/0003_auto__add_field_testjob_requested_device__add_field_testjob_requested_.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0003_auto__add_field_testjob_requested_device__add_field_testjob_requested_.py	1970-01-01 00:00:00 +0000
@@ -1,95 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.requested_device'
-        db.add_column('lava_scheduler_app_testjob', 'requested_device', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='+', null=True, to=orm['lava_scheduler_app.Device']), keep_default=False)
-
-        # Adding field 'TestJob.requested_device_type'
-        db.add_column('lava_scheduler_app_testjob', 'requested_device_type', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='+', null=True, to=orm['lava_scheduler_app.DeviceType']), keep_default=False)
-
-        # Adding field 'TestJob.actual_device'
-        db.add_column('lava_scheduler_app_testjob', 'actual_device', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='+', null=True, to=orm['lava_scheduler_app.Device']), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.requested_device'
-        db.delete_column('lava_scheduler_app_testjob', 'requested_device_id')
-
-        # Deleting field 'TestJob.requested_device_type'
-        db.delete_column('lava_scheduler_app_testjob', 'requested_device_type_id')
-
-        # Deleting field 'TestJob.actual_device'
-        db.delete_column('lava_scheduler_app_testjob', 'actual_device_id')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']", 'null': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.Device']", 'null': 'True'})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0004_fill_out_device_fields.py'
--- lava_scheduler_app/migrations/0004_fill_out_device_fields.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0004_fill_out_device_fields.py	1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
-# encoding: utf-8
-from south.v2 import DataMigration
-
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        "Write your forwards methods here."
-        for job in orm.TestJob.objects.all():
-            job.requested_device = job.target
-            if job.status != 0:
-                job.actual_device = job.target
-            if not job.target:
-                job.requested_device_type = job.device_type
-            job.save()
-
-    def backwards(self, orm):
-        "Write your backwards methods here."
-        for job in orm.TestJob.objects.all():
-            job.target = job.requested_device
-            job.device_type = job.requested_device.device_type
-            job.save()
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']", 'null': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.Device']", 'null': 'True'})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0005_auto__del_field_testjob_device_type__del_field_testjob_target.py'
--- lava_scheduler_app/migrations/0005_auto__del_field_testjob_device_type__del_field_testjob_target.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0005_auto__del_field_testjob_device_type__del_field_testjob_target.py	1970-01-01 00:00:00 +0000
@@ -1,87 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Deleting field 'TestJob.device_type'
-        db.delete_column('lava_scheduler_app_testjob', 'device_type_id')
-
-        # Deleting field 'TestJob.target'
-        db.delete_column('lava_scheduler_app_testjob', 'target_id')
-
-    def backwards(self, orm):
-
-        # Adding field 'TestJob.device_type'
-        db.add_column('lava_scheduler_app_testjob', 'device_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.DeviceType'], null=True), keep_default=False)
-
-        # Adding field 'TestJob.target'
-        db.add_column('lava_scheduler_app_testjob', 'target', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.Device'], null=True), keep_default=False)
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0006_auto__add_field_testjob_log_file.py'
--- lava_scheduler_app/migrations/0006_auto__add_field_testjob_log_file.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0006_auto__add_field_testjob_log_file.py	1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.log_file'
-        db.add_column('lava_scheduler_app_testjob', 'log_file', self.gf('django.db.models.fields.files.FileField')(default=None, max_length=100, null=True), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.log_file'
-        db.delete_column('lava_scheduler_app_testjob', 'log_file')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.Device']", 'null': 'True'})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0007_merged_migration.py'
--- lava_scheduler_app/migrations/0007_merged_migration.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0007_merged_migration.py	1970-01-01 00:00:00 +0000
@@ -1,77 +0,0 @@
-# encoding: utf-8
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        pass
-
-    def backwards(self, orm):
-        pass
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0008_auto__add_field_testjob_results_link.py'
--- lava_scheduler_app/migrations/0008_auto__add_field_testjob_results_link.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0008_auto__add_field_testjob_results_link.py	1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.results_link'
-        db.add_column('lava_scheduler_app_testjob', 'results_link', self.gf('django.db.models.fields.CharField')(default=None, max_length=400, null=True, blank=True), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.results_link'
-        db.delete_column('lava_scheduler_app_testjob', 'results_link')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0009_auto__add_field_testjob_description.py'
--- lava_scheduler_app/migrations/0009_auto__add_field_testjob_description.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0009_auto__add_field_testjob_description.py	1970-01-01 00:00:00 +0000
@@ -1,84 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.description'
-        db.add_column('lava_scheduler_app_testjob', 'description', self.gf('django.db.models.fields.CharField')(default='', max_length=200), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.description'
-        db.delete_column('lava_scheduler_app_testjob', 'description')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '200'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0010_auto__chg_field_testjob_description.py'
--- lava_scheduler_app/migrations/0010_auto__chg_field_testjob_description.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0010_auto__chg_field_testjob_description.py	1970-01-01 00:00:00 +0000
@@ -1,84 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'TestJob.description'
-        db.alter_column('lava_scheduler_app_testjob', 'description', self.gf('django.db.models.fields.CharField')(max_length=200, null=True))
-
-    def backwards(self, orm):
-
-        # Changing field 'TestJob.description'
-        db.alter_column('lava_scheduler_app_testjob', 'description', self.gf('django.db.models.fields.CharField')(max_length=200))
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0011_auto__add_tag.py'
--- lava_scheduler_app/migrations/0011_auto__add_tag.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0011_auto__add_tag.py	1970-01-01 00:00:00 +0000
@@ -1,120 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding model 'Tag'
-        db.create_table('lava_scheduler_app_tag', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, db_index=True)),
-            ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
-        ))
-        db.send_create_signal('lava_scheduler_app', ['Tag'])
-
-        # Adding M2M table for field tags on 'Device'
-        db.create_table('lava_scheduler_app_device_tags', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('device', models.ForeignKey(orm['lava_scheduler_app.device'], null=False)),
-            ('tag', models.ForeignKey(orm['lava_scheduler_app.tag'], null=False))
-        ))
-        db.create_unique('lava_scheduler_app_device_tags', ['device_id', 'tag_id'])
-
-        # Adding M2M table for field tags on 'TestJob'
-        db.create_table('lava_scheduler_app_testjob_tags', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testjob', models.ForeignKey(orm['lava_scheduler_app.testjob'], null=False)),
-            ('tag', models.ForeignKey(orm['lava_scheduler_app.tag'], null=False))
-        ))
-        db.create_unique('lava_scheduler_app_testjob_tags', ['testjob_id', 'tag_id'])
-
-    def backwards(self, orm):
-
-        # Deleting model 'Tag'
-        db.delete_table('lava_scheduler_app_tag')
-
-        # Removing M2M table for field tags on 'Device'
-        db.delete_table('lava_scheduler_app_device_tags')
-
-        # Removing M2M table for field tags on 'TestJob'
-        db.delete_table('lava_scheduler_app_testjob_tags')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0012_auto__add_field_testjob_submit_token.py'
--- lava_scheduler_app/migrations/0012_auto__add_field_testjob_submit_token.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0012_auto__add_field_testjob_submit_token.py	1970-01-01 00:00:00 +0000
@@ -1,102 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.submit_token'
-        db.add_column('lava_scheduler_app_testjob', 'submit_token', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['linaro_django_xmlrpc.AuthToken'], null=True), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.submit_token'
-        db.delete_column('lava_scheduler_app_testjob', 'submit_token_id')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'z53d9om32nyy04rnuhy09xi5emz00f02igc497gjpz8lkjd02uijemou95fyyjfgrsttfzbg4hm0y10u5jbpcxyfowq669b6q6ud6z6rjkbzgatobh066exd45rx88q7'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0013_auto__add_devicestatetransition.py'
--- lava_scheduler_app/migrations/0013_auto__add_devicestatetransition.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0013_auto__add_devicestatetransition.py	1970-01-01 00:00:00 +0000
@@ -1,123 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding model 'DeviceStateTransition'
-        db.create_table('lava_scheduler_app_devicestatetransition', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('created_on', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
-            ('created_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
-            ('device', self.gf('django.db.models.fields.related.ForeignKey')(related_name='transitions', to=orm['lava_scheduler_app.Device'])),
-            ('job', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.TestJob'], null=True, blank=True)),
-            ('old_state', self.gf('django.db.models.fields.IntegerField')()),
-            ('new_state', self.gf('django.db.models.fields.IntegerField')()),
-            ('message', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
-        ))
-        db.send_create_signal('lava_scheduler_app', ['DeviceStateTransition'])
-
-    def backwards(self, orm):
-
-        # Deleting model 'DeviceStateTransition'
-        db.delete_table('lava_scheduler_app_devicestatetransition')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'7omt7ki208qrgeoltltir1le0c9xka9u70j8guza8i8j1zjmpibxnwyzor8w3d07kngkzfiqo7fo80gx0x3yxxhxm9byfb00ylso2odh53odiz35u0djul4qhp2i0hew'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0014_auto__add_field_device_health_status__add_field_device_last_health_rep.py'
--- lava_scheduler_app/migrations/0014_auto__add_field_device_health_status__add_field_device_last_health_rep.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0014_auto__add_field_device_health_status__add_field_device_last_health_rep.py	1970-01-01 00:00:00 +0000
@@ -1,121 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'Device.health_status'
-        db.add_column('lava_scheduler_app_device', 'health_status', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
-
-        # Adding field 'Device.last_health_report_job'
-        db.add_column('lava_scheduler_app_device', 'last_health_report_job', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name=u'Health Report Job', unique=True, null=True, to=orm['lava_scheduler_app.TestJob']), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'Device.health_status'
-        db.delete_column('lava_scheduler_app_device', 'health_status')
-
-        # Deleting field 'Device.last_health_report_job'
-        db.delete_column('lava_scheduler_app_device', 'last_health_report_job_id')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'Health Report Job'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'wxahi36scmitudt29p0u6qx6ktiq2d0od7uuq0ptklddiiayy1g1yf24p51qlbgbsns74dfdq0bwzz1uh0o4ps5981c2eu0hdrix0smnz4sftf9uros2z002t7gttc5h'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0015_auto__add_field_testjob_health_check.py'
--- lava_scheduler_app/migrations/0015_auto__add_field_testjob_health_check.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0015_auto__add_field_testjob_health_check.py	1970-01-01 00:00:00 +0000
@@ -1,116 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.health_check'
-        db.add_column('lava_scheduler_app_testjob', 'health_check', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.health_check'
-        db.delete_column('lava_scheduler_app_testjob', 'health_check')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'Current Job'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'Health Report Job'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'ezum04q7hfcefuclm2hfdaeh9n5mljd2r6uo6ua440j2p2grb6aspla2o0p0t1jl7udoqehyk2qgy50zryucuj1mwtttdqhceg00dfy0gdcmsbexhf0e7o2ndd73ndjb'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0016_auto__add_field_devicetype_health_check_job.py'
--- lava_scheduler_app/migrations/0016_auto__add_field_devicetype_health_check_job.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0016_auto__add_field_devicetype_health_check_job.py	1970-01-01 00:00:00 +0000
@@ -1,117 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'DeviceType.health_check_job'
-        db.add_column('lava_scheduler_app_devicetype', 'health_check_job', self.gf('django.db.models.fields.TextField')(default=None, null=True, blank=True), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'DeviceType.health_check_job'
-        db.delete_column('lava_scheduler_app_devicetype', 'health_check_job')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'558rhcm45h7251wlnrp2aotn8x2a2ta8cq6qjkm8rzi8snjd702xs81jw7ocle3fik1cq11a3iwt10wkxg2l3w4i5mynzo7kq07d50hfpmkpx5kbn83l0esdh648n77k'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0017_add_lava_health_user.py'
--- lava_scheduler_app/migrations/0017_add_lava_health_user.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0017_add_lava_health_user.py	1970-01-01 00:00:00 +0000
@@ -1,121 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.v2 import DataMigration
-
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        # because the 'frozen' auth.User doesn't have its usual custom manager
-        # or convenience methods, they are inlined here.
-        now = datetime.datetime.now()
-        new_user = orm['auth.User'](
-            username='lava-health', email='lava@lava.invalid', is_staff=False,
-            is_active=True, is_superuser=False, last_login=now,
-            date_joined=now)
-        new_user.password = '!'
-        new_user.save()
-
-    def backwards(self, orm):
-        orm['auth.User'].objects.filter(username='lava-health').delete()
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'tna03mimg70u3tl70fb1t66pu3rp6m6kg3844s3ngwulis85chbt32foe2u49rau01rzw3dfydqc0ugsngubfjqz3zp0tze0zkncapi90bsybh84kls58572go0ggaz4'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py'
--- lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py	1970-01-01 00:00:00 +0000
@@ -1,131 +0,0 @@
-# encoding: utf-8
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Adding field 'TestJob.user'
-        db.add_column('lava_scheduler_app_testjob', 'user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True), keep_default=False)
-
-        # Adding field 'TestJob.group'
-        db.add_column('lava_scheduler_app_testjob', 'group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Group'], null=True, blank=True), keep_default=False)
-
-        # Adding field 'TestJob.is_public'
-        db.add_column('lava_scheduler_app_testjob', 'is_public', self.gf('django.db.models.fields.BooleanField')(default=True), keep_default=False)
-
-    def backwards(self, orm):
-
-        # Deleting field 'TestJob.user'
-        db.delete_column('lava_scheduler_app_testjob', 'user_id')
-
-        # Deleting field 'TestJob.group'
-        db.delete_column('lava_scheduler_app_testjob', 'group_id')
-
-        # Deleting field 'TestJob.is_public'
-        db.delete_column('lava_scheduler_app_testjob', 'is_public')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'g13kpfwrkljb08chbabb0zyr642p4ukfqoc18qxmjc1zefpb0cfeddzotwot4cs1ltzh83wl5g0e7177da4n0nn5zmax8hyo8se7cbqf784y8qe6m03g0ch90uwfbpry'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0019_set_testjob_owner.py'
--- lava_scheduler_app/migrations/0019_set_testjob_owner.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0019_set_testjob_owner.py	1970-01-01 00:00:00 +0000
@@ -1,120 +0,0 @@
-# encoding: utf-8
-from south.v2 import DataMigration
-from django.db import models
-
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        "Write your forwards methods here."
-        orm['lava_scheduler_app.TestJob'].objects.update(
-            user=models.F('submitter'))
-
-    def backwards(self, orm):
-        "Write your backwards methods here."
-        orm['lava_scheduler_app.TestJob'].objects.update(
-            user=None)
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'ymu1iwklrasagpior1qddpatt0qzmf6lcy5bhctm7q4csn4gnjq5wizxljd60j4acjpjhkfiu3bc6ze6f3xakitusy0ujjiu6j2sxz0itgwf2g4h6lcmu07h98mqdtne'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0020_auto__add_field_testjob__results_bundle.py'
--- lava_scheduler_app/migrations/0020_auto__add_field_testjob__results_bundle.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0020_auto__add_field_testjob__results_bundle.py	1970-01-01 00:00:00 +0000
@@ -1,148 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    depends_on = [
-        ('dashboard_app', '0001_initial'),
-    ]
-
-    def forwards(self, orm):
-        # Adding field 'TestJob._results_bundle'
-        db.add_column('lava_scheduler_app_testjob', '_results_bundle',
-                      self.gf('django.db.models.fields.related.OneToOneField')(to=orm['dashboard_app.Bundle'], unique=True, null=True, db_column='results_bundle_id', blank=True),
-                      keep_default=False)
-
-    def backwards(self, orm):
-        # Deleting field 'TestJob._results_bundle'
-        db.delete_column('lava_scheduler_app_testjob', 'results_bundle_id')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['dashboard_app.Bundle']", 'unique': 'True', 'null': 'True', 'db_column': "'results_bundle_id'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'h6kq4ozukdkya8a00fat2mn16gs9i75p15xmz1oy5q5bi0u6g04xfzsiiolqq131dnxy70ffpue6m7cg7awasgdx21x7txuk848r5isj1m8kw822z8n00bh6y9kyaew3'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0021_rename_results_link.py'
--- lava_scheduler_app/migrations/0021_rename_results_link.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0021_rename_results_link.py	1970-01-01 00:00:00 +0000
@@ -1,154 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-    """When faced with a field name change that does not affect the db_column,
-    in this case:
-
-    results_link = models.CharField(
-        max_length=400, default=None, null=True, blank=True)
-
-    becoming:
-
-    _results_link = models.CharField(
-        max_length=400, default=None, null=True, blank=True, db_column="results_link")
-
-    schemamigration --auto wants to delete and re-add the field.  That's not
-    at all what we want here, so this empty migration allows south to know
-    about this change without actually touching the db at all.
-    """
-
-    def forwards(self, orm):
-        pass
-
-    def backwards(self, orm):
-        pass
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Bundle']", 'null': 'True', 'db_column': "'results_bundle_id'", 'blank': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'dous3jo4hqd6e52q3s52t90dt8uebg4igr60u4a70x052l8wob80ha0ppilxjcm75ymkhrlgpyoppnccn1riu9ckp20wu9jtyptd037few649pglrwom1gntkjpzib52'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0022_auto__chg_field_testjob__results_bundle__add_unique_testjob__results_b.py'
--- lava_scheduler_app/migrations/0022_auto__chg_field_testjob__results_bundle__add_unique_testjob__results_b.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0022_auto__chg_field_testjob__results_bundle__add_unique_testjob__results_b.py	1970-01-01 00:00:00 +0000
@@ -1,148 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'TestJob._results_bundle'
-        db.alter_column('lava_scheduler_app_testjob', 'results_bundle_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['dashboard_app.Bundle'], unique=True, null=True, db_column='results_bundle_id'))
-        # Adding unique constraint on 'TestJob', fields ['_results_bundle']
-        db.create_unique('lava_scheduler_app_testjob', ['results_bundle_id'])
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'TestJob', fields ['_results_bundle']
-        db.delete_unique('lava_scheduler_app_testjob', ['results_bundle_id'])
-
-        # Changing field 'TestJob._results_bundle'
-        db.alter_column('lava_scheduler_app_testjob', 'results_bundle_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.Bundle'], null=True, db_column='results_bundle_id'))
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['dashboard_app.Bundle']", 'unique': 'True', 'null': 'True', 'db_column': "'results_bundle_id'", 'blank': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'w7imtbmkbr2izp1pek7qh4t8uybibd94nlqjh50js3k758hbeosy9xt14tx5wh19hiffofhxmmlquq333ffe72n6l0afdxce5zigu8q6x623o9i1217r4kd0h8h3x9b4'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0023_auto__add_field_devicetype_use_celery.py'
--- lava_scheduler_app/migrations/0023_auto__add_field_devicetype_use_celery.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0023_auto__add_field_devicetype_use_celery.py	1970-01-01 00:00:00 +0000
@@ -1,145 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'DeviceType.use_celery'
-        db.add_column('lava_scheduler_app_devicetype', 'use_celery',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-    def backwards(self, orm):
-        # Deleting field 'DeviceType.use_celery'
-        db.delete_column('lava_scheduler_app_devicetype', 'use_celery')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'}),
-            'use_celery': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['dashboard_app.Bundle']", 'unique': 'True', 'null': 'True', 'db_column': "'results_bundle_id'", 'blank': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'fxxmj9mnu0ox1a771w9c53gxjh07mnlc5bj5gthygd6jraelz0wpac744ls1ucrz0dyb5s9sbrojbk00lcw7tx4iczlu3le1qi63aejomaiuc4bnr7e3uhesli16em4r'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0024_auto__add_field_devicetype_display.py'
--- lava_scheduler_app/migrations/0024_auto__add_field_devicetype_display.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0024_auto__add_field_devicetype_display.py	1970-01-01 00:00:00 +0000
@@ -1,146 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'DeviceType.display'
-        db.add_column('lava_scheduler_app_devicetype', 'display',
-                      self.gf('django.db.models.fields.BooleanField')(default=True),
-                      keep_default=False)
-
-    def backwards(self, orm):
-        # Deleting field 'DeviceType.display'
-        db.delete_column('lava_scheduler_app_devicetype', 'display')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'}),
-            'use_celery': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['dashboard_app.Bundle']", 'unique': 'True', 'null': 'True', 'db_column': "'results_bundle_id'", 'blank': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'2on31z509ns9xctx8tcf0f3f0i3hi2k3hd9z5bogrh9rzup2dmb0au70uz0106tk2q31jowpkt134idrft378n4er00nmwfc6rhda8soa7lafeqwrjnoytz3l8g30g7f'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0025_auto__chg_field_testjob__results_bundle__chg_field_testjob_submit_toke.py'
--- lava_scheduler_app/migrations/0025_auto__chg_field_testjob__results_bundle__chg_field_testjob_submit_toke.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0025_auto__chg_field_testjob__results_bundle__chg_field_testjob_submit_toke.py	1970-01-01 00:00:00 +0000
@@ -1,177 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'TestJob._results_bundle'
-        db.alter_column('lava_scheduler_app_testjob', 'results_bundle_id', self.gf('django.db.models.fields.related.OneToOneField')(null=True, db_column='results_bundle_id', on_delete=models.SET_NULL, to=orm['dashboard_app.Bundle'], unique=True))
-
-        # Changing field 'TestJob.submit_token'
-        db.alter_column('lava_scheduler_app_testjob', 'submit_token_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['linaro_django_xmlrpc.AuthToken'], null=True, on_delete=models.SET_NULL))
-
-        # Changing field 'DeviceStateTransition.created_by'
-        db.alter_column('lava_scheduler_app_devicestatetransition', 'created_by_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.SET_NULL))
-
-        # Changing field 'DeviceStateTransition.job'
-        db.alter_column('lava_scheduler_app_devicestatetransition', 'job_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.TestJob'], null=True, on_delete=models.SET_NULL))
-
-        # Changing field 'Device.current_job'
-        db.alter_column('lava_scheduler_app_device', 'current_job_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, on_delete=models.SET_NULL, to=orm['lava_scheduler_app.TestJob'], unique=True))
-
-        # Changing field 'Device.last_health_report_job'
-        db.alter_column('lava_scheduler_app_device', 'last_health_report_job_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, on_delete=models.SET_NULL, to=orm['lava_scheduler_app.TestJob'], unique=True))
-
-    def backwards(self, orm):
-
-        # Changing field 'TestJob._results_bundle'
-        db.alter_column('lava_scheduler_app_testjob', 'results_bundle_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['dashboard_app.Bundle'], unique=True, null=True, db_column='results_bundle_id'))
-
-        # Changing field 'TestJob.submit_token'
-        db.alter_column('lava_scheduler_app_testjob', 'submit_token_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['linaro_django_xmlrpc.AuthToken'], null=True))
-
-        # Changing field 'DeviceStateTransition.created_by'
-        db.alter_column('lava_scheduler_app_devicestatetransition', 'created_by_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True))
-
-        # Changing field 'DeviceStateTransition.job'
-        db.alter_column('lava_scheduler_app_devicestatetransition', 'job_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.TestJob'], null=True))
-
-        # Changing field 'Device.current_job'
-        db.alter_column('lava_scheduler_app_device', 'current_job_id', self.gf('django.db.models.fields.related.ForeignKey')(unique=True, null=True, to=orm['lava_scheduler_app.TestJob']))
-
-        # Changing field 'Device.last_health_report_job'
-        db.alter_column('lava_scheduler_app_device', 'last_health_report_job_id', self.gf('django.db.models.fields.related.ForeignKey')(unique=True, null=True, to=orm['lava_scheduler_app.TestJob']))
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'}),
-            'use_celery': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'omk0tualeq2crdog45ys0cgo2gfgp626w6kchza9belc08w9p10xlcpiq1i0f86ta1m8us92ksryupbl4ll0c7zhbeluj0s4sw40gxsc0hkwkip3fgjg0gsh2j6lbbhy'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0026_auto__add_field_device_device_version.py'
--- lava_scheduler_app/migrations/0026_auto__add_field_device_device_version.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0026_auto__add_field_device_device_version.py	1970-01-01 00:00:00 +0000
@@ -1,147 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Device.device_version'
-        db.add_column('lava_scheduler_app_device', 'device_version',
-                      self.gf('django.db.models.fields.CharField')(default=None, max_length=200, null=True),
-                      keep_default=False)
-
-    def backwards(self, orm):
-        # Deleting field 'Device.device_version'
-        db.delete_column('lava_scheduler_app_device', 'device_version')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'}),
-            'use_celery': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'ql3hon1ufbemikjdr23ps3qzhpmq9gsrbryfiy5b8aokm0wo7w5u9b8r2yaybtgu0hp943x5a00ifjh5kqclpu3sbbei1um33c7axjp59sa7sdi2xxfpfq0xp0hw7ya0'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0027_auto__add_field_testjob_priority.py'
--- lava_scheduler_app/migrations/0027_auto__add_field_testjob_priority.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0027_auto__add_field_testjob_priority.py	1970-01-01 00:00:00 +0000
@@ -1,148 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'TestJob.priority'
-        db.add_column('lava_scheduler_app_testjob', 'priority',
-                      self.gf('django.db.models.fields.IntegerField')(default=50),
-                      keep_default=False)
-
-    def backwards(self, orm):
-        # Deleting field 'TestJob.priority'
-        db.delete_column('lava_scheduler_app_testjob', 'priority')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'}),
-            'use_celery': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'priority': ('django.db.models.fields.IntegerField', [], {'default': '50'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'76y45rqfq9pe0a22csih80ofg197kmkcqqr80m443r1ryoxby4d8ng8zl3fwmp7xuzrb11i5m5c1zlt0kemj240czk7d10n0m7p0hjrt54kmzfktrb4rrdfoxdlrrf35'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0028_auto__del_field_devicetype_use_celery.py'
--- lava_scheduler_app/migrations/0028_auto__del_field_devicetype_use_celery.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0028_auto__del_field_devicetype_use_celery.py	1970-01-01 00:00:00 +0000
@@ -1,147 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting field 'DeviceType.use_celery'
-        db.delete_column('lava_scheduler_app_devicetype', 'use_celery')
-
-    def backwards(self, orm):
-        # Adding field 'DeviceType.use_celery'
-        db.add_column('lava_scheduler_app_devicetype', 'use_celery',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'priority': ('django.db.models.fields.IntegerField', [], {'default': '50'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'ed8uhywjegfx2khwzfkcu0x3jwfbee4dbbp1dbs8mj0er7717uzx42c84bgdi9iss5xymgsz1cg1508cgcc7ypj0ux6zn1d8rbayo6jee49fhoopu7mlcailg69i6mbw'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0029_auto__add_jobfailuretag__add_field_testjob_failure_comment.py'
--- lava_scheduler_app/migrations/0029_auto__add_jobfailuretag__add_field_testjob_failure_comment.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/migrations/0029_auto__add_jobfailuretag__add_field_testjob_failure_comment.py	1970-01-01 00:00:00 +0000
@@ -1,178 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'JobFailureTag'
-        db.create_table('lava_scheduler_app_jobfailuretag', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=256)),
-            ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
-        ))
-        db.send_create_signal('lava_scheduler_app', ['JobFailureTag'])
-
-        # Adding field 'TestJob.failure_comment'
-        db.add_column('lava_scheduler_app_testjob', 'failure_comment',
-                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
-                      keep_default=False)
-
-        # Adding M2M table for field failure_tags on 'TestJob'
-        db.create_table('lava_scheduler_app_testjob_failure_tags', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testjob', models.ForeignKey(orm['lava_scheduler_app.testjob'], null=False)),
-            ('jobfailuretag', models.ForeignKey(orm['lava_scheduler_app.jobfailuretag'], null=False))
-        ))
-        db.create_unique('lava_scheduler_app_testjob_failure_tags', ['testjob_id', 'jobfailuretag_id'])
-
-    def backwards(self, orm):
-        # Deleting model 'JobFailureTag'
-        db.delete_table('lava_scheduler_app_jobfailuretag')
-
-        # Deleting field 'TestJob.failure_comment'
-        db.delete_column('lava_scheduler_app_testjob', 'failure_comment')
-
-        # Removing M2M table for field failure_tags on 'TestJob'
-        db.delete_table('lava_scheduler_app_testjob_failure_tags')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.jobfailuretag': {
-            'Meta': {'object_name': 'JobFailureTag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'failure_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'failure_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'failure_tags'", 'blank': 'True', 'to': "orm['lava_scheduler_app.JobFailureTag']"}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'priority': ('django.db.models.fields.IntegerField', [], {'default': '50'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'gz3f80buhio70b6ptm90c0bly6640oiylkimx0t3okbuq5ckezltlfyiz0ndcmgd8osaqu9h9mc8224108zatlq2hs8drzq0cgbqc22ia6f4lf7bg98r0i12nhti33yj'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0030_auto__add_field_testjob_sub_id__add_field_testjob_target_group.py'
--- lava_scheduler_app/migrations/0030_auto__add_field_testjob_sub_id__add_field_testjob_target_group.py	2013-07-17 12:48:53 +0000
+++ lava_scheduler_app/migrations/0030_auto__add_field_testjob_sub_id__add_field_testjob_target_group.py	1970-01-01 00:00:00 +0000
@@ -1,165 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.db import db
-from south.v2 import SchemaMigration
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'TestJob.sub_id'
-        db.add_column('lava_scheduler_app_testjob', 'sub_id',
-                      self.gf('django.db.models.fields.CharField')(default='', max_length=200, blank=True),
-                      keep_default=False)
-
-        # Adding field 'TestJob.target_group'
-        db.add_column('lava_scheduler_app_testjob', 'target_group',
-                      self.gf('django.db.models.fields.CharField')(default=None, max_length=64, null=True, blank=True),
-                      keep_default=False)
-
-    def backwards(self, orm):
-        # Deleting field 'TestJob.sub_id'
-        db.delete_column('lava_scheduler_app_testjob', 'sub_id')
-
-        # Deleting field 'TestJob.target_group'
-        db.delete_column('lava_scheduler_app_testjob', 'target_group')
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.jobfailuretag': {
-            'Meta': {'object_name': 'JobFailureTag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'failure_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'failure_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'failure_tags'", 'blank': 'True', 'to': "orm['lava_scheduler_app.JobFailureTag']"}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'priority': ('django.db.models.fields.IntegerField', [], {'default': '50'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'sub_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'target_group': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '64', 'null': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'7rf4239t35kqjrcixn4srgw00r61ncuq51jna0d6xbwpg2ur2annw5y1gkr9yt6ys9gh06b3wtcum4j0f2pdn5crul72mu1e1tw4at9jfgwk18asogkgoqcbc20ftylx'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']

=== removed file 'lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py'
--- lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py	2013-08-14 13:35:55 +0000
+++ lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py	1970-01-01 00:00:00 +0000
@@ -1,162 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'TestJob.multinode_definition'
-        db.add_column('lava_scheduler_app_testjob', 'multinode_definition',
-                      self.gf('django.db.models.fields.TextField')(default='', blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'TestJob.multinode_definition'
-        db.delete_column('lava_scheduler_app_testjob', 'multinode_definition')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'lava_scheduler_app.device': {
-            'Meta': {'object_name': 'Device'},
-            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
-            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'lava_scheduler_app.devicestatetransition': {
-            'Meta': {'object_name': 'DeviceStateTransition'},
-            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'new_state': ('django.db.models.fields.IntegerField', [], {}),
-            'old_state': ('django.db.models.fields.IntegerField', [], {})
-        },
-        'lava_scheduler_app.devicetype': {
-            'Meta': {'object_name': 'DeviceType'},
-            'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'})
-        },
-        'lava_scheduler_app.jobfailuretag': {
-            'Meta': {'object_name': 'JobFailureTag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'lava_scheduler_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
-        },
-        'lava_scheduler_app.testjob': {
-            'Meta': {'object_name': 'TestJob'},
-            '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}),
-            '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}),
-            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'definition': ('django.db.models.fields.TextField', [], {}),
-            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'failure_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'failure_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'failure_tags'", 'blank': 'True', 'to': "orm['lava_scheduler_app.JobFailureTag']"}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'multinode_definition': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'priority': ('django.db.models.fields.IntegerField', [], {'default': '50'}),
-            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
-            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
-            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'sub_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
-            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
-            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
-            'target_group': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '64', 'null': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'linaro_django_xmlrpc.authtoken': {
-            'Meta': {'object_name': 'AuthToken'},
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'secret': ('django.db.models.fields.CharField', [], {'default': "'g4fgt7t5qdghq3qo3t3h5dhbj6fes2zh8n6lkncc0u0rcqxy0kaez7aacw05nc0oxjc3060pj0f1fsunjpo1btk6urfpt8xfmgefcatgmh1e7kj0ams90ikni05sd5qk'", 'unique': 'True', 'max_length': '128'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['lava_scheduler_app']
\ No newline at end of file

=== removed file 'lava_scheduler_app/migrations/__init__.py'
=== removed file 'lava_scheduler_app/models.py'
--- lava_scheduler_app/models.py	2013-09-12 06:28:07 +0000
+++ lava_scheduler_app/models.py	1970-01-01 00:00:00 +0000
@@ -1,684 +0,0 @@
-import logging
-import os
-import uuid
-import simplejson
-import urlparse
-
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.contrib.sites.models import Site
-from django.core.exceptions import ImproperlyConfigured, ValidationError
-from django.core.mail import send_mail
-from django.core.validators import validate_email
-from django.db import models
-from django.template.loader import render_to_string
-from django.utils.translation import ugettext as _
-
-from django_restricted_resource.models import RestrictedResource
-
-from dashboard_app.models import Bundle, BundleStream
-
-from lava_dispatcher.job import validate_job_data
-from lava_scheduler_app import utils
-
-from linaro_django_xmlrpc.models import AuthToken
-
-
-class JSONDataError(ValueError):
-    """Error raised when JSON is syntactically valid but ill-formed."""
-
-
-class DevicesUnavailableException(UserWarning):
-    """Error raised when required number of devices are unavailable."""
-
-
-class Tag(models.Model):
-
-    name = models.SlugField(unique=True)
-
-    description = models.TextField(null=True, blank=True)
-
-    def __unicode__(self):
-        return self.name
-
-
-def validate_job_json(data):
-    try:
-        ob = simplejson.loads(data)
-        validate_job_data(ob)
-    except ValueError, e:
-        raise ValidationError(e)
-
-
-def check_device_availability(requested_devices):
-    """Checks whether the number of devices requested is available for a multinode job.
-    
-    See utils.requested_device_count() for details of REQUESTED_DEVICES
-    dictionary format.
-
-    Returns True for singlenode or if the requested number of devices are available
-    for the multinode job, else raises DevicesUnavailableException.
-    """
-    device_types = DeviceType.objects.values_list('name').filter(
-        models.Q(device__status=Device.IDLE) |
-        models.Q(device__status=Device.RUNNING) |
-        models.Q(device__status=Device.RESERVED) |
-        models.Q(device__status=Device.OFFLINE) |
-        models.Q(device__status=Device.OFFLINING)
-        ).annotate(
-            num_count=models.Count('name')
-        ).order_by('name')
-
-    if requested_devices:
-        all_devices = {}
-        for dt in device_types:
-            # dt[0] -> device type name
-            # dt[1] -> device type count
-            all_devices[dt[0]] = dt[1]
-
-        for board, count in requested_devices.iteritems():
-            if all_devices.get(board, None) and count <= all_devices[board]:
-                continue
-            else:
-                raise DevicesUnavailableException(
-                    "Requested %d %s device(s) - only %d available." % (count, board, all_devices.get(board,0)))
-    return True
-
-
-class DeviceType(models.Model):
-    """
-    A class of device, for example a pandaboard or a snowball.
-    """
-
-    name = models.SlugField(primary_key=True)
-
-    def __unicode__(self):
-        return self.name
-
-    health_check_job = models.TextField(
-        null=True, blank=True, default=None, validators=[validate_job_json])
-
-    display = models.BooleanField(default=True,
-                                  help_text=("Should this be displayed in the GUI or not. This can be "
-                                  "useful if you are removing all devices of this type but don't "
-                                  "want to loose the test results generated by the devices."))
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("lava.scheduler.device_type.detail", [self.pk])
-
-
-class Device(models.Model):
-    """
-    A device that we can run tests on.
-    """
-
-    OFFLINE = 0
-    IDLE = 1
-    RUNNING = 2
-    OFFLINING = 3
-    RETIRED = 4
-    RESERVED = 5
-
-    STATUS_CHOICES = (
-        (OFFLINE, 'Offline'),
-        (IDLE, 'Idle'),
-        (RUNNING, 'Running'),
-        (OFFLINING, 'Going offline'),
-        (RETIRED, 'Retired'),
-        (RESERVED, 'Reserved')
-    )
-
-    # A device health shows a device is ready to test or not
-    HEALTH_UNKNOWN, HEALTH_PASS, HEALTH_FAIL, HEALTH_LOOPING = range(4)
-    HEALTH_CHOICES = (
-        (HEALTH_UNKNOWN, 'Unknown'),
-        (HEALTH_PASS, 'Pass'),
-        (HEALTH_FAIL, 'Fail'),
-        (HEALTH_LOOPING, 'Looping'),
-    )
-
-    hostname = models.CharField(
-        verbose_name=_(u"Hostname"),
-        max_length=200,
-        primary_key=True,
-    )
-
-    device_type = models.ForeignKey(
-        DeviceType, verbose_name=_(u"Device type"))
-
-    device_version = models.CharField(
-        verbose_name=_(u"Device Version"),
-        max_length=200,
-        null=True,
-        default=None,
-        blank=True,
-    )
-
-    current_job = models.ForeignKey(
-        "TestJob", blank=True, unique=True, null=True, related_name='+',
-        on_delete=models.SET_NULL)
-
-    tags = models.ManyToManyField(Tag, blank=True)
-
-    status = models.IntegerField(
-        choices=STATUS_CHOICES,
-        default=IDLE,
-        verbose_name=_(u"Device status"),
-    )
-
-    health_status = models.IntegerField(
-        choices=HEALTH_CHOICES,
-        default=HEALTH_UNKNOWN,
-        verbose_name=_(u"Device Health"),
-    )
-
-    last_health_report_job = models.ForeignKey(
-        "TestJob", blank=True, unique=True, null=True, related_name='+',
-        on_delete=models.SET_NULL)
-
-    def __unicode__(self):
-        return self.hostname
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("lava.scheduler.device.detail", [self.pk])
-
-    @models.permalink
-    def get_device_health_url(self):
-        return ("lava.scheduler.labhealth.detail", [self.pk])
-
-    def recent_jobs(self):
-        return TestJob.objects.select_related(
-            "actual_device",
-            "requested_device",
-            "requested_device_type",
-            "submitter",
-            "user",
-            "group",
-        ).filter(
-            actual_device=self
-        ).order_by(
-            '-start_time'
-        )
-
-    def can_admin(self, user):
-        return user.has_perm('lava_scheduler_app.change_device')
-
-    def put_into_maintenance_mode(self, user, reason):
-        if self.status in [self.RUNNING, self.RESERVED, self.OFFLINING]:
-            new_status = self.OFFLINING
-        else:
-            new_status = self.OFFLINE
-        DeviceStateTransition.objects.create(
-            created_by=user, device=self, old_state=self.status,
-            new_state=new_status, message=reason, job=None).save()
-        self.status = new_status
-        if self.health_status == Device.HEALTH_LOOPING:
-            self.health_status = Device.HEALTH_UNKNOWN
-        self.save()
-
-    def put_into_online_mode(self, user, reason):
-        if self.status == Device.OFFLINING:
-            new_status = self.RUNNING
-        else:
-            new_status = self.IDLE
-        DeviceStateTransition.objects.create(
-            created_by=user, device=self, old_state=self.status,
-            new_state=new_status, message=reason, job=None).save()
-        self.status = new_status
-        self.health_status = Device.HEALTH_UNKNOWN
-        self.save()
-
-    def put_into_looping_mode(self, user):
-        if self.status not in [Device.OFFLINE, Device.OFFLINING]:
-            return
-        new_status = self.IDLE
-        DeviceStateTransition.objects.create(
-            created_by=user, device=self, old_state=self.status,
-            new_state=new_status, message="Looping mode", job=None).save()
-        self.status = new_status
-        self.health_status = Device.HEALTH_LOOPING
-        self.save()
-
-    def cancel_reserved_status(self, user, reason):
-        if self.status != Device.RESERVED:
-            return
-        new_status = self.IDLE
-        DeviceStateTransition.objects.create(
-            created_by=user, device=self, old_state=self.status,
-            new_state=new_status, message=reason, job=None).save()
-        self.status = new_status
-        self.save()
-
-
-class JobFailureTag(models.Model):
-    """
-    Allows us to maintain a set of common ways jobs fail. These can then be
-    associated with a TestJob so we can do easy data mining
-    """
-    name = models.CharField(unique=True, max_length=256)
-
-    description = models.TextField(null=True, blank=True)
-
-    def __unicode__(self):
-        return self.name
-
-
-class TestJob(RestrictedResource):
-    """
-    A test job is a test process that will be run on a Device.
-    """
-
-    SUBMITTED = 0
-    RUNNING = 1
-    COMPLETE = 2
-    INCOMPLETE = 3
-    CANCELED = 4
-    CANCELING = 5
-
-    STATUS_CHOICES = (
-        (SUBMITTED, 'Submitted'),
-        (RUNNING, 'Running'),
-        (COMPLETE, 'Complete'),
-        (INCOMPLETE, 'Incomplete'),
-        (CANCELED, 'Canceled'),
-        (CANCELING, 'Canceling'),
-    )
-
-    LOW = 0
-    MEDIUM = 50
-    HIGH = 100
-
-    PRIORITY_CHOICES = (
-        (LOW, 'Low'),
-        (MEDIUM, 'Medium'),
-        (HIGH, 'High'),
-    )
-
-    id = models.AutoField(primary_key=True)
-
-    sub_id = models.CharField(
-        verbose_name=_(u"Sub ID"),
-        blank=True,
-        max_length=200
-    )
-
-    target_group = models.CharField(
-        verbose_name=_(u"Target Group"),
-        blank=True,
-        max_length=64,
-        null=True,
-        default=None
-    )
-
-    submitter = models.ForeignKey(
-        User,
-        verbose_name=_(u"Submitter"),
-        related_name='+',
-    )
-
-    submit_token = models.ForeignKey(
-        AuthToken, null=True, blank=True, on_delete=models.SET_NULL)
-
-    description = models.CharField(
-        verbose_name=_(u"Description"),
-        max_length=200,
-        null=True,
-        blank=True,
-        default=None
-    )
-
-    health_check = models.BooleanField(default=False)
-
-    # Only one of these two should be non-null.
-    requested_device = models.ForeignKey(
-        Device, null=True, default=None, related_name='+', blank=True)
-    requested_device_type = models.ForeignKey(
-        DeviceType, null=True, default=None, related_name='+', blank=True)
-
-    tags = models.ManyToManyField(Tag, blank=True)
-
-    # This is set once the job starts or is reserved.
-    actual_device = models.ForeignKey(
-        Device, null=True, default=None, related_name='+', blank=True)
-
-    submit_time = models.DateTimeField(
-        verbose_name=_(u"Submit time"),
-        auto_now=False,
-        auto_now_add=True
-    )
-    start_time = models.DateTimeField(
-        verbose_name=_(u"Start time"),
-        auto_now=False,
-        auto_now_add=False,
-        null=True,
-        blank=True,
-        editable=False
-    )
-    end_time = models.DateTimeField(
-        verbose_name=_(u"End time"),
-        auto_now=False,
-        auto_now_add=False,
-        null=True,
-        blank=True,
-        editable=False
-    )
-
-    @property
-    def duration(self):
-        if self.end_time is None:
-            return None
-        return self.end_time - self.start_time
-
-    status = models.IntegerField(
-        choices=STATUS_CHOICES,
-        default=SUBMITTED,
-        verbose_name=_(u"Status"),
-    )
-
-    priority = models.IntegerField(
-        choices=PRIORITY_CHOICES,
-        default=MEDIUM,
-        verbose_name=_(u"Priority"),
-    )
-
-    definition = models.TextField(
-        editable=False,
-    )
-
-    multinode_definition = models.TextField(
-        editable=False,
-        blank=True
-    )
-
-    log_file = models.FileField(
-        upload_to='lava-logs', default=None, null=True, blank=True)
-
-    @property
-    def output_dir(self):
-        return os.path.join(settings.MEDIA_ROOT, 'job-output', 'job-%s' % self.id)
-
-    def output_file(self):
-        output_path = os.path.join(self.output_dir, 'output.txt')
-        if os.path.exists(output_path):
-            return open(output_path)
-        elif self.log_file:
-            log_file = self.log_file
-            if log_file:
-                try:
-                    log_file.open()
-                except IOError:
-                    log_file = None
-            return log_file
-        else:
-            return None
-
-    failure_tags = models.ManyToManyField(
-        JobFailureTag, blank=True, related_name='failure_tags')
-    failure_comment = models.TextField(null=True, blank=True)
-
-    _results_link = models.CharField(
-        max_length=400, default=None, null=True, blank=True, db_column="results_link")
-
-    _results_bundle = models.OneToOneField(
-        Bundle, null=True, blank=True, db_column="results_bundle_id",
-        on_delete=models.SET_NULL)
-
-    @property
-    def results_link(self):
-        if self._results_bundle:
-            return self._results_bundle.get_permalink()
-        elif self._results_link:
-            return self._results_link
-        else:
-            return None
-
-    @property
-    def results_bundle(self):
-        if self._results_bundle:
-            return self._results_bundle
-        if not self.results_link:
-            return None
-        sha1 = self.results_link.strip('/').split('/')[-1]
-        try:
-            return Bundle.objects.get(content_sha1=sha1)
-        except Bundle.DoesNotExist:
-            return None
-
-    def __unicode__(self):
-        r = "%s test job" % self.get_status_display()
-        if self.requested_device:
-            r += " for %s" % (self.requested_device.hostname,)
-        return r
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("lava.scheduler.job.detail", [self.pk])
-
-    @classmethod
-    def from_json_and_user(cls, json_data, user, health_check=False):
-        requested_devices = utils.requested_device_count(json_data)
-        check_device_availability(requested_devices)
-        job_data = simplejson.loads(json_data)
-        validate_job_data(job_data)
-
-        # Validate job, for parameters, specific to multinode that has been
-        # input by the user. These parameters are reserved by LAVA and
-        # generated during job submissions.
-        reserved_job_params = ["group_size", "role", "sub_id", "target_group"]
-        reserved_params_found = set(reserved_job_params).intersection(
-            set(job_data.keys()))
-        if reserved_params_found:
-            raise JSONDataError("Reserved parameters found in job data %s" %
-                                str([x for x in reserved_params_found]))
-
-        if 'target' in job_data:
-            target = Device.objects.get(hostname=job_data['target'])
-            device_type = None
-        elif 'device_type' in job_data:
-            target = None
-            device_type = DeviceType.objects.get(name=job_data['device_type'])
-        elif 'device_group' in job_data:
-            target = None
-            device_type = None
-        else:
-            raise JSONDataError(
-                "No 'target' or 'device_type' or 'device_group' are found "
-                "in job data.")
-
-        priorities = dict([(j.upper(), i) for i, j in cls.PRIORITY_CHOICES])
-        priority = cls.MEDIUM
-        if 'priority' in job_data:
-            priority_key = job_data['priority'].upper()
-            if priority_key not in priorities:
-                raise JSONDataError("Invalid job priority: %r" % priority_key)
-            priority = priorities[priority_key]
-
-        for email_field in 'notify', 'notify_on_incomplete':
-            if email_field in job_data:
-                value = job_data[email_field]
-                msg = ("%r must be a list of email addresses if present"
-                       % email_field)
-                if not isinstance(value, list):
-                    raise ValueError(msg)
-                for address in value:
-                    if not isinstance(address, basestring):
-                        raise ValueError(msg)
-                    try:
-                        validate_email(address)
-                    except ValidationError:
-                        raise ValueError(
-                            "%r is not a valid email address." % address)
-
-        if job_data.get('health_check', False) and not health_check:
-            raise ValueError(
-                "cannot submit a job with health_check: true via the api.")
-
-        job_name = job_data.get('job_name', '')
-
-        submitter = user
-        group = None
-        is_public = True
-
-        for action in job_data['actions']:
-            if not action['command'].startswith('submit_results'):
-                continue
-            stream = action['parameters']['stream']
-            try:
-                bundle_stream = BundleStream.objects.get(pathname=stream)
-            except BundleStream.DoesNotExist:
-                raise ValueError("stream %s not found" % stream)
-            if not bundle_stream.can_upload(submitter):
-                raise ValueError(
-                    "you cannot submit to the stream %s" % stream)
-            if not bundle_stream.is_anonymous:
-                user, group, is_public = (bundle_stream.user,
-                                          bundle_stream.group,
-                                          bundle_stream.is_public)
-            server = action['parameters']['server']
-            parsed_server = urlparse.urlsplit(server)
-            action["parameters"]["server"] = utils.rewrite_hostname(server)
-            if parsed_server.hostname is None:
-                raise ValueError("invalid server: %s" % server)
-
-        tags = []
-        for tag_name in job_data.get('device_tags', []):
-            try:
-                tags.append(Tag.objects.get(name=tag_name))
-            except Tag.DoesNotExist:
-                raise JSONDataError("tag %r does not exist" % tag_name)
-
-        if 'device_group' in job_data:
-            target_group = str(uuid.uuid4())
-            node_json = utils.split_multi_job(job_data, target_group)
-            job_list = []
-            try:
-                parent_id = (TestJob.objects.latest('id')).id + 1
-            except:
-                parent_id = 1
-            child_id = 0
-
-            for role in node_json:
-                role_count = len(node_json[role])
-                for c in range(0, role_count):
-                    device_type = DeviceType.objects.get(
-                        name=node_json[role][c]["device_type"])
-                    sub_id = '.'.join([str(parent_id), str(child_id)])
-
-                    # Add sub_id to the generated job dictionary.
-                    node_json[role][c]["sub_id"] = sub_id
-
-                    job = TestJob(
-                        sub_id=sub_id, submitter=submitter,
-                        requested_device=target, description=job_name,
-                        requested_device_type=device_type,
-                        definition=simplejson.dumps(node_json[role][c]),
-                        multinode_definition=json_data,
-                        health_check=health_check, user=user, group=group,
-                        is_public=is_public, priority=priority,
-                        target_group=target_group)
-                    job.save()
-                    job_list.append(sub_id)
-                    child_id += 1
-            return job_list
-
-        else:
-            job = TestJob(
-                definition=simplejson.dumps(job_data), submitter=submitter,
-                requested_device=target, requested_device_type=device_type,
-                description=job_name, health_check=health_check, user=user,
-                group=group, is_public=is_public, priority=priority)
-            job.save()
-            return job
-
-    def _can_admin(self, user):
-        """ used to check for things like if the user can cancel or annotate
-        a job failure
-        """
-        return user.is_superuser or user == self.submitter
-
-    def can_annotate(self, user):
-        """
-        Permission required for user to add failure information to a job
-        """
-        states = [TestJob.COMPLETE, TestJob.INCOMPLETE, TestJob.CANCELED]
-        return self._can_admin(user) and self.status in states
-
-    def can_cancel(self, user):
-        return self._can_admin(user) and self.status <= TestJob.RUNNING
-
-    def can_resubmit(self, user):
-        states = [TestJob.COMPLETE, TestJob.INCOMPLETE, TestJob.CANCELED]
-        return self._can_admin(user) and self.status in states
-
-    def cancel(self):
-        # if SUBMITTED with actual_device - clear the actual_device back to idle.
-        if self.status == TestJob.SUBMITTED and self.actual_device is not None:
-            device = Device.objects.get(hostname=self.actual_device)
-            device.cancel_reserved_status(self.submitter, "multinode-cancel")
-        if self.status == TestJob.RUNNING:
-            self.status = TestJob.CANCELING
-        else:
-            self.status = TestJob.CANCELED
-        self.save()
-
-    def _generate_summary_mail(self):
-        domain = '???'
-        try:
-            site = Site.objects.get_current()
-        except (Site.DoesNotExist, ImproperlyConfigured):
-            pass
-        else:
-            domain = site.domain
-        url_prefix = 'http://%s' % domain
-        return render_to_string(
-            'lava_scheduler_app/job_summary_mail.txt',
-            {'job': self, 'url_prefix': url_prefix})
-
-    def _get_notification_recipients(self):
-        job_data = simplejson.loads(self.definition)
-        recipients = job_data.get('notify', [])
-        if self.status != self.COMPLETE:
-            recipients.extend(job_data.get('notify_on_incomplete', []))
-        return recipients
-
-    def send_summary_mails(self):
-        recipients = self._get_notification_recipients()
-        if not recipients:
-            return
-        mail = self._generate_summary_mail()
-        description = self.description.splitlines()[0]
-        if len(description) > 200:
-            description = description[197:] + '...'
-        logger = logging.getLogger(self.__class__.__name__ + '.' + str(self.pk))
-        logger.info("sending mail to %s", recipients)
-        send_mail(
-            "LAVA job notification: " + description, mail,
-            settings.SERVER_EMAIL, recipients)
-
-    @property
-    def sub_jobs_list(self):
-        if self.is_multinode:
-            jobs = TestJob.objects.filter(
-                target_group=self.target_group).order_by('id')
-            return jobs
-        else:
-            return None
-
-    @property
-    def is_multinode(self):
-        if self.target_group:
-            return True
-        else:
-            return False
-
-
-class DeviceStateTransition(models.Model):
-    created_on = models.DateTimeField(auto_now_add=True)
-    created_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
-    device = models.ForeignKey(Device, related_name='transitions')
-    job = models.ForeignKey(TestJob, null=True, blank=True, on_delete=models.SET_NULL)
-    old_state = models.IntegerField(choices=Device.STATUS_CHOICES)
-    new_state = models.IntegerField(choices=Device.STATUS_CHOICES)
-    message = models.TextField(null=True, blank=True)

=== removed directory 'lava_scheduler_app/static'
=== removed directory 'lava_scheduler_app/static/lava_scheduler_app'
=== removed directory 'lava_scheduler_app/static/lava_scheduler_app/css'
=== removed file 'lava_scheduler_app/static/lava_scheduler_app/css/jquery-linedtextarea.css'
--- lava_scheduler_app/static/lava_scheduler_app/css/jquery-linedtextarea.css	2013-06-26 12:57:41 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/css/jquery-linedtextarea.css	1970-01-01 00:00:00 +0000
@@ -1,74 +0,0 @@
-/**
- * jQuery Lined Textarea Plugin
- *   http://alan.blog-city.com/jquerylinedtextarea.htm
- *
- * Copyright (c) 2010 Alan Williamson
- *
- * Contribution done by Ryan Zielke (neoalchemy@gmail.com)
- *
- * Released under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * Usage:
- *   Displays a line number count column to the left of the textarea
- *
- *   Class up your textarea with a given class, or target it directly
- *   with JQuery Selectors
- *
- *   $(".lined").linedtextarea({
- *   	selectedLine: 10,
- *    selectedClass: 'lineselect'
- *   });
- *
- */
-
-textarea { resize:both; }
-
-.linedwrap {
-	border: 1px solid #c0c0c0;
-	padding: 3px;
-	display: inline-block;
-}
-
-.linedtextarea {
-	padding: 0px;
-	margin: 0px;
-}
-
-.linedtextarea textarea, .linedwrap .codelines .lineno {
-	font-size: 9pt;
-	font-family: monospace;
-	line-height: normal !important;
-}
-
-.linedtextarea textarea {
-	padding-right:0.3em;
-	padding-top:0.3em;
-	border: 0;
-}
-
-.linedwrap .lines {
-	margin-top: 0px;
-	width: 50px;
-	float: left;
-	overflow: hidden;
-	border-right: 1px solid #c0c0c0;
-	margin-right: 10px;
-}
-
-.linedwrap .codelines {
-	padding-top: 3px;
-}
-
-.linedwrap .codelines .lineno {
-	color:#AAAAAA;
-	padding-right: 0.5em;
-	padding-top: 0.0em;
-	text-align: right;
-	white-space: nowrap;
-}
-
-.linedwrap .codelines .lineselect {
-	color: white;
-        background-color: red;
-}
\ No newline at end of file

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/css/logfile.css'
--- lava_scheduler_app/static/lava_scheduler_app/css/logfile.css	2013-07-30 10:15:36 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/css/logfile.css	1970-01-01 00:00:00 +0000
@@ -1,36 +0,0 @@
-
-#logfile_content
-{
-    margin-left: 5px;
-}
-
-.log_log
-{
-    color: #a23212;
-}
-
-.console_log
-{
-    margin-left: 10px;
-}
-.traceback_log
-{
-    color: #ee1111;
-}
-
-.clickable
-{
-    border-style: solid;
-    border-width: medium;
-}
-
-.line 
-{
-    line-height: 18px;
-    white-space: nowrap;
-}
-
-div:target 
-{
-    background-color: rgb(255, 128, 128);
-}

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/css/scheduler.css'
--- lava_scheduler_app/static/lava_scheduler_app/css/scheduler.css	2013-06-28 09:45:22 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/css/scheduler.css	1970-01-01 00:00:00 +0000
@@ -1,77 +0,0 @@
-.column {
-    position: relative;
-    float: left;
-    padding-right: 2em;
-    padding-bottom: 1em;
-    width: 20%;
-}
-#tab-definition {
-    width: 70%; 
-}
-
-#tab-definition pre {
- overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not needed in Firefox 3 */
- white-space: pre-wrap; /* css-3 */
- white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- /* width: 99%; */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
- max-height: 400px;
-}
-
-#tab-output pre {
-    max-height: 400px;
-    max-width: 800px;
-    margin: 25px;
-}
-
-.skip {
-    color:red;
-}
-
-#dispatcher-error pre {
-    color: red;
-}
-
-pre.log {
-    margin: 0;
-}
-
-pre.action {
-    color: blue
-}
-
-.logbuttons .ui-button-text {
-    padding: 0.1em 0.4em;
-}
-
-#json-input {
-    width: 900px;
-    height: 400px;
-    margin: 0px;
-    resize: both;
-}
-
-#submit-container {
-    margin-top: 10px;
-}
-
-#json-valid-container {
-    border: 1px solid #cccccc;
-    display: none;
-    margin-top: 10px;
-    width: 500px;
-    padding: 10px;
-}
-
-#job-success {
-    font-size: 16px;
-    font-weight: bold;
-}
-
-#job-error {
-    font-size: 14px;
-    font-weight: bold;
-    color: red;
-}

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/css/shCore.css'
--- lava_scheduler_app/static/lava_scheduler_app/css/shCore.css	2011-11-26 21:49:36 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/css/shCore.css	1970-01-01 00:00:00 +0000
@@ -1,226 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- * 
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
-  -moz-border-radius: 0 0 0 0 !important;
-  -webkit-border-radius: 0 0 0 0 !important;
-  background: none !important;
-  border: 0 !important;
-  bottom: auto !important;
-  float: none !important;
-  height: auto !important;
-  left: auto !important;
-  line-height: 1.1em !important;
-  margin: 0 !important;
-  outline: 0 !important;
-  overflow: visible !important;
-  padding: 0 !important;
-  position: static !important;
-  right: auto !important;
-  text-align: left !important;
-  top: auto !important;
-  vertical-align: baseline !important;
-  width: auto !important;
-  box-sizing: content-box !important;
-  font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
-  font-weight: normal !important;
-  font-style: normal !important;
-  font-size: 1em !important;
-  min-height: inherit !important;
-  min-height: auto !important;
-}
-
-.syntaxhighlighter {
-  width: 100% !important;
-  margin: 1em 0 1em 0 !important;
-  position: relative !important;
-  overflow: auto !important;
-  font-size: 1em !important;
-}
-.syntaxhighlighter.source {
-  overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
-  font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
-  font-style: italic !important;
-}
-.syntaxhighlighter .line {
-  white-space: pre !important;
-}
-.syntaxhighlighter table {
-  width: 100% !important;
-}
-.syntaxhighlighter table caption {
-  text-align: left !important;
-  padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
-  width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
-  position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
-  box-sizing: border-box !important;
-  position: absolute !important;
-  left: 0 !important;
-  top: 0 !important;
-  width: 100% !important;
-  height: 100% !important;
-  border: none !important;
-  background: white !important;
-  padding-left: 1em !important;
-  overflow: hidden !important;
-  white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
-  text-align: right !important;
-  padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
-  padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
-  padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
-  display: block !important;
-}
-.syntaxhighlighter.collapsed table {
-  display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
-  padding: 0.1em 0.8em 0em 0.8em !important;
-  font-size: 1em !important;
-  position: static !important;
-  width: auto !important;
-  height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
-  display: inline !important;
-  margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
-  padding: 0 !important;
-  display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
-  display: inline !important;
-}
-.syntaxhighlighter .toolbar {
-  position: absolute !important;
-  right: 1px !important;
-  top: 1px !important;
-  width: 11px !important;
-  height: 11px !important;
-  font-size: 10px !important;
-  z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
-  display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
-  display: block !important;
-  text-align: center !important;
-  text-decoration: none !important;
-  padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
-  display: none !important;
-}
-.syntaxhighlighter.ie {
-  font-size: .9em !important;
-  padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
-  line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
-  padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
-  background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
-  color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
-  color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
-  display: none !important;
-}
-.syntaxhighlighter.printing a {
-  text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
-  color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
-  color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
-  color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
-  color: #006699 !important;
-  font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
-  color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
-  color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
-  color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
-  color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
-  color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
-  font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
-  color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
-  color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
-  color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
-  color: black !important;
-}

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/css/shThemeDefault.css'
--- lava_scheduler_app/static/lava_scheduler_app/css/shThemeDefault.css	2011-11-26 21:49:36 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/css/shThemeDefault.css	1970-01-01 00:00:00 +0000
@@ -1,117 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- * 
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
-  background-color: white !important;
-}
-.syntaxhighlighter .line.alt1 {
-  background-color: white !important;
-}
-.syntaxhighlighter .line.alt2 {
-  background-color: white !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
-  background-color: #e0e0e0 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
-  color: black !important;
-}
-.syntaxhighlighter table caption {
-  color: black !important;
-}
-.syntaxhighlighter .gutter {
-  color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
-  border-right: 3px solid #6ce26c !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
-  background-color: #6ce26c !important;
-  color: white !important;
-}
-.syntaxhighlighter.printing .line .content {
-  border: none !important;
-}
-.syntaxhighlighter.collapsed {
-  overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
-  color: blue !important;
-  background: white !important;
-  border: 1px solid #6ce26c !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
-  color: blue !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
-  color: red !important;
-}
-.syntaxhighlighter .toolbar {
-  color: white !important;
-  background: #6ce26c !important;
-  border: none !important;
-}
-.syntaxhighlighter .toolbar a {
-  color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
-  color: black !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
-  color: black !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
-  color: #008200 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
-  color: blue !important;
-}
-.syntaxhighlighter .keyword {
-  color: #006699 !important;
-}
-.syntaxhighlighter .preprocessor {
-  color: gray !important;
-}
-.syntaxhighlighter .variable {
-  color: #aa7700 !important;
-}
-.syntaxhighlighter .value {
-  color: #009900 !important;
-}
-.syntaxhighlighter .functions {
-  color: #ff1493 !important;
-}
-.syntaxhighlighter .constants {
-  color: #0066cc !important;
-}
-.syntaxhighlighter .script {
-  font-weight: bold !important;
-  color: #006699 !important;
-  background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
-  color: gray !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
-  color: #ff1493 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
-  color: red !important;
-}
-
-.syntaxhighlighter .keyword {
-  font-weight: bold !important;
-}

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/css/shThemeLAVA.css'
--- lava_scheduler_app/static/lava_scheduler_app/css/shThemeLAVA.css	2013-09-11 19:21:44 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/css/shThemeLAVA.css	1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
-.syntaxhighlighter {
-  background-color: transparent !important;
-}
-.syntaxhighlighter .line.alt1 {
-  background-color: white !important;
-}
-.syntaxhighlighter .line.alt2 {
-  background-color: transparent !important;
-}

=== removed directory 'lava_scheduler_app/static/lava_scheduler_app/images'
=== removed file 'lava_scheduler_app/static/lava_scheduler_app/images/ajax-progress.gif'
Binary files lava_scheduler_app/static/lava_scheduler_app/images/ajax-progress.gif	2011-12-12 04:38:14 +0000 and lava_scheduler_app/static/lava_scheduler_app/images/ajax-progress.gif	1970-01-01 00:00:00 +0000 differ
=== removed directory 'lava_scheduler_app/static/lava_scheduler_app/js'
=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/jQuery.Rule.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/jQuery.Rule.js	2011-12-09 04:45:32 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/jQuery.Rule.js	1970-01-01 00:00:00 +0000
@@ -1,273 +0,0 @@
-/*!
- * jQuery.Rule - Css Rules manipulation, the jQuery way.
- * Copyright (c) 2007-2011 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
- * Dual licensed under MIT and GPL.
- * Date: 02/7/2011
- * Compatible with jQuery 1.2+
- *
- * @author Ariel Flesler
- * @version 1.0.2
- *
- * @id jQuery.rule
- * @param {Undefined|String|jQuery.Rule} The rules, can be a selector, or literal CSS rules. Many can be given, comma separated.
- * @param {Undefined|String|DOMElement|jQuery) The context stylesheets, all of them by default.
- * @return {jQuery.Rule} Returns a jQuery.Rule object.
- *
- * @example $.rule('p,div').filter(function(){ return this.style.display != 'block'; }).remove();
- *
- * @example $.rule('div{ padding:20px;background:#CCC}, p{ border:1px red solid; }').appendTo('style');
- *
- * @example $.rule('div{}').append('margin:40px').css('margin-left',0).appendTo('link:eq(1)');
- *
- * @example $.rule().not('div, p.magic').fadeOut('slow');
- *
- * @example var text = $.rule('#screen h2').add('h4').end().eq(4).text();
- */
-;(function( $ ){	
-	
-   /**
-	* Notes
-	*	Some styles and animations might fail, please report it.
-	*	The plugin needs a style node to stay in the DOM all along to temporarily hold rules. DON'T TOUCH IT.
-	*	Opera requires this style to have alternate in the rel to allow disabling it.
-	*	Rules in IE don't have .parentStylesheet. We need to find it each time(slow).
-	*	Animations need close attention. Programatically knowing which rule has precedence, would require a LOT of work.
-	*	This plugin adds $.rule and also 4 methods to $.fn: ownerNode, sheet, cssRules and cssText
-	*	Note that rules are not directly inside nodes, you need to do: $('style').sheet().cssRules().
-	*/
-	
-	var storageNode = $('<style rel="alternate stylesheet" type="text/css" />').appendTo('head')[0],//we must append to get a stylesheet
-		sheet = storageNode.sheet ? 'sheet' : 'styleSheet',
-		storage = storageNode[sheet],//css rules must remain in a stylesheet for IE and FF
-		rules = storage.rules ? 'rules' : 'cssRules',
-		remove = storage.deleteRule ? 'deleteRule' : 'removeRule',
-		owner = storage.ownerNode ? 'ownerNode' : 'owningElement',		
-		reRule = /^([^{]+)\{([^}]*)\}/m,
-		reStyle = /([^:]+):([^;}]+)/;	
-
-//	storage.disabled = true;//let's ignore your rules 
-	
-	var $rule = $.rule = function( r, c ){
-		if(!(this instanceof $rule))
-			return new $rule( r, c );
-
-		this.sheets = $rule.sheets(c);
-		if( r && reRule.test(r) )
-			r = $rule.clean( r );
-		if( typeof r == 'object' && !r.exec ) {
-			setArray( this, r.get ? r.get() : r.splice ? r : [r] );
-		} else {
-			setArray( this, this.sheets.cssRules().get() );
-			if (r)
-				return this.filter( r );
-		}
-		return this;
-	};
-	
-	$.extend( $rule, {
-		sheets:function( c ){
-			var o = c;
-			if( typeof o != 'object' )
-				o = $.makeArray(document.styleSheets);
-			o = $(o).not(storage);//skip our stylesheet
-			if( typeof c == 'string' )
-				o = o.ownerNode().filter(c).sheet();
-			return o;
-		},
-		rule:function( str ){
-			if( str.selectorText )/* * */
-				return [ '', str.selectorText, str.style.cssText ];
-			return reRule.exec( str );
-		},
-		appendTo:function( r, ss, skip ){
-			switch( typeof ss ){//find the desired stylesheet
-				case 'string': ss = this.sheets(ss);
-				case 'object':
-					if( ss[0] ) ss = ss[0];
-					if( ss[sheet] ) ss = ss[sheet];
-					if( ss[rules] ) break;//only if the stylesheet is valid
-				default:
-					if( typeof r == 'object' ) return r;//let's not waist time, it is parsed
-					ss = storage;
-			}
-			var p;
-			if( !skip && (p = this.parent(r)) )//if this is an actual rule, and it's appended.
-				r = this.remove( r, p );
-				
-			var rule = this.rule( r );			
-			if( ss.addRule )
-				ss.addRule( rule[1], rule[2]||';' );//IE won't allow empty rules
-			else if( ss.insertRule )
-				ss.insertRule( rule[1] + '{'+ rule[2] +'}', ss[rules].length );
-			
-			return ss[rules][ ss[rules].length - 1 ];//return the added/parsed rule
-		},
-		remove:function( r, p ){
-			p = p || this.parent(r);
-			if( p != storage ){//let's save some unnecesary cycles.
-				var i = p ? $.inArray( r, p[rules] ) : -1;
-				if( i != -1 ){//if not stored before removal, IE will crash eventually, and some rules in FF get messed up
-					r = this.appendTo( r, 0 /*storage*/, true );//is faster and shorter to imply storage
-					p[remove](i);
-				}
-			}
-			return r;
-		},
-		clean:function( r ){
-			return $.map( r.split('}'), function( txt ){
-				if( txt )
-					return $rule.appendTo( txt + '}' /*, storage*/ );//parse the string, storage implied
-			});
-		},
-		parent:function( r ){//CSS rules in IE don't have parentStyleSheet attribute
-			if( typeof r == 'string' || !$.browser.msie )//if it's a string, just return undefined.
-				return r.parentStyleSheet;
-
-			var par;
-			this.sheets().each(function(){
-				if( $.inArray(r, this[rules]) != -1 ){
-					par = this;	
-					return false;
-				}
-			});
-			return par;
-		},
-		outerText:function( rule ){
-			return !rule || !rule.selectorText ? '' : [rule.selectorText+'{', '\t'+rule.style.cssText,'}'].join('\n').toLowerCase();
-		},
-		text:function( rule, txt ){
-			if( txt !== undefined )
-				rule.style.cssText = txt;
-			return !rule ? '' : rule.style.cssText.toLowerCase();
-		}
-	});
-	
-	$rule.fn = $rule.prototype = {
-		pushStack:function( rs, sh ){
-			var ret = $rule( rs, sh || this.sheets );
-			ret.prevObject = this;
-			return ret;
-		},
-		end:function(){
-			return this.prevObject || $rule(0,[]);
-		},
-		filter:function( s ){
-			var o;
-			if( !s ) s = /./;//just keep them all.
-			if( s.split ){
-				o = $.trim(s).toLowerCase().split(/\s*,\s*/);
-				s = function(){
-					var s = this.selectorText || '';
-					return !!$.grep( s.toLowerCase().split(/\s*,\s*/), function( sel ){
-						return $.inArray( sel, o ) != -1;
-					}).length;
-				};
-			}else if( s.exec ){//string regex, or actual regex
-				o = s;
-				s = function(){ return o.test(this.selectorText); };
-			}
-			return this.pushStack($.grep( this, function( e, i ){
-				return s.call( e, i );
-			}));
-		},
-		add:function( rs, c ){
-			return this.pushStack( $.merge(this.get(), $rule(rs, c)) );	
-		},
-		is:function( s ){
-			return !!(s && this.filter( s ).length);
-		},
-		not:function( n, c ){
-			n = $rule( n, c );
-			return this.filter(function(){
-				return $.inArray( this, n ) == -1;
-			});
-		},
-		append:function( s ){
-			var rules = this, rule;
-			$.each( s.split(/\s*;\s*/),function(i,v){
-				if(( rule = reStyle.exec( v ) ))
-					rules.css( rule[1], rule[2] );
-			});
-			return this;
-		},
-		text:function( txt ){
-			return !arguments.length ? $rule.text( this[0] )
-				: this.each(function(){	$rule.text( this, txt ); });
-		},
-		outerText:function(){
-			return $rule.outerText(this[0]);	
-		}
-	};
-	
-	$.each({
-		ownerNode:owner,//when having the stylesheet, get the node that contains it
-		sheet:sheet, //get the stylesheet from the node
-		cssRules:rules //get the rules from the stylesheet.
-	},function( m, a ){
-		var many = a == rules;//the rules need some more processing
-		$.fn[m] = function(){
-			return this.map(function(){
-				return many ? $.makeArray(this[a]) : this[a];
-			});
-		};
-	});
-	
-	$.fn.cssText = function(){
-		return this.filter('link,style').eq(0).sheet().cssRules().map(function(){
-			return $rule.outerText(this);							   
-		}).get().join('\n');
-	};
-	
-	$.each('remove,appendTo,parent'.split(','),function( k, f ){
-		$rule.fn[f] = function(){
-			var args = $.makeArray(arguments), that = this;
-			args.unshift(0);
-			return this.each(function( i ){
-				args[0] = this;
-				that[i] = $rule[f].apply( $rule, args ) || that[i];
-			});
-		};
-	});
-		
-	$.each(('each,index,get,size,eq,slice,map,attr,andSelf,css,show,hide,toggle,'+
-			'queue,dequeue,stop,animate,fadeIn,fadeOut,fadeTo').split(','),function( k, f ){
-		$rule.fn[f] = $.fn[f];																				  
-	});
-	
-	// this function has been pulled in from jQuery 1.4.1, because it is an internal function and has been dropped as of 1.4.2
-	function setArray(rule, elems) { 
-		rule.length = 0;
-		Array.prototype.push.apply( rule, elems );
-	}
-	
-	var curCSS = $.curCSS;
-	$.curCSS = function( e, a ){//this hack is still quite exprimental
-		return ('selectorText' in e ) ?
-			e.style[a] || $.prop( e, a=='opacity'? 1 : 0,'curCSS', 0, a )//TODO: improve these defaults
-		: curCSS.apply(this,arguments);
-	};
-	
-	/**
-	 * Time to hack jQuery.data for animations.
-	 * Only IE really needs this, but to keep the behavior consistent, I'll hack it for all browsers.
-	 * TODO: This kind of id doesn't seem to be good enough
-	 * TODO: Avoid animating similar rules simultaneously
-	 * TODO: Avoid rules' precedence from interfering on animations ?
-	 */
-	$rule.cache = {};
-	var mediator = function( original ){
-		return function( elm ){
-			var id = elm.selectorText;
-			if( id )
-				arguments[0] = $rule.cache[id] = $rule.cache[id] || {};
-			return original.apply( $, arguments );	
-		};
-	};
-	$.data = mediator( $.data );
-	$.removeData = mediator( $.removeData );
-	
-	$(window).unload(function(){
-		$(storage).cssRules().remove();//empty our rules bin
-	});
-		
-})( jQuery );

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/job-submit.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/job-submit.js	2013-06-28 11:44:54 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/job-submit.js	1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
-$(window).ready(
-    function () {
-        $("#json-input").linedtextarea();
-
-        $("#json-input").bind('paste', function() {
-            // Need a timeout since paste event does not give the content
-            // of the clipboard.
-            setTimeout(function(){
-                validate_input($("#json-input").val());
-            },100);
-        });
-
-        $("#json-input").blur(function() {
-            validate_input($("#json-input").val());
-        });
-
-        $("#submit").attr("disabled", "disabled");
-    });
-
-validate_input = function(json_input) {
-
-    if ($("#json-input").val() != "") {
-        if ($("#json-input").val().split("\n").length == 1) {
-            load_url();
-        } else {
-            validate_job_data(json_input);
-        }
-    }
-}
-
-load_url = function() {
-    // Loads JSON content if URL is provided in the json text area.
-    if ($("#json-input").val().split("\n").length == 1) {
-        $.ajax({
-            type: "POST",
-            url: remote_json_url,
-            data: {
-                "url": $("#json-input").val().trim(),
-                "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()
-            },
-            success: function(data) {
-                try {
-                    $.parseJSON(data);
-                    $("#json-input").val(data);
-                    validate_job_data(data);
-                } catch (e) {
-                    $("#json-valid-container").html("Invalid JSON: " + data);
-                    valid_json_css(false);
-                    $("#submit").attr("disabled", "disabled");
-                }
-            }});
-    }
-}
-
-validate_job_data = function(data) {
-    $.post(window.location.pathname,
-           {"json-input": data,
-            "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()},
-           function(data) {
-               if (data == "success") {
-                   $("#json-valid-container").html("Valid JSON.");
-                   valid_json_css(true);
-                   $("#submit").removeAttr("disabled");
-                   unselect_error_line();
-               } else {
-                   $("#json-valid-container").html(
-                       data.replace("[u'", "").replace("']", "").
-                           replace('[u"', "").replace('"]', ""));
-                   valid_json_css(false);
-                   $("#submit").attr("disabled", "disabled");
-                   select_error_line(data);
-               }
-           }, "json");
-}
-
-
-valid_json_css = function(success) {
-    // Updates the css of the json validation container with appropriate msg.
-    if (success) {
-        $("#json-valid-container").css("backgound-color", "#50ef53");
-        $("#json-valid-container").css("color", "#139a16");
-        $("#json-valid-container").css("border-color", "#139a16");
-        $("#json-valid-container").show();
-    } else {
-        $("#json-valid-container").css("backgound-color", "#ff8383");
-        $("#json-valid-container").css("color", "#da110a");
-        $("#json-valid-container").css("border-color", "#da110a");
-        $("#json-valid-container").show();
-    }
-}
-
-unselect_error_line = function() {
-    // Unselect any potential previously selected lines.
-    $(".lineno").removeClass("lineselect");
-}
-
-select_error_line = function(error) {
-    // Selects the appropriate line in text area based on the parsed error msg.
-    line_string = error.split(": ")[1];
-    line_number = parseInt(line_string.split(" ")[1]);
-
-    $(".lineno").removeClass("lineselect");
-    $("#lineno"+line_number).addClass("lineselect");
-
-    // Scroll the textarea to the highlighted line.
-    $("#json-input").scrollTop(
-        line_number * (parseInt($("#lineno1").css(
-            "height")) - 1) - ($("#json-input").height() / 2));
-}

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/jquery-linedtextarea.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/jquery-linedtextarea.js	2013-06-26 11:39:05 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/jquery-linedtextarea.js	1970-01-01 00:00:00 +0000
@@ -1,119 +0,0 @@
-/**
- * jQuery Lined Textarea Plugin
- *   http://alan.blog-city.com/jquerylinedtextarea.htm
- *
- * Copyright (c) 2010 Alan Williamson
- *
- * Contributions done by Ryan Zielke (NeoAlchemy@gmail.com)
- *
- * Version:
- *    $Id: jquery-linedtextarea.js 464 2010-01-08 10:36:33Z alan $
- *
- * Released under the MIT License:
- *    http://www.opensource.org/licenses/mit-license.php
- *
- * Usage:
- *   Displays a line number count column to the left of the textarea
- *
- *   Class up your textarea with a given class, or target it directly
- *   with JQuery Selectors
- *
- *   $(".lined").linedtextarea({
- *   	selectedLine: 10,
- *    selectedClass: 'lineselect'
- *   });
- */
-
-(function($) {
-    $.fn.linedtextarea = function(options) {
-	// Get the Options
-	var opts = $.extend({}, $.fn.linedtextarea.defaults, options);
-
-	/*
-	 * Helper function to make sure the line numbers are always
-	 * kept up to the current system
-	 */
-	var fillOutLines = function(codeLines, h, lineNo){
-	    while ( (codeLines.height() - h ) <= 0 ){
-		if ( lineNo == opts.selectedLine )
-		    codeLines.append("<div id='lineno" + lineNo + "' class='lineno lineselect'>" + lineNo + "</div>");
-		else
-		    codeLines.append("<div id='lineno" + lineNo + "' class='lineno'>" + lineNo + "</div>");
-
-		lineNo++;
-	    }
-	    return lineNo;
-	};
-
-	/*
-	 * Iterate through each of the elements are to be applied to
-	 */
-	return this.each(function() {
-	    var lineNo = 1;
-	    var textarea = $(this);
-
-	    /* Turn off the wrapping of as we don't want to screw up the line numbers */
-	    textarea.attr("wrap", "off");
-	    textarea.css({resize:'both'});
-	    var originalTextAreaWidth = textarea.outerWidth();
-
-	    /* Wrap the text area in the elements we need */
-	    var linedTextAreaDiv = textarea.wrap("<div class='linedwrap'></div>");
-	    var linedWrapDiv = linedTextAreaDiv.parent();
-
-	    linedWrapDiv.prepend("<div class='lines' style='width:50px'></div>");
-
-	    var linesDiv = linedWrapDiv.find(".lines");
-
-	    /* Draw the number bar; filling it out where necessary */
-	    linesDiv.append("<div class='codelines'></div>");
-	    var codeLinesDiv = linesDiv.find(".codelines");
-	    lineNo = fillOutLines( codeLinesDiv, linesDiv.height(), 1 );
-
-	    /* Move the textarea to the selected line */
-	    if ( opts.selectedLine != -1 && !isNaN(opts.selectedLine) ){
-		var fontSize = parseInt( textarea.height() / (lineNo-2) );
-		var position = parseInt( fontSize * opts.selectedLine ) - (textarea.height()/2);
-		textarea[0].scrollTop = position;
-	    }
-
-	    /* Set the width */
-	    var sidebarWidth = linesDiv.outerWidth(true);
-	    var paddingHorizontal = parseInt( linedWrapDiv.css("border-left-width") ) + parseInt( linedWrapDiv.css("border-right-width") ) + parseInt( linedWrapDiv.css("padding-left") ) + parseInt( linedWrapDiv.css("padding-right") );
-	    var linedWrapDivNewWidth = originalTextAreaWidth - paddingHorizontal;
-	    var textareaNewWidth = originalTextAreaWidth - sidebarWidth - paddingHorizontal;
-
-	    textarea.width(textareaNewWidth);
-	    textarea.css({maxWidth: textareaNewWidth - 6}); //TODO make this calculated
-
-	    /* React to the scroll event */
-	    textarea.scroll( function(tn){
-		var domTextArea = $(this)[0];
-		var scrollTop = domTextArea.scrollTop;
-		var clientHeight = domTextArea.clientHeight;
-		codeLinesDiv.css({'margin-top': (-1*scrollTop) + "px"});
-		lineNo = fillOutLines(codeLinesDiv, scrollTop + clientHeight, lineNo);
-	    });
-
-	    /* Should the textarea get resized outside of our control */
-	    textarea.resize( function(tn){
-		var domTextArea	= $(this)[0];
-		linesDiv.height(domTextArea.clientHeight + 6);
-	    });
-
-	    window.setInterval( function(tn) {
-		linesDiv.height(textarea.height());
-		var scrollTop = textarea[0].scrollTop;
-		var clientHeight = textarea[0].clientHeight;
-		codeLinesDiv.css({'margin-top': (-1*scrollTop) + "px"});
-		lineNo = fillOutLines(codeLinesDiv, scrollTop + clientHeight, lineNo);
-	    },10);
-	});
-    };
-
-    // default options
-    $.fn.linedtextarea.defaults = {
-  	selectedLine: -1,
-  	selectedClass: 'lineselect'
-    };
-})(jQuery);

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/jquery.details.min.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/jquery.details.min.js	2012-02-07 23:58:06 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/jquery.details.min.js	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-/*! http://mths.be/details v0.0.1 by @mathias */
-(function(a,$){var c=$.fn,b,d=(function(i){var g=i.createElement("details"),f,e,h;if(!("open" in g)){return false}e=i.body||(function(){var j=i.documentElement;f=true;return j.insertBefore(i.createElement("body"),j.firstElementChild||j.firstChild)}());g.innerHTML="<summary>a</summary>b";g.style.display="block";e.appendChild(g);h=g.offsetHeight;g.open=true;h=h!=g.offsetHeight;e.removeChild(g);if(f){e.parentNode.removeChild(e)}return h}(a));
-/*! http://mths.be/noselect v1.0.2 by @mathias */
-c.noSelect=function(){var e="none";return this.bind("selectstart dragstart mousedown",function(){return false}).css({MozUserSelect:e,WebkitUserSelect:e,userSelect:e})};if(d){b=c.details=function(){return this};b.support=d}else{b=c.details=function(){return this.each(function(){var e=$(this),h=$("summary",e),g=e.children(":not(summary)"),i=e.contents(":not(summary)"),f=this.getAttribute("open");if(!h.length){h=$(a.createElement("summary")).text("Details").prependTo(e)}if(g.length!=i.length){i.filter(function(){return(this.nodeType===3)&&(/[^ \t\n\f\r]/.test(this.data))}).wrap("<span>");g=e.children(":not(summary)")}if(typeof f=="string"||(typeof f=="boolean"&&f)){e.addClass("open");g.show()}else{g.hide()}h.noSelect().attr("tabIndex",0).click(function(){h.focus();typeof e.attr("open")!="undefined"?e.removeAttr("open"):e.attr("open","open");g.toggle(0);e.toggleClass("open")}).keyup(function(j){if(13===j.keyCode||32===j.keyCode){if(!($.browser.opera&&13===j.keyCode)){j.preventDefault();h.click()}}})})};b.support=d}}(document,jQuery));
\ No newline at end of file

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/jquery.flot.min.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/jquery.flot.min.js	2012-06-18 18:49:51 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/jquery.flot.min.js	1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-/* Javascript plotting library for jQuery, v. 0.7.
- *
- * Released under the MIT license by IOLA, December 2007.
- *
- */
-(function(b){b.color={};b.color.make=function(d,e,g,f){var c={};c.r=d||0;c.g=e||0;c.b=g||0;c.a=f!=null?f:1;c.add=function(h,j){for(var k=0;k<h.length;++k){c[h.charAt(k)]+=j}return c.normalize()};c.scale=function(h,j){for(var k=0;k<h.length;++k){c[h.charAt(k)]*=j}return c.normalize()};c.toString=function(){if(c.a>=1){return"rgb("+[c.r,c.g,c.b].join(",")+")"}else{return"rgba("+[c.r,c.g,c.b,c.a].join(",")+")"}};c.normalize=function(){function h(k,j,l){return j<k?k:(j>l?l:j)}c.r=h(0,parseInt(c.r),255);c.g=h(0,parseInt(c.g),255);c.b=h(0,parseInt(c.b),255);c.a=h(0,c.a,1);return c};c.clone=function(){return b.color.make(c.r,c.b,c.g,c.a)};return c.normalize()};b.color.extract=function(d,e){var c;do{c=d.css(e).toLowerCase();if(c!=""&&c!="transparent"){break}d=d.parent()}while(!b.nodeName(d.get(0),"body"));if(c=="rgba(0, 0, 0, 0)"){c="transparent"}return b.color.parse(c)};b.color.parse=function(c){var d,f=b.color.make;if(d=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c)){return f(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10))}if(d=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c)){return f(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10),parseFloat(d[4]))}if(d=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c)){return f(parseFloat(d[1])*2.55,parseFloat(d[2])*2.55,parseFloat(d[3])*2.55)}if(d=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c)){return f(parseFloat(d[1])*2.55,parseFloat(d[2])*2.55,parseFloat(d[3])*2.55,parseFloat(d[4]))}if(d=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c)){return f(parseInt(d[1],16),parseInt(d[2],16),parseInt(d[3],16))}if(d=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c)){return f(parseInt(d[1]+d[1],16),parseInt(d[2]+d[2],16),parseInt(d[3]+d[3],16))}var e=b.trim(c).toLowerCase();if(e=="transparent"){return f(255,255,255,0)}else{d=a[e]||[0,0,0];return f(d[0],d[1],d[2])}};var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);(function(c){function b(av,ai,J,af){var Q=[],O={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:0.85},xaxis:{show:null,position:"bottom",mode:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null,monthNames:null,timeformat:null,twelveHourClock:false},yaxis:{autoscaleMargin:0.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:false,fillColor:null,steps:false},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left",horizontal:false},shadowSize:3},grid:{show:true,aboveData:false,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},hooks:{}},az=null,ad=null,y=null,H=null,A=null,p=[],aw=[],q={left:0,right:0,top:0,bottom:0},G=0,I=0,h=0,w=0,ak={processOptions:[],processRawData:[],processDatapoints:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},aq=this;aq.setData=aj;aq.setupGrid=t;aq.draw=W;aq.getPlaceholder=function(){return av};aq.getCanvas=function(){return az};aq.getPlotOffset=function(){return q};aq.width=function(){return h};aq.height=function(){return w};aq.offset=function(){var aB=y.offset();aB.left+=q.left;aB.top+=q.top;return aB};aq.getData=function(){return Q};aq.getAxes=function(){var aC={},aB;c.each(p.concat(aw),function(aD,aE){if(aE){aC[aE.direction+(aE.n!=1?aE.n:"")+"axis"]=aE}});return aC};aq.getXAxes=function(){return p};aq.getYAxes=function(){return aw};aq.c2p=C;aq.p2c=ar;aq.getOptions=function(){return O};aq.highlight=x;aq.unhighlight=T;aq.triggerRedrawOverlay=f;aq.pointOffset=function(aB){return{left:parseInt(p[aA(aB,"x")-1].p2c(+aB.x)+q.left),top:parseInt(aw[aA(aB,"y")-1].p2c(+aB.y)+q.top)}};aq.shutdown=ag;aq.resize=function(){B();g(az);g(ad)};aq.hooks=ak;F(aq);Z(J);X();aj(ai);t();W();ah();function an(aD,aB){aB=[aq].concat(aB);for(var aC=0;aC<aD.length;++aC){aD[aC].apply(this,aB)}}function F(){for(var aB=0;aB<af.length;++aB){var aC=af[aB];aC.init(aq);if(aC.options){c.extend(true,O,aC.options)}}}function Z(aC){var aB;c.extend(true,O,aC);if(O.xaxis.color==null){O.xaxis.color=O.grid.color}if(O.yaxis.color==null){O.yaxis.color=O.grid.color}if(O.xaxis.tickColor==null){O.xaxis.tickColor=O.grid.tickColor}if(O.yaxis.tickColor==null){O.yaxis.tickColor=O.grid.tickColor}if(O.grid.borderColor==null){O.grid.borderColor=O.grid.color}if(O.grid.tickColor==null){O.grid.tickColor=c.color.parse(O.grid.color).scale("a",0.22).toString()}for(aB=0;aB<Math.max(1,O.xaxes.length);++aB){O.xaxes[aB]=c.extend(true,{},O.xaxis,O.xaxes[aB])}for(aB=0;aB<Math.max(1,O.yaxes.length);++aB){O.yaxes[aB]=c.extend(true,{},O.yaxis,O.yaxes[aB])}if(O.xaxis.noTicks&&O.xaxis.ticks==null){O.xaxis.ticks=O.xaxis.noTicks}if(O.yaxis.noTicks&&O.yaxis.ticks==null){O.yaxis.ticks=O.yaxis.noTicks}if(O.x2axis){O.xaxes[1]=c.extend(true,{},O.xaxis,O.x2axis);O.xaxes[1].position="top"}if(O.y2axis){O.yaxes[1]=c.extend(true,{},O.yaxis,O.y2axis);O.yaxes[1].position="right"}if(O.grid.coloredAreas){O.grid.markings=O.grid.coloredAreas}if(O.grid.coloredAreasColor){O.grid.markingsColor=O.grid.coloredAreasColor}if(O.lines){c.extend(true,O.series.lines,O.lines)}if(O.points){c.extend(true,O.series.points,O.points)}if(O.bars){c.extend(true,O.series.bars,O.bars)}if(O.shadowSize!=null){O.series.shadowSize=O.shadowSize}for(aB=0;aB<O.xaxes.length;++aB){V(p,aB+1).options=O.xaxes[aB]}for(aB=0;aB<O.yaxes.length;++aB){V(aw,aB+1).options=O.yaxes[aB]}for(var aD in ak){if(O.hooks[aD]&&O.hooks[aD].length){ak[aD]=ak[aD].concat(O.hooks[aD])}}an(ak.processOptions,[O])}function aj(aB){Q=Y(aB);ax();z()}function Y(aE){var aC=[];for(var aB=0;aB<aE.length;++aB){var aD=c.extend(true,{},O.series);if(aE[aB].data!=null){aD.data=aE[aB].data;delete aE[aB].data;c.extend(true,aD,aE[aB]);aE[aB].data=aD.data}else{aD.data=aE[aB]}aC.push(aD)}return aC}function aA(aC,aD){var aB=aC[aD+"axis"];if(typeof aB=="object"){aB=aB.n}if(typeof aB!="number"){aB=1}return aB}function m(){return c.grep(p.concat(aw),function(aB){return aB})}function C(aE){var aC={},aB,aD;for(aB=0;aB<p.length;++aB){aD=p[aB];if(aD&&aD.used){aC["x"+aD.n]=aD.c2p(aE.left)}}for(aB=0;aB<aw.length;++aB){aD=aw[aB];if(aD&&aD.used){aC["y"+aD.n]=aD.c2p(aE.top)}}if(aC.x1!==undefined){aC.x=aC.x1}if(aC.y1!==undefined){aC.y=aC.y1}return aC}function ar(aF){var aD={},aC,aE,aB;for(aC=0;aC<p.length;++aC){aE=p[aC];if(aE&&aE.used){aB="x"+aE.n;if(aF[aB]==null&&aE.n==1){aB="x"}if(aF[aB]!=null){aD.left=aE.p2c(aF[aB]);break}}}for(aC=0;aC<aw.length;++aC){aE=aw[aC];if(aE&&aE.used){aB="y"+aE.n;if(aF[aB]==null&&aE.n==1){aB="y"}if(aF[aB]!=null){aD.top=aE.p2c(aF[aB]);break}}}return aD}function V(aC,aB){if(!aC[aB-1]){aC[aB-1]={n:aB,direction:aC==p?"x":"y",options:c.extend(true,{},aC==p?O.xaxis:O.yaxis)}}return aC[aB-1]}function ax(){var aG;var aM=Q.length,aB=[],aE=[];for(aG=0;aG<Q.length;++aG){var aJ=Q[aG].color;if(aJ!=null){--aM;if(typeof aJ=="number"){aE.push(aJ)}else{aB.push(c.color.parse(Q[aG].color))}}}for(aG=0;aG<aE.length;++aG){aM=Math.max(aM,aE[aG]+1)}var aC=[],aF=0;aG=0;while(aC.length<aM){var aI;if(O.colors.length==aG){aI=c.color.make(100,100,100)}else{aI=c.color.parse(O.colors[aG])}var aD=aF%2==1?-1:1;aI.scale("rgb",1+aD*Math.ceil(aF/2)*0.2);aC.push(aI);++aG;if(aG>=O.colors.length){aG=0;++aF}}var aH=0,aN;for(aG=0;aG<Q.length;++aG){aN=Q[aG];if(aN.color==null){aN.color=aC[aH].toString();++aH}else{if(typeof aN.color=="number"){aN.color=aC[aN.color].toString()}}if(aN.lines.show==null){var aL,aK=true;for(aL in aN){if(aN[aL]&&aN[aL].show){aK=false;break}}if(aK){aN.lines.show=true}}aN.xaxis=V(p,aA(aN,"x"));aN.yaxis=V(aw,aA(aN,"y"))}}function z(){var aO=Number.POSITIVE_INFINITY,aI=Number.NEGATIVE_INFINITY,aB=Number.MAX_VALUE,aU,aS,aR,aN,aD,aJ,aT,aP,aH,aG,aC,a0,aX,aL;function aF(a3,a2,a1){if(a2<a3.datamin&&a2!=-aB){a3.datamin=a2}if(a1>a3.datamax&&a1!=aB){a3.datamax=a1}}c.each(m(),function(a1,a2){a2.datamin=aO;a2.datamax=aI;a2.used=false});for(aU=0;aU<Q.length;++aU){aJ=Q[aU];aJ.datapoints={points:[]};an(ak.processRawData,[aJ,aJ.data,aJ.datapoints])}for(aU=0;aU<Q.length;++aU){aJ=Q[aU];var aZ=aJ.data,aW=aJ.datapoints.format;if(!aW){aW=[];aW.push({x:true,number:true,required:true});aW.push({y:true,number:true,required:true});if(aJ.bars.show||(aJ.lines.show&&aJ.lines.fill)){aW.push({y:true,number:true,required:false,defaultValue:0});if(aJ.bars.horizontal){delete aW[aW.length-1].y;aW[aW.length-1].x=true}}aJ.datapoints.format=aW}if(aJ.datapoints.pointsize!=null){continue}aJ.datapoints.pointsize=aW.length;aP=aJ.datapoints.pointsize;aT=aJ.datapoints.points;insertSteps=aJ.lines.show&&aJ.lines.steps;aJ.xaxis.used=aJ.yaxis.used=true;for(aS=aR=0;aS<aZ.length;++aS,aR+=aP){aL=aZ[aS];var aE=aL==null;if(!aE){for(aN=0;aN<aP;++aN){a0=aL[aN];aX=aW[aN];if(aX){if(aX.number&&a0!=null){a0=+a0;if(isNaN(a0)){a0=null}else{if(a0==Infinity){a0=aB}else{if(a0==-Infinity){a0=-aB}}}}if(a0==null){if(aX.required){aE=true}if(aX.defaultValue!=null){a0=aX.defaultValue}}}aT[aR+aN]=a0}}if(aE){for(aN=0;aN<aP;++aN){a0=aT[aR+aN];if(a0!=null){aX=aW[aN];if(aX.x){aF(aJ.xaxis,a0,a0)}if(aX.y){aF(aJ.yaxis,a0,a0)}}aT[aR+aN]=null}}else{if(insertSteps&&aR>0&&aT[aR-aP]!=null&&aT[aR-aP]!=aT[aR]&&aT[aR-aP+1]!=aT[aR+1]){for(aN=0;aN<aP;++aN){aT[aR+aP+aN]=aT[aR+aN]}aT[aR+1]=aT[aR-aP+1];aR+=aP}}}}for(aU=0;aU<Q.length;++aU){aJ=Q[aU];an(ak.processDatapoints,[aJ,aJ.datapoints])}for(aU=0;aU<Q.length;++aU){aJ=Q[aU];aT=aJ.datapoints.points,aP=aJ.datapoints.pointsize;var aK=aO,aQ=aO,aM=aI,aV=aI;for(aS=0;aS<aT.length;aS+=aP){if(aT[aS]==null){continue}for(aN=0;aN<aP;++aN){a0=aT[aS+aN];aX=aW[aN];if(!aX||a0==aB||a0==-aB){continue}if(aX.x){if(a0<aK){aK=a0}if(a0>aM){aM=a0}}if(aX.y){if(a0<aQ){aQ=a0}if(a0>aV){aV=a0}}}}if(aJ.bars.show){var aY=aJ.bars.align=="left"?0:-aJ.bars.barWidth/2;if(aJ.bars.horizontal){aQ+=aY;aV+=aY+aJ.bars.barWidth}else{aK+=aY;aM+=aY+aJ.bars.barWidth}}aF(aJ.xaxis,aK,aM);aF(aJ.yaxis,aQ,aV)}c.each(m(),function(a1,a2){if(a2.datamin==aO){a2.datamin=null}if(a2.datamax==aI){a2.datamax=null}})}function j(aB,aC){var aD=document.createElement("canvas");aD.className=aC;aD.width=G;aD.height=I;if(!aB){c(aD).css({position:"absolute",left:0,top:0})}c(aD).appendTo(av);if(!aD.getContext){aD=window.G_vmlCanvasManager.initElement(aD)}aD.getContext("2d").save();return aD}function B(){G=av.width();I=av.height();if(G<=0||I<=0){throw"Invalid dimensions for plot, width = "+G+", height = "+I}}function g(aC){if(aC.width!=G){aC.width=G}if(aC.height!=I){aC.height=I}var aB=aC.getContext("2d");aB.restore();aB.save()}function X(){var aC,aB=av.children("canvas.base"),aD=av.children("canvas.overlay");if(aB.length==0||aD==0){av.html("");av.css({padding:0});if(av.css("position")=="static"){av.css("position","relative")}B();az=j(true,"base");ad=j(false,"overlay");aC=false}else{az=aB.get(0);ad=aD.get(0);aC=true}H=az.getContext("2d");A=ad.getContext("2d");y=c([ad,az]);if(aC){av.data("plot").shutdown();aq.resize();A.clearRect(0,0,G,I);y.unbind();av.children().not([az,ad]).remove()}av.data("plot",aq)}function ah(){if(O.grid.hoverable){y.mousemove(aa);y.mouseleave(l)}if(O.grid.clickable){y.click(R)}an(ak.bindEvents,[y])}function ag(){if(M){clearTimeout(M)}y.unbind("mousemove",aa);y.unbind("mouseleave",l);y.unbind("click",R);an(ak.shutdown,[y])}function r(aG){function aC(aH){return aH}var aF,aB,aD=aG.options.transform||aC,aE=aG.options.inverseTransform;if(aG.direction=="x"){aF=aG.scale=h/Math.abs(aD(aG.max)-aD(aG.min));aB=Math.min(aD(aG.max),aD(aG.min))}else{aF=aG.scale=w/Math.abs(aD(aG.max)-aD(aG.min));aF=-aF;aB=Math.max(aD(aG.max),aD(aG.min))}if(aD==aC){aG.p2c=function(aH){return(aH-aB)*aF}}else{aG.p2c=function(aH){return(aD(aH)-aB)*aF}}if(!aE){aG.c2p=function(aH){return aB+aH/aF}}else{aG.c2p=function(aH){return aE(aB+aH/aF)}}}function L(aD){var aB=aD.options,aF,aJ=aD.ticks||[],aI=[],aE,aK=aB.labelWidth,aG=aB.labelHeight,aC;function aH(aM,aL){return c('<div style="position:absolute;top:-10000px;'+aL+'font-size:smaller"><div class="'+aD.direction+"Axis "+aD.direction+aD.n+'Axis">'+aM.join("")+"</div></div>").appendTo(av)}if(aD.direction=="x"){if(aK==null){aK=Math.floor(G/(aJ.length>0?aJ.length:1))}if(aG==null){aI=[];for(aF=0;aF<aJ.length;++aF){aE=aJ[aF].label;if(aE){aI.push('<div class="tickLabel" style="float:left;width:'+aK+'px">'+aE+"</div>")}}if(aI.length>0){aI.push('<div style="clear:left"></div>');aC=aH(aI,"width:10000px;");aG=aC.height();aC.remove()}}}else{if(aK==null||aG==null){for(aF=0;aF<aJ.length;++aF){aE=aJ[aF].label;if(aE){aI.push('<div class="tickLabel">'+aE+"</div>")}}if(aI.length>0){aC=aH(aI,"");if(aK==null){aK=aC.children().width()}if(aG==null){aG=aC.find("div.tickLabel").height()}aC.remove()}}}if(aK==null){aK=0}if(aG==null){aG=0}aD.labelWidth=aK;aD.labelHeight=aG}function au(aD){var aC=aD.labelWidth,aL=aD.labelHeight,aH=aD.options.position,aF=aD.options.tickLength,aG=O.grid.axisMargin,aJ=O.grid.labelMargin,aK=aD.direction=="x"?p:aw,aE;var aB=c.grep(aK,function(aN){return aN&&aN.options.position==aH&&aN.reserveSpace});if(c.inArray(aD,aB)==aB.length-1){aG=0}if(aF==null){aF="full"}var aI=c.grep(aK,function(aN){return aN&&aN.reserveSpace});var aM=c.inArray(aD,aI)==0;if(!aM&&aF=="full"){aF=5}if(!isNaN(+aF)){aJ+=+aF}if(aD.direction=="x"){aL+=aJ;if(aH=="bottom"){q.bottom+=aL+aG;aD.box={top:I-q.bottom,height:aL}}else{aD.box={top:q.top+aG,height:aL};q.top+=aL+aG}}else{aC+=aJ;if(aH=="left"){aD.box={left:q.left+aG,width:aC};q.left+=aC+aG}else{q.right+=aC+aG;aD.box={left:G-q.right,width:aC}}}aD.position=aH;aD.tickLength=aF;aD.box.padding=aJ;aD.innermost=aM}function U(aB){if(aB.direction=="x"){aB.box.left=q.left;aB.box.width=h}else{aB.box.top=q.top;aB.box.height=w}}function t(){var aC,aE=m();c.each(aE,function(aF,aG){aG.show=aG.options.show;if(aG.show==null){aG.show=aG.used}aG.reserveSpace=aG.show||aG.options.reserveSpace;n(aG)});allocatedAxes=c.grep(aE,function(aF){return aF.reserveSpace});q.left=q.right=q.top=q.bottom=0;if(O.grid.show){c.each(allocatedAxes,function(aF,aG){S(aG);P(aG);ap(aG,aG.ticks);L(aG)});for(aC=allocatedAxes.length-1;aC>=0;--aC){au(allocatedAxes[aC])}var aD=O.grid.minBorderMargin;if(aD==null){aD=0;for(aC=0;aC<Q.length;++aC){aD=Math.max(aD,Q[aC].points.radius+Q[aC].points.lineWidth/2)}}for(var aB in q){q[aB]+=O.grid.borderWidth;q[aB]=Math.max(aD,q[aB])}}h=G-q.left-q.right;w=I-q.bottom-q.top;c.each(aE,function(aF,aG){r(aG)});if(O.grid.show){c.each(allocatedAxes,function(aF,aG){U(aG)});k()}o()}function n(aE){var aF=aE.options,aD=+(aF.min!=null?aF.min:aE.datamin),aB=+(aF.max!=null?aF.max:aE.datamax),aH=aB-aD;if(aH==0){var aC=aB==0?1:0.01;if(aF.min==null){aD-=aC}if(aF.max==null||aF.min!=null){aB+=aC}}else{var aG=aF.autoscaleMargin;if(aG!=null){if(aF.min==null){aD-=aH*aG;if(aD<0&&aE.datamin!=null&&aE.datamin>=0){aD=0}}if(aF.max==null){aB+=aH*aG;if(aB>0&&aE.datamax!=null&&aE.datamax<=0){aB=0}}}}aE.min=aD;aE.max=aB}function S(aG){var aM=aG.options;var aH;if(typeof aM.ticks=="number"&&aM.ticks>0){aH=aM.ticks}else{aH=0.3*Math.sqrt(aG.direction=="x"?G:I)}var aT=(aG.max-aG.min)/aH,aO,aB,aN,aR,aS,aQ,aI;if(aM.mode=="time"){var aJ={second:1000,minute:60*1000,hour:60*60*1000,day:24*60*60*1000,month:30*24*60*60*1000,year:365.2425*24*60*60*1000};var aK=[[1,"second"],[2,"second"],[5,"second"],[10,"second"],[30,"second"],[1,"minute"],[2,"minute"],[5,"minute"],[10,"minute"],[30,"minute"],[1,"hour"],[2,"hour"],[4,"hour"],[8,"hour"],[12,"hour"],[1,"day"],[2,"day"],[3,"day"],[0.25,"month"],[0.5,"month"],[1,"month"],[2,"month"],[3,"month"],[6,"month"],[1,"year"]];var aC=0;if(aM.minTickSize!=null){if(typeof aM.tickSize=="number"){aC=aM.tickSize}else{aC=aM.minTickSize[0]*aJ[aM.minTickSize[1]]}}for(var aS=0;aS<aK.length-1;++aS){if(aT<(aK[aS][0]*aJ[aK[aS][1]]+aK[aS+1][0]*aJ[aK[aS+1][1]])/2&&aK[aS][0]*aJ[aK[aS][1]]>=aC){break}}aO=aK[aS][0];aN=aK[aS][1];if(aN=="year"){aQ=Math.pow(10,Math.floor(Math.log(aT/aJ.year)/Math.LN10));aI=(aT/aJ.year)/aQ;if(aI<1.5){aO=1}else{if(aI<3){aO=2}else{if(aI<7.5){aO=5}else{aO=10}}}aO*=aQ}aG.tickSize=aM.tickSize||[aO,aN];aB=function(aX){var a2=[],a0=aX.tickSize[0],a3=aX.tickSize[1],a1=new Date(aX.min);var aW=a0*aJ[a3];if(a3=="second"){a1.setUTCSeconds(a(a1.getUTCSeconds(),a0))}if(a3=="minute"){a1.setUTCMinutes(a(a1.getUTCMinutes(),a0))}if(a3=="hour"){a1.setUTCHours(a(a1.getUTCHours(),a0))}if(a3=="month"){a1.setUTCMonth(a(a1.getUTCMonth(),a0))}if(a3=="year"){a1.setUTCFullYear(a(a1.getUTCFullYear(),a0))}a1.setUTCMilliseconds(0);if(aW>=aJ.minute){a1.setUTCSeconds(0)}if(aW>=aJ.hour){a1.setUTCMinutes(0)}if(aW>=aJ.day){a1.setUTCHours(0)}if(aW>=aJ.day*4){a1.setUTCDate(1)}if(aW>=aJ.year){a1.setUTCMonth(0)}var a5=0,a4=Number.NaN,aY;do{aY=a4;a4=a1.getTime();a2.push(a4);if(a3=="month"){if(a0<1){a1.setUTCDate(1);var aV=a1.getTime();a1.setUTCMonth(a1.getUTCMonth()+1);var aZ=a1.getTime();a1.setTime(a4+a5*aJ.hour+(aZ-aV)*a0);a5=a1.getUTCHours();a1.setUTCHours(0)}else{a1.setUTCMonth(a1.getUTCMonth()+a0)}}else{if(a3=="year"){a1.setUTCFullYear(a1.getUTCFullYear()+a0)}else{a1.setTime(a4+aW)}}}while(a4<aX.max&&a4!=aY);return a2};aR=function(aV,aY){var a0=new Date(aV);if(aM.timeformat!=null){return c.plot.formatDate(a0,aM.timeformat,aM.monthNames)}var aW=aY.tickSize[0]*aJ[aY.tickSize[1]];var aX=aY.max-aY.min;var aZ=(aM.twelveHourClock)?" %p":"";if(aW<aJ.minute){fmt="%h:%M:%S"+aZ}else{if(aW<aJ.day){if(aX<2*aJ.day){fmt="%h:%M"+aZ}else{fmt="%b %d %h:%M"+aZ}}else{if(aW<aJ.month){fmt="%b %d"}else{if(aW<aJ.year){if(aX<aJ.year){fmt="%b"}else{fmt="%b %y"}}else{fmt="%y"}}}}return c.plot.formatDate(a0,fmt,aM.monthNames)}}else{var aU=aM.tickDecimals;var aP=-Math.floor(Math.log(aT)/Math.LN10);if(aU!=null&&aP>aU){aP=aU}aQ=Math.pow(10,-aP);aI=aT/aQ;if(aI<1.5){aO=1}else{if(aI<3){aO=2;if(aI>2.25&&(aU==null||aP+1<=aU)){aO=2.5;++aP}}else{if(aI<7.5){aO=5}else{aO=10}}}aO*=aQ;if(aM.minTickSize!=null&&aO<aM.minTickSize){aO=aM.minTickSize}aG.tickDecimals=Math.max(0,aU!=null?aU:aP);aG.tickSize=aM.tickSize||aO;aB=function(aX){var aZ=[];var a0=a(aX.min,aX.tickSize),aW=0,aV=Number.NaN,aY;do{aY=aV;aV=a0+aW*aX.tickSize;aZ.push(aV);++aW}while(aV<aX.max&&aV!=aY);return aZ};aR=function(aV,aW){return aV.toFixed(aW.tickDecimals)}}if(aM.alignTicksWithAxis!=null){var aF=(aG.direction=="x"?p:aw)[aM.alignTicksWithAxis-1];if(aF&&aF.used&&aF!=aG){var aL=aB(aG);if(aL.length>0){if(aM.min==null){aG.min=Math.min(aG.min,aL[0])}if(aM.max==null&&aL.length>1){aG.max=Math.max(aG.max,aL[aL.length-1])}}aB=function(aX){var aY=[],aV,aW;for(aW=0;aW<aF.ticks.length;++aW){aV=(aF.ticks[aW].v-aF.min)/(aF.max-aF.min);aV=aX.min+aV*(aX.max-aX.min);aY.push(aV)}return aY};if(aG.mode!="time"&&aM.tickDecimals==null){var aE=Math.max(0,-Math.floor(Math.log(aT)/Math.LN10)+1),aD=aB(aG);if(!(aD.length>1&&/\..*0$/.test((aD[1]-aD[0]).toFixed(aE)))){aG.tickDecimals=aE}}}}aG.tickGenerator=aB;if(c.isFunction(aM.tickFormatter)){aG.tickFormatter=function(aV,aW){return""+aM.tickFormatter(aV,aW)}}else{aG.tickFormatter=aR}}function P(aF){var aH=aF.options.ticks,aG=[];if(aH==null||(typeof aH=="number"&&aH>0)){aG=aF.tickGenerator(aF)}else{if(aH){if(c.isFunction(aH)){aG=aH({min:aF.min,max:aF.max})}else{aG=aH}}}var aE,aB;aF.ticks=[];for(aE=0;aE<aG.length;++aE){var aC=null;var aD=aG[aE];if(typeof aD=="object"){aB=+aD[0];if(aD.length>1){aC=aD[1]}}else{aB=+aD}if(aC==null){aC=aF.tickFormatter(aB,aF)}if(!isNaN(aB)){aF.ticks.push({v:aB,label:aC})}}}function ap(aB,aC){if(aB.options.autoscaleMargin&&aC.length>0){if(aB.options.min==null){aB.min=Math.min(aB.min,aC[0].v)}if(aB.options.max==null&&aC.length>1){aB.max=Math.max(aB.max,aC[aC.length-1].v)}}}function W(){H.clearRect(0,0,G,I);var aC=O.grid;if(aC.show&&aC.backgroundColor){N()}if(aC.show&&!aC.aboveData){ac()}for(var aB=0;aB<Q.length;++aB){an(ak.drawSeries,[H,Q[aB]]);d(Q[aB])}an(ak.draw,[H]);if(aC.show&&aC.aboveData){ac()}}function D(aB,aI){var aE,aH,aG,aD,aF=m();for(i=0;i<aF.length;++i){aE=aF[i];if(aE.direction==aI){aD=aI+aE.n+"axis";if(!aB[aD]&&aE.n==1){aD=aI+"axis"}if(aB[aD]){aH=aB[aD].from;aG=aB[aD].to;break}}}if(!aB[aD]){aE=aI=="x"?p[0]:aw[0];aH=aB[aI+"1"];aG=aB[aI+"2"]}if(aH!=null&&aG!=null&&aH>aG){var aC=aH;aH=aG;aG=aC}return{from:aH,to:aG,axis:aE}}function N(){H.save();H.translate(q.left,q.top);H.fillStyle=am(O.grid.backgroundColor,w,0,"rgba(255, 255, 255, 0)");H.fillRect(0,0,h,w);H.restore()}function ac(){var aF;H.save();H.translate(q.left,q.top);var aH=O.grid.markings;if(aH){if(c.isFunction(aH)){var aK=aq.getAxes();aK.xmin=aK.xaxis.min;aK.xmax=aK.xaxis.max;aK.ymin=aK.yaxis.min;aK.ymax=aK.yaxis.max;aH=aH(aK)}for(aF=0;aF<aH.length;++aF){var aD=aH[aF],aC=D(aD,"x"),aI=D(aD,"y");if(aC.from==null){aC.from=aC.axis.min}if(aC.to==null){aC.to=aC.axis.max}if(aI.from==null){aI.from=aI.axis.min}if(aI.to==null){aI.to=aI.axis.max}if(aC.to<aC.axis.min||aC.from>aC.axis.max||aI.to<aI.axis.min||aI.from>aI.axis.max){continue}aC.from=Math.max(aC.from,aC.axis.min);aC.to=Math.min(aC.to,aC.axis.max);aI.from=Math.max(aI.from,aI.axis.min);aI.to=Math.min(aI.to,aI.axis.max);if(aC.from==aC.to&&aI.from==aI.to){continue}aC.from=aC.axis.p2c(aC.from);aC.to=aC.axis.p2c(aC.to);aI.from=aI.axis.p2c(aI.from);aI.to=aI.axis.p2c(aI.to);if(aC.from==aC.to||aI.from==aI.to){H.beginPath();H.strokeStyle=aD.color||O.grid.markingsColor;H.lineWidth=aD.lineWidth||O.grid.markingsLineWidth;H.moveTo(aC.from,aI.from);H.lineTo(aC.to,aI.to);H.stroke()}else{H.fillStyle=aD.color||O.grid.markingsColor;H.fillRect(aC.from,aI.to,aC.to-aC.from,aI.from-aI.to)}}}var aK=m(),aM=O.grid.borderWidth;for(var aE=0;aE<aK.length;++aE){var aB=aK[aE],aG=aB.box,aQ=aB.tickLength,aN,aL,aP,aJ;if(!aB.show||aB.ticks.length==0){continue}H.strokeStyle=aB.options.tickColor||c.color.parse(aB.options.color).scale("a",0.22).toString();H.lineWidth=1;if(aB.direction=="x"){aN=0;if(aQ=="full"){aL=(aB.position=="top"?0:w)}else{aL=aG.top-q.top+(aB.position=="top"?aG.height:0)}}else{aL=0;if(aQ=="full"){aN=(aB.position=="left"?0:h)}else{aN=aG.left-q.left+(aB.position=="left"?aG.width:0)}}if(!aB.innermost){H.beginPath();aP=aJ=0;if(aB.direction=="x"){aP=h}else{aJ=w}if(H.lineWidth==1){aN=Math.floor(aN)+0.5;aL=Math.floor(aL)+0.5}H.moveTo(aN,aL);H.lineTo(aN+aP,aL+aJ);H.stroke()}H.beginPath();for(aF=0;aF<aB.ticks.length;++aF){var aO=aB.ticks[aF].v;aP=aJ=0;if(aO<aB.min||aO>aB.max||(aQ=="full"&&aM>0&&(aO==aB.min||aO==aB.max))){continue}if(aB.direction=="x"){aN=aB.p2c(aO);aJ=aQ=="full"?-w:aQ;if(aB.position=="top"){aJ=-aJ}}else{aL=aB.p2c(aO);aP=aQ=="full"?-h:aQ;if(aB.position=="left"){aP=-aP}}if(H.lineWidth==1){if(aB.direction=="x"){aN=Math.floor(aN)+0.5}else{aL=Math.floor(aL)+0.5}}H.moveTo(aN,aL);H.lineTo(aN+aP,aL+aJ)}H.stroke()}if(aM){H.lineWidth=aM;H.strokeStyle=O.grid.borderColor;H.strokeRect(-aM/2,-aM/2,h+aM,w+aM)}H.restore()}function k(){av.find(".tickLabels").remove();var aG=['<div class="tickLabels" style="font-size:smaller">'];var aJ=m();for(var aD=0;aD<aJ.length;++aD){var aC=aJ[aD],aF=aC.box;if(!aC.show){continue}aG.push('<div class="'+aC.direction+"Axis "+aC.direction+aC.n+'Axis" style="color:'+aC.options.color+'">');for(var aE=0;aE<aC.ticks.length;++aE){var aH=aC.ticks[aE];if(!aH.label||aH.v<aC.min||aH.v>aC.max){continue}var aK={},aI;if(aC.direction=="x"){aI="center";aK.left=Math.round(q.left+aC.p2c(aH.v)-aC.labelWidth/2);if(aC.position=="bottom"){aK.top=aF.top+aF.padding}else{aK.bottom=I-(aF.top+aF.height-aF.padding)}}else{aK.top=Math.round(q.top+aC.p2c(aH.v)-aC.labelHeight/2);if(aC.position=="left"){aK.right=G-(aF.left+aF.width-aF.padding);aI="right"}else{aK.left=aF.left+aF.padding;aI="left"}}aK.width=aC.labelWidth;var aB=["position:absolute","text-align:"+aI];for(var aL in aK){aB.push(aL+":"+aK[aL]+"px")}aG.push('<div class="tickLabel" style="'+aB.join(";")+'">'+aH.label+"</div>")}aG.push("</div>")}aG.push("</div>");av.append(aG.join(""))}function d(aB){if(aB.lines.show){at(aB)}if(aB.bars.show){e(aB)}if(aB.points.show){ao(aB)}}function at(aE){function aD(aP,aQ,aI,aU,aT){var aV=aP.points,aJ=aP.pointsize,aN=null,aM=null;H.beginPath();for(var aO=aJ;aO<aV.length;aO+=aJ){var aL=aV[aO-aJ],aS=aV[aO-aJ+1],aK=aV[aO],aR=aV[aO+1];if(aL==null||aK==null){continue}if(aS<=aR&&aS<aT.min){if(aR<aT.min){continue}aL=(aT.min-aS)/(aR-aS)*(aK-aL)+aL;aS=aT.min}else{if(aR<=aS&&aR<aT.min){if(aS<aT.min){continue}aK=(aT.min-aS)/(aR-aS)*(aK-aL)+aL;aR=aT.min}}if(aS>=aR&&aS>aT.max){if(aR>aT.max){continue}aL=(aT.max-aS)/(aR-aS)*(aK-aL)+aL;aS=aT.max}else{if(aR>=aS&&aR>aT.max){if(aS>aT.max){continue}aK=(aT.max-aS)/(aR-aS)*(aK-aL)+aL;aR=aT.max}}if(aL<=aK&&aL<aU.min){if(aK<aU.min){continue}aS=(aU.min-aL)/(aK-aL)*(aR-aS)+aS;aL=aU.min}else{if(aK<=aL&&aK<aU.min){if(aL<aU.min){continue}aR=(aU.min-aL)/(aK-aL)*(aR-aS)+aS;aK=aU.min}}if(aL>=aK&&aL>aU.max){if(aK>aU.max){continue}aS=(aU.max-aL)/(aK-aL)*(aR-aS)+aS;aL=aU.max}else{if(aK>=aL&&aK>aU.max){if(aL>aU.max){continue}aR=(aU.max-aL)/(aK-aL)*(aR-aS)+aS;aK=aU.max}}if(aL!=aN||aS!=aM){H.moveTo(aU.p2c(aL)+aQ,aT.p2c(aS)+aI)}aN=aK;aM=aR;H.lineTo(aU.p2c(aK)+aQ,aT.p2c(aR)+aI)}H.stroke()}function aF(aI,aQ,aP){var aW=aI.points,aV=aI.pointsize,aN=Math.min(Math.max(0,aP.min),aP.max),aX=0,aU,aT=false,aM=1,aL=0,aR=0;while(true){if(aV>0&&aX>aW.length+aV){break}aX+=aV;var aZ=aW[aX-aV],aK=aW[aX-aV+aM],aY=aW[aX],aJ=aW[aX+aM];if(aT){if(aV>0&&aZ!=null&&aY==null){aR=aX;aV=-aV;aM=2;continue}if(aV<0&&aX==aL+aV){H.fill();aT=false;aV=-aV;aM=1;aX=aL=aR+aV;continue}}if(aZ==null||aY==null){continue}if(aZ<=aY&&aZ<aQ.min){if(aY<aQ.min){continue}aK=(aQ.min-aZ)/(aY-aZ)*(aJ-aK)+aK;aZ=aQ.min}else{if(aY<=aZ&&aY<aQ.min){if(aZ<aQ.min){continue}aJ=(aQ.min-aZ)/(aY-aZ)*(aJ-aK)+aK;aY=aQ.min}}if(aZ>=aY&&aZ>aQ.max){if(aY>aQ.max){continue}aK=(aQ.max-aZ)/(aY-aZ)*(aJ-aK)+aK;aZ=aQ.max}else{if(aY>=aZ&&aY>aQ.max){if(aZ>aQ.max){continue}aJ=(aQ.max-aZ)/(aY-aZ)*(aJ-aK)+aK;aY=aQ.max}}if(!aT){H.beginPath();H.moveTo(aQ.p2c(aZ),aP.p2c(aN));aT=true}if(aK>=aP.max&&aJ>=aP.max){H.lineTo(aQ.p2c(aZ),aP.p2c(aP.max));H.lineTo(aQ.p2c(aY),aP.p2c(aP.max));continue}else{if(aK<=aP.min&&aJ<=aP.min){H.lineTo(aQ.p2c(aZ),aP.p2c(aP.min));H.lineTo(aQ.p2c(aY),aP.p2c(aP.min));continue}}var aO=aZ,aS=aY;if(aK<=aJ&&aK<aP.min&&aJ>=aP.min){aZ=(aP.min-aK)/(aJ-aK)*(aY-aZ)+aZ;aK=aP.min}else{if(aJ<=aK&&aJ<aP.min&&aK>=aP.min){aY=(aP.min-aK)/(aJ-aK)*(aY-aZ)+aZ;aJ=aP.min}}if(aK>=aJ&&aK>aP.max&&aJ<=aP.max){aZ=(aP.max-aK)/(aJ-aK)*(aY-aZ)+aZ;aK=aP.max}else{if(aJ>=aK&&aJ>aP.max&&aK<=aP.max){aY=(aP.max-aK)/(aJ-aK)*(aY-aZ)+aZ;aJ=aP.max}}if(aZ!=aO){H.lineTo(aQ.p2c(aO),aP.p2c(aK))}H.lineTo(aQ.p2c(aZ),aP.p2c(aK));H.lineTo(aQ.p2c(aY),aP.p2c(aJ));if(aY!=aS){H.lineTo(aQ.p2c(aY),aP.p2c(aJ));H.lineTo(aQ.p2c(aS),aP.p2c(aJ))}}}H.save();H.translate(q.left,q.top);H.lineJoin="round";var aG=aE.lines.lineWidth,aB=aE.shadowSize;if(aG>0&&aB>0){H.lineWidth=aB;H.strokeStyle="rgba(0,0,0,0.1)";var aH=Math.PI/18;aD(aE.datapoints,Math.sin(aH)*(aG/2+aB/2),Math.cos(aH)*(aG/2+aB/2),aE.xaxis,aE.yaxis);H.lineWidth=aB/2;aD(aE.datapoints,Math.sin(aH)*(aG/2+aB/4),Math.cos(aH)*(aG/2+aB/4),aE.xaxis,aE.yaxis)}H.lineWidth=aG;H.strokeStyle=aE.color;var aC=ae(aE.lines,aE.color,0,w);if(aC){H.fillStyle=aC;aF(aE.datapoints,aE.xaxis,aE.yaxis)}if(aG>0){aD(aE.datapoints,0,0,aE.xaxis,aE.yaxis)}H.restore()}function ao(aE){function aH(aN,aM,aU,aK,aS,aT,aQ,aJ){var aR=aN.points,aI=aN.pointsize;for(var aL=0;aL<aR.length;aL+=aI){var aP=aR[aL],aO=aR[aL+1];if(aP==null||aP<aT.min||aP>aT.max||aO<aQ.min||aO>aQ.max){continue}H.beginPath();aP=aT.p2c(aP);aO=aQ.p2c(aO)+aK;if(aJ=="circle"){H.arc(aP,aO,aM,0,aS?Math.PI:Math.PI*2,false)}else{aJ(H,aP,aO,aM,aS)}H.closePath();if(aU){H.fillStyle=aU;H.fill()}H.stroke()}}H.save();H.translate(q.left,q.top);var aG=aE.points.lineWidth,aC=aE.shadowSize,aB=aE.points.radius,aF=aE.points.symbol;if(aG>0&&aC>0){var aD=aC/2;H.lineWidth=aD;H.strokeStyle="rgba(0,0,0,0.1)";aH(aE.datapoints,aB,null,aD+aD/2,true,aE.xaxis,aE.yaxis,aF);H.strokeStyle="rgba(0,0,0,0.2)";aH(aE.datapoints,aB,null,aD/2,true,aE.xaxis,aE.yaxis,aF)}H.lineWidth=aG;H.strokeStyle=aE.color;aH(aE.datapoints,aB,ae(aE.points,aE.color),0,false,aE.xaxis,aE.yaxis,aF);H.restore()}function E(aN,aM,aV,aI,aQ,aF,aD,aL,aK,aU,aR,aC){var aE,aT,aJ,aP,aG,aB,aO,aH,aS;if(aR){aH=aB=aO=true;aG=false;aE=aV;aT=aN;aP=aM+aI;aJ=aM+aQ;if(aT<aE){aS=aT;aT=aE;aE=aS;aG=true;aB=false}}else{aG=aB=aO=true;aH=false;aE=aN+aI;aT=aN+aQ;aJ=aV;aP=aM;if(aP<aJ){aS=aP;aP=aJ;aJ=aS;aH=true;aO=false}}if(aT<aL.min||aE>aL.max||aP<aK.min||aJ>aK.max){return}if(aE<aL.min){aE=aL.min;aG=false}if(aT>aL.max){aT=aL.max;aB=false}if(aJ<aK.min){aJ=aK.min;aH=false}if(aP>aK.max){aP=aK.max;aO=false}aE=aL.p2c(aE);aJ=aK.p2c(aJ);aT=aL.p2c(aT);aP=aK.p2c(aP);if(aD){aU.beginPath();aU.moveTo(aE,aJ);aU.lineTo(aE,aP);aU.lineTo(aT,aP);aU.lineTo(aT,aJ);aU.fillStyle=aD(aJ,aP);aU.fill()}if(aC>0&&(aG||aB||aO||aH)){aU.beginPath();aU.moveTo(aE,aJ+aF);if(aG){aU.lineTo(aE,aP+aF)}else{aU.moveTo(aE,aP+aF)}if(aO){aU.lineTo(aT,aP+aF)}else{aU.moveTo(aT,aP+aF)}if(aB){aU.lineTo(aT,aJ+aF)}else{aU.moveTo(aT,aJ+aF)}if(aH){aU.lineTo(aE,aJ+aF)}else{aU.moveTo(aE,aJ+aF)}aU.stroke()}}function e(aD){function aC(aJ,aI,aL,aG,aK,aN,aM){var aO=aJ.points,aF=aJ.pointsize;for(var aH=0;aH<aO.length;aH+=aF){if(aO[aH]==null){continue}E(aO[aH],aO[aH+1],aO[aH+2],aI,aL,aG,aK,aN,aM,H,aD.bars.horizontal,aD.bars.lineWidth)}}H.save();H.translate(q.left,q.top);H.lineWidth=aD.bars.lineWidth;H.strokeStyle=aD.color;var aB=aD.bars.align=="left"?0:-aD.bars.barWidth/2;var aE=aD.bars.fill?function(aF,aG){return ae(aD.bars,aD.color,aF,aG)}:null;aC(aD.datapoints,aB,aB+aD.bars.barWidth,0,aE,aD.xaxis,aD.yaxis);H.restore()}function ae(aD,aB,aC,aF){var aE=aD.fill;if(!aE){return null}if(aD.fillColor){return am(aD.fillColor,aC,aF,aB)}var aG=c.color.parse(aB);aG.a=typeof aE=="number"?aE:0.4;aG.normalize();return aG.toString()}function o(){av.find(".legend").remove();if(!O.legend.show){return}var aH=[],aF=false,aN=O.legend.labelFormatter,aM,aJ;for(var aE=0;aE<Q.length;++aE){aM=Q[aE];aJ=aM.label;if(!aJ){continue}if(aE%O.legend.noColumns==0){if(aF){aH.push("</tr>")}aH.push("<tr>");aF=true}if(aN){aJ=aN(aJ,aM)}aH.push('<td class="legendColorBox"><div style="border:1px solid '+O.legend.labelBoxBorderColor+';padding:1px"><div style="width:4px;height:0;border:5px solid '+aM.color+';overflow:hidden"></div></div></td><td class="legendLabel">'+aJ+"</td>")}if(aF){aH.push("</tr>")}if(aH.length==0){return}var aL='<table style="font-size:smaller;color:'+O.grid.color+'">'+aH.join("")+"</table>";if(O.legend.container!=null){c(O.legend.container).html(aL)}else{var aI="",aC=O.legend.position,aD=O.legend.margin;if(aD[0]==null){aD=[aD,aD]}if(aC.charAt(0)=="n"){aI+="top:"+(aD[1]+q.top)+"px;"}else{if(aC.charAt(0)=="s"){aI+="bottom:"+(aD[1]+q.bottom)+"px;"}}if(aC.charAt(1)=="e"){aI+="right:"+(aD[0]+q.right)+"px;"}else{if(aC.charAt(1)=="w"){aI+="left:"+(aD[0]+q.left)+"px;"}}var aK=c('<div class="legend">'+aL.replace('style="','style="position:absolute;'+aI+";")+"</div>").appendTo(av);if(O.legend.backgroundOpacity!=0){var aG=O.legend.backgroundColor;if(aG==null){aG=O.grid.backgroundColor;if(aG&&typeof aG=="string"){aG=c.color.parse(aG)}else{aG=c.color.extract(aK,"background-color")}aG.a=1;aG=aG.toString()}var aB=aK.children();c('<div style="position:absolute;width:'+aB.width()+"px;height:"+aB.height()+"px;"+aI+"background-color:"+aG+';"> </div>').prependTo(aK).css("opacity",O.legend.backgroundOpacity)}}}var ab=[],M=null;function K(aI,aG,aD){var aO=O.grid.mouseActiveRadius,a0=aO*aO+1,aY=null,aR=false,aW,aU;for(aW=Q.length-1;aW>=0;--aW){if(!aD(Q[aW])){continue}var aP=Q[aW],aH=aP.xaxis,aF=aP.yaxis,aV=aP.datapoints.points,aT=aP.datapoints.pointsize,aQ=aH.c2p(aI),aN=aF.c2p(aG),aC=aO/aH.scale,aB=aO/aF.scale;if(aH.options.inverseTransform){aC=Number.MAX_VALUE}if(aF.options.inverseTransform){aB=Number.MAX_VALUE}if(aP.lines.show||aP.points.show){for(aU=0;aU<aV.length;aU+=aT){var aK=aV[aU],aJ=aV[aU+1];if(aK==null){continue}if(aK-aQ>aC||aK-aQ<-aC||aJ-aN>aB||aJ-aN<-aB){continue}var aM=Math.abs(aH.p2c(aK)-aI),aL=Math.abs(aF.p2c(aJ)-aG),aS=aM*aM+aL*aL;if(aS<a0){a0=aS;aY=[aW,aU/aT]}}}if(aP.bars.show&&!aY){var aE=aP.bars.align=="left"?0:-aP.bars.barWidth/2,aX=aE+aP.bars.barWidth;for(aU=0;aU<aV.length;aU+=aT){var aK=aV[aU],aJ=aV[aU+1],aZ=aV[aU+2];if(aK==null){continue}if(Q[aW].bars.horizontal?(aQ<=Math.max(aZ,aK)&&aQ>=Math.min(aZ,aK)&&aN>=aJ+aE&&aN<=aJ+aX):(aQ>=aK+aE&&aQ<=aK+aX&&aN>=Math.min(aZ,aJ)&&aN<=Math.max(aZ,aJ))){aY=[aW,aU/aT]}}}}if(aY){aW=aY[0];aU=aY[1];aT=Q[aW].datapoints.pointsize;return{datapoint:Q[aW].datapoints.points.slice(aU*aT,(aU+1)*aT),dataIndex:aU,series:Q[aW],seriesIndex:aW}}return null}function aa(aB){if(O.grid.hoverable){u("plothover",aB,function(aC){return aC.hoverable!=false})}}function l(aB){if(O.grid.hoverable){u("plothover",aB,function(aC){return false})}}function R(aB){u("plotclick",aB,function(aC){return aC.clickable!=false})}function u(aC,aB,aD){var aE=y.offset(),aH=aB.pageX-aE.left-q.left,aF=aB.pageY-aE.top-q.top,aJ=C({left:aH,top:aF});aJ.pageX=aB.pageX;aJ.pageY=aB.pageY;var aK=K(aH,aF,aD);if(aK){aK.pageX=parseInt(aK.series.xaxis.p2c(aK.datapoint[0])+aE.left+q.left);aK.pageY=parseInt(aK.series.yaxis.p2c(aK.datapoint[1])+aE.top+q.top)}if(O.grid.autoHighlight){for(var aG=0;aG<ab.length;++aG){var aI=ab[aG];if(aI.auto==aC&&!(aK&&aI.series==aK.series&&aI.point[0]==aK.datapoint[0]&&aI.point[1]==aK.datapoint[1])){T(aI.series,aI.point)}}if(aK){x(aK.series,aK.datapoint,aC)}}av.trigger(aC,[aJ,aK])}function f(){if(!M){M=setTimeout(s,30)}}function s(){M=null;A.save();A.clearRect(0,0,G,I);A.translate(q.left,q.top);var aC,aB;for(aC=0;aC<ab.length;++aC){aB=ab[aC];if(aB.series.bars.show){v(aB.series,aB.point)}else{ay(aB.series,aB.point)}}A.restore();an(ak.drawOverlay,[A])}function x(aD,aB,aF){if(typeof aD=="number"){aD=Q[aD]}if(typeof aB=="number"){var aE=aD.datapoints.pointsize;aB=aD.datapoints.points.slice(aE*aB,aE*(aB+1))}var aC=al(aD,aB);if(aC==-1){ab.push({series:aD,point:aB,auto:aF});f()}else{if(!aF){ab[aC].auto=false}}}function T(aD,aB){if(aD==null&&aB==null){ab=[];f()}if(typeof aD=="number"){aD=Q[aD]}if(typeof aB=="number"){aB=aD.data[aB]}var aC=al(aD,aB);if(aC!=-1){ab.splice(aC,1);f()}}function al(aD,aE){for(var aB=0;aB<ab.length;++aB){var aC=ab[aB];if(aC.series==aD&&aC.point[0]==aE[0]&&aC.point[1]==aE[1]){return aB}}return -1}function ay(aE,aD){var aC=aD[0],aI=aD[1],aH=aE.xaxis,aG=aE.yaxis;if(aC<aH.min||aC>aH.max||aI<aG.min||aI>aG.max){return}var aF=aE.points.radius+aE.points.lineWidth/2;A.lineWidth=aF;A.strokeStyle=c.color.parse(aE.color).scale("a",0.5).toString();var aB=1.5*aF,aC=aH.p2c(aC),aI=aG.p2c(aI);A.beginPath();if(aE.points.symbol=="circle"){A.arc(aC,aI,aB,0,2*Math.PI,false)}else{aE.points.symbol(A,aC,aI,aB,false)}A.closePath();A.stroke()}function v(aE,aB){A.lineWidth=aE.bars.lineWidth;A.strokeStyle=c.color.parse(aE.color).scale("a",0.5).toString();var aD=c.color.parse(aE.color).scale("a",0.5).toString();var aC=aE.bars.align=="left"?0:-aE.bars.barWidth/2;E(aB[0],aB[1],aB[2]||0,aC,aC+aE.bars.barWidth,0,function(){return aD},aE.xaxis,aE.yaxis,A,aE.bars.horizontal,aE.bars.lineWidth)}function am(aJ,aB,aH,aC){if(typeof aJ=="string"){return aJ}else{var aI=H.createLinearGradient(0,aH,0,aB);for(var aE=0,aD=aJ.colors.length;aE<aD;++aE){var aF=aJ.colors[aE];if(typeof aF!="string"){var aG=c.color.parse(aC);if(aF.brightness!=null){aG=aG.scale("rgb",aF.brightness)}if(aF.opacity!=null){aG.a*=aF.opacity}aF=aG.toString()}aI.addColorStop(aE/(aD-1),aF)}return aI}}}c.plot=function(g,e,d){var f=new b(c(g),e,d,c.plot.plugins);return f};c.plot.version="0.7";c.plot.plugins=[];c.plot.formatDate=function(l,f,h){var o=function(d){d=""+d;return d.length==1?"0"+d:d};var e=[];var p=false,j=false;var n=l.getUTCHours();var k=n<12;if(h==null){h=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}if(f.search(/%p|%P/)!=-1){if(n>12){n=n-12}else{if(n==0){n=12}}}for(var g=0;g<f.length;++g){var m=f.charAt(g);if(p){switch(m){case"h":m=""+n;break;case"H":m=o(n);break;case"M":m=o(l.getUTCMinutes());break;case"S":m=o(l.getUTCSeconds());break;case"d":m=""+l.getUTCDate();break;case"m":m=""+(l.getUTCMonth()+1);break;case"y":m=""+l.getUTCFullYear();break;case"b":m=""+h[l.getUTCMonth()];break;case"p":m=(k)?("am"):("pm");break;case"P":m=(k)?("AM"):("PM");break;case"0":m="";j=true;break}if(m&&j){m=o(m);j=false}e.push(m);if(!j){p=false}}else{if(m=="%"){p=true}else{e.push(m)}}}return e.join("")};function a(e,d){return d*Math.floor(e/d)}})(jQuery);
\ No newline at end of file

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/jquery.flot.stack.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/jquery.flot.stack.js	2012-06-18 23:34:04 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/jquery.flot.stack.js	1970-01-01 00:00:00 +0000
@@ -1,184 +0,0 @@
-/*
-Flot plugin for stacking data sets, i.e. putting them on top of each
-other, for accumulative graphs.
-
-The plugin assumes the data is sorted on x (or y if stacking
-horizontally). For line charts, it is assumed that if a line has an
-undefined gap (from a null point), then the line above it should have
-the same gap - insert zeros instead of "null" if you want another
-behaviour. This also holds for the start and end of the chart. Note
-that stacking a mix of positive and negative values in most instances
-doesn't make sense (so it looks weird).
-
-Two or more series are stacked when their "stack" attribute is set to
-the same key (which can be any number or string or just "true"). To
-specify the default stack, you can set
-
-  series: {
-    stack: null or true or key (number/string)
-  }
-
-or specify it for a specific series
-
-  $.plot($("#placeholder"), [{ data: [ ... ], stack: true }])
-  
-The stacking order is determined by the order of the data series in
-the array (later series end up on top of the previous).
-
-Internally, the plugin modifies the datapoints in each series, adding
-an offset to the y value. For line series, extra data points are
-inserted through interpolation. If there's a second y value, it's also
-adjusted (e.g for bar charts or filled areas).
-*/
-
-(function ($) {
-    var options = {
-        series: { stack: null } // or number/string
-    };
-    
-    function init(plot) {
-        function findMatchingSeries(s, allseries) {
-            var res = null
-            for (var i = 0; i < allseries.length; ++i) {
-                if (s == allseries[i])
-                    break;
-                
-                if (allseries[i].stack == s.stack)
-                    res = allseries[i];
-            }
-            
-            return res;
-        }
-        
-        function stackData(plot, s, datapoints) {
-            if (s.stack == null)
-                return;
-
-            var other = findMatchingSeries(s, plot.getData());
-            if (!other)
-                return;
-
-            var ps = datapoints.pointsize,
-                points = datapoints.points,
-                otherps = other.datapoints.pointsize,
-                otherpoints = other.datapoints.points,
-                newpoints = [],
-                px, py, intery, qx, qy, bottom,
-                withlines = s.lines.show,
-                horizontal = s.bars.horizontal,
-                withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
-                withsteps = withlines && s.lines.steps,
-                fromgap = true,
-                keyOffset = horizontal ? 1 : 0,
-                accumulateOffset = horizontal ? 0 : 1,
-                i = 0, j = 0, l;
-
-            while (true) {
-                if (i >= points.length)
-                    break;
-
-                l = newpoints.length;
-
-                if (points[i] == null) {
-                    // copy gaps
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(points[i + m]);
-                    i += ps;
-                }
-                else if (j >= otherpoints.length) {
-                    // for lines, we can't use the rest of the points
-                    if (!withlines) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                    }
-                    i += ps;
-                }
-                else if (otherpoints[j] == null) {
-                    // oops, got a gap
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(null);
-                    fromgap = true;
-                    j += otherps;
-                }
-                else {
-                    // cases where we actually got two points
-                    px = points[i + keyOffset];
-                    py = points[i + accumulateOffset];
-                    qx = otherpoints[j + keyOffset];
-                    qy = otherpoints[j + accumulateOffset];
-                    bottom = 0;
-
-                    if (px == qx) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-
-                        newpoints[l + accumulateOffset] += qy;
-                        bottom = qy;
-                        
-                        i += ps;
-                        j += otherps;
-                    }
-                    else if (px > qx) {
-                        // we got past point below, might need to
-                        // insert interpolated extra point
-                        if (withlines && i > 0 && points[i - ps] != null) {
-                            intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
-                            newpoints.push(qx);
-                            newpoints.push(intery + qy);
-                            for (m = 2; m < ps; ++m)
-                                newpoints.push(points[i + m]);
-                            bottom = qy; 
-                        }
-
-                        j += otherps;
-                    }
-                    else { // px < qx
-                        if (fromgap && withlines) {
-                            // if we come from a gap, we just skip this point
-                            i += ps;
-                            continue;
-                        }
-                            
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                        
-                        // we might be able to interpolate a point below,
-                        // this can give us a better y
-                        if (withlines && j > 0 && otherpoints[j - otherps] != null)
-                            bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
-
-                        newpoints[l + accumulateOffset] += bottom;
-                        
-                        i += ps;
-                    }
-
-                    fromgap = false;
-                    
-                    if (l != newpoints.length && withbottom)
-                        newpoints[l + 2] += bottom;
-                }
-
-                // maintain the line steps invariant
-                if (withsteps && l != newpoints.length && l > 0
-                    && newpoints[l] != null
-                    && newpoints[l] != newpoints[l - ps]
-                    && newpoints[l + 1] != newpoints[l - ps + 1]) {
-                    for (m = 0; m < ps; ++m)
-                        newpoints[l + ps + m] = newpoints[l + m];
-                    newpoints[l + 1] = newpoints[l - ps + 1];
-                }
-            }
-
-            datapoints.points = newpoints;
-        }
-        
-        plot.hooks.processDatapoints.push(stackData);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'stack',
-        version: '1.2'
-    });
-})(jQuery);

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/shBrushJScript.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/shBrushJScript.js	2011-11-26 21:49:36 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/shBrushJScript.js	1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- * 
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
-	// CommonJS
-	typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
-	function Brush()
-	{
-		var keywords =	'break case catch continue ' +
-						'default delete do else false  ' +
-						'for function if in instanceof ' +
-						'new null return super switch ' +
-						'this throw true try typeof var while with'
-						;
-
-		var r = SyntaxHighlighter.regexLib;
-		
-		this.regexList = [
-			{ regex: r.multiLineDoubleQuotedString,					css: 'string' },			// double quoted strings
-			{ regex: r.multiLineSingleQuotedString,					css: 'string' },			// single quoted strings
-			{ regex: r.singleLineCComments,							css: 'comments' },			// one line comments
-			{ regex: r.multiLineCComments,							css: 'comments' },			// multiline comments
-			{ regex: /\s*#.*/gm,									css: 'preprocessor' },		// preprocessor tags like #region and #endregion
-			{ regex: new RegExp(this.getKeywords(keywords), 'gm'),	css: 'keyword' }			// keywords
-			];
-	
-		this.forHtmlScript(r.scriptScriptTags);
-	};
-
-	Brush.prototype	= new SyntaxHighlighter.Highlighter();
-	Brush.aliases	= ['js', 'jscript', 'javascript'];
-
-	SyntaxHighlighter.brushes.JScript = Brush;
-
-	// CommonJS
-	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();

=== removed file 'lava_scheduler_app/static/lava_scheduler_app/js/shCore.js'
--- lava_scheduler_app/static/lava_scheduler_app/js/shCore.js	2013-04-23 22:17:58 +0000
+++ lava_scheduler_app/static/lava_scheduler_app/js/shCore.js	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- * 
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('K M;I(M)1S 2U("2a\'t 4k M 4K 2g 3l 4G 4H");(6(){6 r(f,e){I(!M.1R(f))1S 3m("3s 15 4R");K a=f.1w;f=M(f.1m,t(f)+(e||""));I(a)f.1w={1m:a.1m,19:a.19?a.19.1a(0):N};H f}6 t(f){H(f.1J?"g":"")+(f.4s?"i":"")+(f.4p?"m":"")+(f.4v?"x":"")+(f.3n?"y":"")}6 B(f,e,a,b){K c=u.L,d,h,g;v=R;5K{O(;c--;){g=u[c];I(a&g.3r&&(!g.2p||g.2p.W(b))){g.2q.12=e;I((h=g.2q.X(f))&&h.P===e){d={3k:g.2b.W(b,h,a),1C:h};1N}}}}5v(i){1S i}5q{v=11}H d}6 p(f,e,a){I(3b.Z.1i)H f.1i(e,a);O(a=a||0;a<f.L;a++)I(f[a]===e)H a;H-1}M=6(f,e){K a=[],b=M.1B,c=0,d,h;I(M.1R(f)){I(e!==1d)1S 3m("2a\'t 5r 5I 5F 5B 5C 15 5E 5p");H r(f)}I(v)1S 2U("2a\'t W 3l M 59 5m 5g 5x 5i");e=e||"";O(d={2N:11,19:[],2K:6(g){H e.1i(g)>-1},3d:6(g){e+=g}};c<f.L;)I(h=B(f,c,b,d)){a.U(h.3k);c+=h.1C[0].L||1}Y I(h=n.X.W(z[b],f.1a(c))){a.U(h[0]);c+=h[0].L}Y{h=f.3a(c);I(h==="[")b=M.2I;Y I(h==="]")b=M.1B;a.U(h);c++}a=15(a.1K(""),n.Q.W(e,w,""));a.1w={1m:f,19:d.2N?d.19:N};H a};M.3v="1.5.0";M.2I=1;M.1B=2;K C=/\\$(?:(\\d\\d?|[$&`\'])|{([$\\w]+)})/g,w=/[^5h]+|([\\s\\S])(?=[\\s\\S]*\\1)/g,A=/^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,v=11,u=[],n={X:15.Z.X,1A:15.Z.1A,1C:1r.Z.1C,Q:1r.Z.Q,1e:1r.Z.1e},x=n.X.W(/()??/,"")[1]===1d,D=6(){K f=/^/g;n.1A.W(f,"");H!f.12}(),y=6(){K f=/x/g;n.Q.W("x",f,"");H!f.12}(),E=15.Z.3n!==1d,z={};z[M.2I]=/^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S]))/;z[M.1B]=/^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;M.1h=6(f,e,a,b){u.U({2q:r(f,"g"+(E?"y":"")),2b:e,3r:a||M.1B,2p:b||N})};M.2n=6(f,e){K a=f+"/"+(e||"");H M.2n[a]||(M.2n[a]=M(f,e))};M.3c=6(f){H r(f,"g")};M.5l=6(f){H f.Q(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g,"\\\\$&")};M.5e=6(f,e,a,b){e=r(e,"g"+(b&&E?"y":""));e.12=a=a||0;f=e.X(f);H b?f&&f.P===a?f:N:f};M.3q=6(){M.1h=6(){1S 2U("2a\'t 55 1h 54 3q")}};M.1R=6(f){H 53.Z.1q.W(f)==="[2m 15]"};M.3p=6(f,e,a,b){O(K c=r(e,"g"),d=-1,h;h=c.X(f);){a.W(b,h,++d,f,c);c.12===h.P&&c.12++}I(e.1J)e.12=0};M.57=6(f,e){H 6 a(b,c){K d=e[c].1I?e[c]:{1I:e[c]},h=r(d.1I,"g"),g=[],i;O(i=0;i<b.L;i++)M.3p(b[i],h,6(k){g.U(d.3j?k[d.3j]||"":k[0])});H c===e.L-1||!g.L?g:a(g,c+1)}([f],0)};15.Z.1p=6(f,e){H J.X(e[0])};15.Z.W=6(f,e){H J.X(e)};15.Z.X=6(f){K e=n.X.1p(J,14),a;I(e){I(!x&&e.L>1&&p(e,"")>-1){a=15(J.1m,n.Q.W(t(J),"g",""));n.Q.W(f.1a(e.P),a,6(){O(K c=1;c<14.L-2;c++)I(14[c]===1d)e[c]=1d})}I(J.1w&&J.1w.19)O(K b=1;b<e.L;b++)I(a=J.1w.19[b-1])e[a]=e[b];!D&&J.1J&&!e[0].L&&J.12>e.P&&J.12--}H e};I(!D)15.Z.1A=6(f){(f=n.X.W(J,f))&&J.1J&&!f[0].L&&J.12>f.P&&J.12--;H!!f};1r.Z.1C=6(f){M.1R(f)||(f=15(f));I(f.1J){K e=n.1C.1p(J,14);f.12=0;H e}H f.X(J)};1r.Z.Q=6(f,e){K a=M.1R(f),b,c;I(a&&1j e.58()==="3f"&&e.1i("${")===-1&&y)H n.Q.1p(J,14);I(a){I(f.1w)b=f.1w.19}Y f+="";I(1j e==="6")c=n.Q.W(J,f,6(){I(b){14[0]=1f 1r(14[0]);O(K d=0;d<b.L;d++)I(b[d])14[0][b[d]]=14[d+1]}I(a&&f.1J)f.12=14[14.L-2]+14[0].L;H e.1p(N,14)});Y{c=J+"";c=n.Q.W(c,f,6(){K d=14;H n.Q.W(e,C,6(h,g,i){I(g)5b(g){24"$":H"$";24"&":H d[0];24"`":H d[d.L-1].1a(0,d[d.L-2]);24"\'":H d[d.L-1].1a(d[d.L-2]+d[0].L);5a:i="";g=+g;I(!g)H h;O(;g>d.L-3;){i=1r.Z.1a.W(g,-1)+i;g=1Q.3i(g/10)}H(g?d[g]||"":"$")+i}Y{g=+i;I(g<=d.L-3)H d[g];g=b?p(b,i):-1;H g>-1?d[g+1]:h}})})}I(a&&f.1J)f.12=0;H c};1r.Z.1e=6(f,e){I(!M.1R(f))H n.1e.1p(J,14);K a=J+"",b=[],c=0,d,h;I(e===1d||+e<0)e=5D;Y{e=1Q.3i(+e);I(!e)H[]}O(f=M.3c(f);d=f.X(a);){I(f.12>c){b.U(a.1a(c,d.P));d.L>1&&d.P<a.L&&3b.Z.U.1p(b,d.1a(1));h=d[0].L;c=f.12;I(b.L>=e)1N}f.12===d.P&&f.12++}I(c===a.L){I(!n.1A.W(f,"")||h)b.U("")}Y b.U(a.1a(c));H b.L>e?b.1a(0,e):b};M.1h(/\\(\\?#[^)]*\\)/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"});M.1h(/\\((?!\\?)/,6(){J.19.U(N);H"("});M.1h(/\\(\\?<([$\\w]+)>/,6(f){J.19.U(f[1]);J.2N=R;H"("});M.1h(/\\\\k<([\\w$]+)>/,6(f){K e=p(J.19,f[1]);H e>-1?"\\\\"+(e+1)+(3R(f.2S.3a(f.P+f[0].L))?"":"(?:)"):f[0]});M.1h(/\\[\\^?]/,6(f){H f[0]==="[]"?"\\\\b\\\\B":"[\\\\s\\\\S]"});M.1h(/^\\(\\?([5A]+)\\)/,6(f){J.3d(f[1]);H""});M.1h(/(?:\\s+|#.*)+/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"},M.1B,6(){H J.2K("x")});M.1h(/\\./,6(){H"[\\\\s\\\\S]"},M.1B,6(){H J.2K("s")})})();1j 2e!="1d"&&(2e.M=M);K 1v=6(){6 r(a,b){a.1l.1i(b)!=-1||(a.1l+=" "+b)}6 t(a){H a.1i("3e")==0?a:"3e"+a}6 B(a){H e.1Y.2A[t(a)]}6 p(a,b,c){I(a==N)H N;K d=c!=R?a.3G:[a.2G],h={"#":"1c",".":"1l"}[b.1o(0,1)]||"3h",g,i;g=h!="3h"?b.1o(1):b.5u();I((a[h]||"").1i(g)!=-1)H a;O(a=0;d&&a<d.L&&i==N;a++)i=p(d[a],b,c);H i}6 C(a,b){K c={},d;O(d 2g a)c[d]=a[d];O(d 2g b)c[d]=b[d];H c}6 w(a,b,c,d){6 h(g){g=g||1P.5y;I(!g.1F){g.1F=g.52;g.3N=6(){J.5w=11}}c.W(d||1P,g)}a.3g?a.3g("4U"+b,h):a.4y(b,h,11)}6 A(a,b){K c=e.1Y.2j,d=N;I(c==N){c={};O(K h 2g e.1U){K g=e.1U[h];d=g.4x;I(d!=N){g.1V=h.4w();O(g=0;g<d.L;g++)c[d[g]]=h}}e.1Y.2j=c}d=e.1U[c[a]];d==N&&b!=11&&1P.1X(e.13.1x.1X+(e.13.1x.3E+a));H d}6 v(a,b){O(K c=a.1e("\\n"),d=0;d<c.L;d++)c[d]=b(c[d],d);H c.1K("\\n")}6 u(a,b){I(a==N||a.L==0||a=="\\n")H a;a=a.Q(/</g,"&1y;");a=a.Q(/ {2,}/g,6(c){O(K d="",h=0;h<c.L-1;h++)d+=e.13.1W;H d+" "});I(b!=N)a=v(a,6(c){I(c.L==0)H"";K d="";c=c.Q(/^(&2s;| )+/,6(h){d=h;H""});I(c.L==0)H d;H d+\'<17 1g="\'+b+\'">\'+c+"</17>"});H a}6 n(a,b){a.1e("\\n");O(K c="",d=0;d<50;d++)c+="                    ";H a=v(a,6(h){I(h.1i("\\t")==-1)H h;O(K g=0;(g=h.1i("\\t"))!=-1;)h=h.1o(0,g)+c.1o(0,b-g%b)+h.1o(g+1,h.L);H h})}6 x(a){H a.Q(/^\\s+|\\s+$/g,"")}6 D(a,b){I(a.P<b.P)H-1;Y I(a.P>b.P)H 1;Y I(a.L<b.L)H-1;Y I(a.L>b.L)H 1;H 0}6 y(a,b){6 c(k){H k[0]}O(K d=N,h=[],g=b.2D?b.2D:c;(d=b.1I.X(a))!=N;){K i=g(d,b);I(1j i=="3f")i=[1f e.2L(i,d.P,b.23)];h=h.1O(i)}H h}6 E(a){K b=/(.*)((&1G;|&1y;).*)/;H a.Q(e.3A.3M,6(c){K d="",h=N;I(h=b.X(c)){c=h[1];d=h[2]}H\'<a 2h="\'+c+\'">\'+c+"</a>"+d})}6 z(){O(K a=1E.36("1k"),b=[],c=0;c<a.L;c++)a[c].3s=="20"&&b.U(a[c]);H b}6 f(a){a=a.1F;K b=p(a,".20",R);a=p(a,".3O",R);K c=1E.4i("3t");I(!(!a||!b||p(a,"3t"))){B(b.1c);r(b,"1m");O(K d=a.3G,h=[],g=0;g<d.L;g++)h.U(d[g].4z||d[g].4A);h=h.1K("\\r");c.39(1E.4D(h));a.39(c);c.2C();c.4C();w(c,"4u",6(){c.2G.4E(c);b.1l=b.1l.Q("1m","")})}}I(1j 3F!="1d"&&1j M=="1d")M=3F("M").M;K e={2v:{"1g-27":"","2i-1s":1,"2z-1s-2t":11,1M:N,1t:N,"42-45":R,"43-22":4,1u:R,16:R,"3V-17":R,2l:11,"41-40":R,2k:11,"1z-1k":11},13:{1W:"&2s;",2M:R,46:11,44:11,34:"4n",1x:{21:"4o 1m",2P:"?",1X:"1v\\n\\n",3E:"4r\'t 4t 1D O: ",4g:"4m 4B\'t 51 O 1z-1k 4F: ",37:\'<!4T 1z 4S "-//4V//3H 4W 1.0 4Z//4Y" "1Z://2y.3L.3K/4X/3I/3H/3I-4P.4J"><1z 4I="1Z://2y.3L.3K/4L/5L"><3J><4N 1Z-4M="5G-5M" 6K="2O/1z; 6J=6I-8" /><1t>6L 1v</1t></3J><3B 1L="25-6M:6Q,6P,6O,6N-6F;6y-2f:#6x;2f:#6w;25-22:6v;2O-3D:3C;"><T 1L="2O-3D:3C;3w-32:1.6z;"><T 1L="25-22:6A-6E;">1v</T><T 1L="25-22:.6C;3w-6B:6R;"><T>3v 3.0.76 (72 73 3x)</T><T><a 2h="1Z://3u.2w/1v" 1F="38" 1L="2f:#3y">1Z://3u.2w/1v</a></T><T>70 17 6U 71.</T><T>6T 6X-3x 6Y 6D.</T></T><T>6t 61 60 J 1k, 5Z <a 2h="6u://2y.62.2w/63-66/65?64=5X-5W&5P=5O" 1L="2f:#3y">5R</a> 5V <2R/>5U 5T 5S!</T></T></3B></1z>\'}},1Y:{2j:N,2A:{}},1U:{},3A:{6n:/\\/\\*[\\s\\S]*?\\*\\//2c,6m:/\\/\\/.*$/2c,6l:/#.*$/2c,6k:/"([^\\\\"\\n]|\\\\.)*"/g,6o:/\'([^\\\\\'\\n]|\\\\.)*\'/g,6p:1f M(\'"([^\\\\\\\\"]|\\\\\\\\.)*"\',"3z"),6s:1f M("\'([^\\\\\\\\\']|\\\\\\\\.)*\'","3z"),6q:/(&1y;|<)!--[\\s\\S]*?--(&1G;|>)/2c,3M:/\\w+:\\/\\/[\\w-.\\/?%&=+:@;]*/g,6a:{18:/(&1y;|<)\\?=?/g,1b:/\\?(&1G;|>)/g},69:{18:/(&1y;|<)%=?/g,1b:/%(&1G;|>)/g},6d:{18:/(&1y;|<)\\s*1k.*?(&1G;|>)/2T,1b:/(&1y;|<)\\/\\s*1k\\s*(&1G;|>)/2T}},16:{1H:6(a){6 b(i,k){H e.16.2o(i,k,e.13.1x[k])}O(K c=\'<T 1g="16">\',d=e.16.2x,h=d.2X,g=0;g<h.L;g++)c+=(d[h[g]].1H||b)(a,h[g]);c+="</T>";H c},2o:6(a,b,c){H\'<2W><a 2h="#" 1g="6e 6h\'+b+" "+b+\'">\'+c+"</a></2W>"},2b:6(a){K b=a.1F,c=b.1l||"";b=B(p(b,".20",R).1c);K d=6(h){H(h=15(h+"6f(\\\\w+)").X(c))?h[1]:N}("6g");b&&d&&e.16.2x[d].2B(b);a.3N()},2x:{2X:["21","2P"],21:{1H:6(a){I(a.V("2l")!=R)H"";K b=a.V("1t");H e.16.2o(a,"21",b?b:e.13.1x.21)},2B:6(a){a=1E.6j(t(a.1c));a.1l=a.1l.Q("47","")}},2P:{2B:6(){K a="68=0";a+=", 18="+(31.30-33)/2+", 32="+(31.2Z-2Y)/2+", 30=33, 2Z=2Y";a=a.Q(/^,/,"");a=1P.6Z("","38",a);a.2C();K b=a.1E;b.6W(e.13.1x.37);b.6V();a.2C()}}}},35:6(a,b){K c;I(b)c=[b];Y{c=1E.36(e.13.34);O(K d=[],h=0;h<c.L;h++)d.U(c[h]);c=d}c=c;d=[];I(e.13.2M)c=c.1O(z());I(c.L===0)H d;O(h=0;h<c.L;h++){O(K g=c[h],i=a,k=c[h].1l,j=3W 0,l={},m=1f M("^\\\\[(?<2V>(.*?))\\\\]$"),s=1f M("(?<27>[\\\\w-]+)\\\\s*:\\\\s*(?<1T>[\\\\w-%#]+|\\\\[.*?\\\\]|\\".*?\\"|\'.*?\')\\\\s*;?","g");(j=s.X(k))!=N;){K o=j.1T.Q(/^[\'"]|[\'"]$/g,"");I(o!=N&&m.1A(o)){o=m.X(o);o=o.2V.L>0?o.2V.1e(/\\s*,\\s*/):[]}l[j.27]=o}g={1F:g,1n:C(i,l)};g.1n.1D!=N&&d.U(g)}H d},1M:6(a,b){K c=J.35(a,b),d=N,h=e.13;I(c.L!==0)O(K g=0;g<c.L;g++){b=c[g];K i=b.1F,k=b.1n,j=k.1D,l;I(j!=N){I(k["1z-1k"]=="R"||e.2v["1z-1k"]==R){d=1f e.4l(j);j="4O"}Y I(d=A(j))d=1f d;Y 6H;l=i.3X;I(h.2M){l=l;K m=x(l),s=11;I(m.1i("<![6G[")==0){m=m.4h(9);s=R}K o=m.L;I(m.1i("]]\\>")==o-3){m=m.4h(0,o-3);s=R}l=s?m:l}I((i.1t||"")!="")k.1t=i.1t;k.1D=j;d.2Q(k);b=d.2F(l);I((i.1c||"")!="")b.1c=i.1c;i.2G.74(b,i)}}},2E:6(a){w(1P,"4k",6(){e.1M(a)})}};e.2E=e.2E;e.1M=e.1M;e.2L=6(a,b,c){J.1T=a;J.P=b;J.L=a.L;J.23=c;J.1V=N};e.2L.Z.1q=6(){H J.1T};e.4l=6(a){6 b(j,l){O(K m=0;m<j.L;m++)j[m].P+=l}K c=A(a),d,h=1f e.1U.5Y,g=J,i="2F 1H 2Q".1e(" ");I(c!=N){d=1f c;O(K k=0;k<i.L;k++)(6(){K j=i[k];g[j]=6(){H h[j].1p(h,14)}})();d.28==N?1P.1X(e.13.1x.1X+(e.13.1x.4g+a)):h.2J.U({1I:d.28.17,2D:6(j){O(K l=j.17,m=[],s=d.2J,o=j.P+j.18.L,F=d.28,q,G=0;G<s.L;G++){q=y(l,s[G]);b(q,o);m=m.1O(q)}I(F.18!=N&&j.18!=N){q=y(j.18,F.18);b(q,j.P);m=m.1O(q)}I(F.1b!=N&&j.1b!=N){q=y(j.1b,F.1b);b(q,j.P+j[0].5Q(j.1b));m=m.1O(q)}O(j=0;j<m.L;j++)m[j].1V=c.1V;H m}})}};e.4j=6(){};e.4j.Z={V:6(a,b){K c=J.1n[a];c=c==N?b:c;K d={"R":R,"11":11}[c];H d==N?c:d},3Y:6(a){H 1E.4i(a)},4c:6(a,b){K c=[];I(a!=N)O(K d=0;d<a.L;d++)I(1j a[d]=="2m")c=c.1O(y(b,a[d]));H J.4e(c.6b(D))},4e:6(a){O(K b=0;b<a.L;b++)I(a[b]!==N)O(K c=a[b],d=c.P+c.L,h=b+1;h<a.L&&a[b]!==N;h++){K g=a[h];I(g!==N)I(g.P>d)1N;Y I(g.P==c.P&&g.L>c.L)a[b]=N;Y I(g.P>=c.P&&g.P<d)a[h]=N}H a},4d:6(a){K b=[],c=2u(J.V("2i-1s"));v(a,6(d,h){b.U(h+c)});H b},3U:6(a){K b=J.V("1M",[]);I(1j b!="2m"&&b.U==N)b=[b];a:{a=a.1q();K c=3W 0;O(c=c=1Q.6c(c||0,0);c<b.L;c++)I(b[c]==a){b=c;1N a}b=-1}H b!=-1},2r:6(a,b,c){a=["1s","6i"+b,"P"+a,"6r"+(b%2==0?1:2).1q()];J.3U(b)&&a.U("67");b==0&&a.U("1N");H\'<T 1g="\'+a.1K(" ")+\'">\'+c+"</T>"},3Q:6(a,b){K c="",d=a.1e("\\n").L,h=2u(J.V("2i-1s")),g=J.V("2z-1s-2t");I(g==R)g=(h+d-1).1q().L;Y I(3R(g)==R)g=0;O(K i=0;i<d;i++){K k=b?b[i]:h+i,j;I(k==0)j=e.13.1W;Y{j=g;O(K l=k.1q();l.L<j;)l="0"+l;j=l}a=j;c+=J.2r(i,k,a)}H c},49:6(a,b){a=x(a);K c=a.1e("\\n");J.V("2z-1s-2t");K d=2u(J.V("2i-1s"));a="";O(K h=J.V("1D"),g=0;g<c.L;g++){K i=c[g],k=/^(&2s;|\\s)+/.X(i),j=N,l=b?b[g]:d+g;I(k!=N){j=k[0].1q();i=i.1o(j.L);j=j.Q(" ",e.13.1W)}i=x(i);I(i.L==0)i=e.13.1W;a+=J.2r(g,l,(j!=N?\'<17 1g="\'+h+\' 5N">\'+j+"</17>":"")+i)}H a},4f:6(a){H a?"<4a>"+a+"</4a>":""},4b:6(a,b){6 c(l){H(l=l?l.1V||g:g)?l+" ":""}O(K d=0,h="",g=J.V("1D",""),i=0;i<b.L;i++){K k=b[i],j;I(!(k===N||k.L===0)){j=c(k);h+=u(a.1o(d,k.P-d),j+"48")+u(k.1T,j+k.23);d=k.P+k.L+(k.75||0)}}h+=u(a.1o(d),c()+"48");H h},1H:6(a){K b="",c=["20"],d;I(J.V("2k")==R)J.1n.16=J.1n.1u=11;1l="20";J.V("2l")==R&&c.U("47");I((1u=J.V("1u"))==11)c.U("6S");c.U(J.V("1g-27"));c.U(J.V("1D"));a=a.Q(/^[ ]*[\\n]+|[\\n]*[ ]*$/g,"").Q(/\\r/g," ");b=J.V("43-22");I(J.V("42-45")==R)a=n(a,b);Y{O(K h="",g=0;g<b;g++)h+=" ";a=a.Q(/\\t/g,h)}a=a;a:{b=a=a;h=/<2R\\s*\\/?>|&1y;2R\\s*\\/?&1G;/2T;I(e.13.46==R)b=b.Q(h,"\\n");I(e.13.44==R)b=b.Q(h,"");b=b.1e("\\n");h=/^\\s*/;g=4Q;O(K i=0;i<b.L&&g>0;i++){K k=b[i];I(x(k).L!=0){k=h.X(k);I(k==N){a=a;1N a}g=1Q.4q(k[0].L,g)}}I(g>0)O(i=0;i<b.L;i++)b[i]=b[i].1o(g);a=b.1K("\\n")}I(1u)d=J.4d(a);b=J.4c(J.2J,a);b=J.4b(a,b);b=J.49(b,d);I(J.V("41-40"))b=E(b);1j 2H!="1d"&&2H.3S&&2H.3S.1C(/5s/)&&c.U("5t");H b=\'<T 1c="\'+t(J.1c)+\'" 1g="\'+c.1K(" ")+\'">\'+(J.V("16")?e.16.1H(J):"")+\'<3Z 5z="0" 5H="0" 5J="0">\'+J.4f(J.V("1t"))+"<3T><3P>"+(1u?\'<2d 1g="1u">\'+J.3Q(a)+"</2d>":"")+\'<2d 1g="17"><T 1g="3O">\'+b+"</T></2d></3P></3T></3Z></T>"},2F:6(a){I(a===N)a="";J.17=a;K b=J.3Y("T");b.3X=J.1H(a);J.V("16")&&w(p(b,".16"),"5c",e.16.2b);J.V("3V-17")&&w(p(b,".17"),"56",f);H b},2Q:6(a){J.1c=""+1Q.5d(1Q.5n()*5k).1q();e.1Y.2A[t(J.1c)]=J;J.1n=C(e.2v,a||{});I(J.V("2k")==R)J.1n.16=J.1n.1u=11},5j:6(a){a=a.Q(/^\\s+|\\s+$/g,"").Q(/\\s+/g,"|");H"\\\\b(?:"+a+")\\\\b"},5f:6(a){J.28={18:{1I:a.18,23:"1k"},1b:{1I:a.1b,23:"1k"},17:1f M("(?<18>"+a.18.1m+")(?<17>.*?)(?<1b>"+a.1b.1m+")","5o")}}};H e}();1j 2e!="1d"&&(2e.1v=1v);',62,441,'||||||function|||||||||||||||||||||||||||||||||||||return|if|this|var|length|XRegExp|null|for|index|replace|true||div|push|getParam|call|exec|else|prototype||false|lastIndex|config|arguments|RegExp|toolbar|code|left|captureNames|slice|right|id|undefined|split|new|class|addToken|indexOf|typeof|script|className|source|params|substr|apply|toString|String|line|title|gutter|SyntaxHighlighter|_xregexp|strings|lt|html|test|OUTSIDE_CLASS|match|brush|document|target|gt|getHtml|regex|global|join|style|highlight|break|concat|window|Math|isRegExp|throw|value|brushes|brushName|space|alert|vars|http|syntaxhighlighter|expandSource|size|css|case|font|Fa|name|htmlScript|dA|can|handler|gm|td|exports|color|in|href|first|discoveredBrushes|light|collapse|object|cache|getButtonHtml|trigger|pattern|getLineHtml|nbsp|numbers|parseInt|defaults|com|items|www|pad|highlighters|execute|focus|func|all|getDiv|parentNode|navigator|INSIDE_CLASS|regexList|hasFlag|Match|useScriptTags|hasNamedCapture|text|help|init|br|input|gi|Error|values|span|list|250|height|width|screen|top|500|tagName|findElements|getElementsByTagName|aboutDialog|_blank|appendChild|charAt|Array|copyAsGlobal|setFlag|highlighter_|string|attachEvent|nodeName|floor|backref|output|the|TypeError|sticky|Za|iterate|freezeTokens|scope|type|textarea|alexgorbatchev|version|margin|2010|005896|gs|regexLib|body|center|align|noBrush|require|childNodes|DTD|xhtml1|head|org|w3|url|preventDefault|container|tr|getLineNumbersHtml|isNaN|userAgent|tbody|isLineHighlighted|quick|void|innerHTML|create|table|links|auto|smart|tab|stripBrs|tabs|bloggerMode|collapsed|plain|getCodeLinesHtml|caption|getMatchesHtml|findMatches|figureOutLineNumbers|removeNestedMatches|getTitleHtml|brushNotHtmlScript|substring|createElement|Highlighter|load|HtmlScript|Brush|pre|expand|multiline|min|Can|ignoreCase|find|blur|extended|toLowerCase|aliases|addEventListener|innerText|textContent|wasn|select|createTextNode|removeChild|option|same|frame|xmlns|dtd|twice|1999|equiv|meta|htmlscript|transitional|1E3|expected|PUBLIC|DOCTYPE|on|W3C|XHTML|TR|EN|Transitional||configured|srcElement|Object|after|run|dblclick|matchChain|valueOf|constructor|default|switch|click|round|execAt|forHtmlScript|token|gimy|functions|getKeywords|1E6|escape|within|random|sgi|another|finally|supply|MSIE|ie|toUpperCase|catch|returnValue|definition|event|border|imsx|constructing|one|Infinity|from|when|Content|cellpadding|flags|cellspacing|try|xhtml|Type|spaces|2930402|hosted_button_id|lastIndexOf|donate|active|development|keep|to|xclick|_s|Xml|please|like|you|paypal|cgi|cmd|webscr|bin|highlighted|scrollbars|aspScriptTags|phpScriptTags|sort|max|scriptScriptTags|toolbar_item|_|command|command_|number|getElementById|doubleQuotedString|singleLinePerlComments|singleLineCComments|multiLineCComments|singleQuotedString|multiLineDoubleQuotedString|xmlComments|alt|multiLineSingleQuotedString|If|https|1em|000|fff|background|5em|xx|bottom|75em|Gorbatchev|large|serif|CDATA|continue|utf|charset|content|About|family|sans|Helvetica|Arial|Geneva|3em|nogutter|Copyright|syntax|close|write|2004|Alex|open|JavaScript|highlighter|July|02|replaceChild|offset|83'.split('|'),0,{}))

=== removed directory 'lava_scheduler_app/templates'
=== removed directory 'lava_scheduler_app/templates/lava_scheduler_app'
=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/_content.html'
--- lava_scheduler_app/templates/lava_scheduler_app/_content.html	2012-06-18 23:34:04 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/_content.html	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-{% extends "layouts/content.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava-server/css/demo_table_jui.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/FixedHeader.min.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}lava-server/js/jquery.dataTables.min.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/jquery.flot.min.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/jquery.flot.stack.js"></script>
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/_device_base.html'
--- lava_scheduler_app/templates/lava_scheduler_app/_device_base.html	2012-10-20 19:58:32 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/_device_base.html	1970-01-01 00:00:00 +0000
@@ -1,153 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-<style type="text/css">
-.column {
-    position: relative;
-    float: left;
-    padding-right: 2em;
-    padding-bottom: 1em;
-}
-</style>
-<style>
-  details, summary { display: block; padding: 0.2em; }
-  summary { cursor: pointer; }
-  summary:hover, summary:focus { background: #ddd; }
-  .no-details details > * { display: none; }
-  .no-details details.open > * { display: block; }
-  .no-details details summary:before { float: left; width: 20px; content: '► '; }
-  .no-details details.open summary:before { content: '▼ '; }
-  .no-details details summary { display: block; }
-</style>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/jquery.details.min.js"></script> 
-{% endblock %}
-
-
-{% block content %}
-{% block device_heading %}{% endblock %}
-
-{% if show_maintenance %}
-<form style="display:inline; float:right" method="POST"
-      action="{% url lava.scheduler.device.maintenance device.pk %}">
-  {% csrf_token %}
-  <button id="maintenance-button">Put into maintenance mode</button>
-</form>
-<form method="POST"
-      action="{% url lava.scheduler.device.maintenance device.pk %}"
-      id="maintenance-dialog" style="display: none">
-  {% csrf_token %}
-  <input name="reason" style="width: 100%"/>
-</form>
-{% endif %}
-{% if show_online %}
-<form style="display:inline; float:right" method="POST"
-      action="{% url lava.scheduler.device.online device.pk %}">
-  {% csrf_token %}
-  <button id="online-button">Put online</button>
-</form>
-<form method="POST"
-      action="{% url lava.scheduler.device.online device.pk %}"
-      id="online-dialog" style="display: none">
-  {% csrf_token %}
-  <input name="reason" style="width: 100%"/>
-</form>
-<form style="display:inline " method="POST"
-      action="{% url lava.scheduler.device.looping device.pk %}">
-  {% csrf_token %}
-  <button id="looping-button">Put into looping mode</button>
-</form>
-{% endif %}
-
-<div id="columns">
-  <div class="column">
-    <dt>Hostname:</dt>
-    <dd>{{ device.hostname }}</dd>
-
-    <dt>Device type:</dt>
-    <dd>{{ device.device_type }}</dd>
-
-    <dt>Device version:</dt>
-    <dd>{{ device.device_version|default:"Unknown" }}</dd>
-
-    <dt>Device Tags</dt>
-    {% for tag in device.tags.all %}
-    <dd>{{ tag.name }}</dd>
-    {% empty %}
-    <dd><i>None</i></dd>
-    {% endfor %}
-  </div>
-  <div class="column">
-    <dt>Status:</dt>
-    <dd>
-      {{ device.get_status_display }}
-      {% if transition %}
-      (reason: <i>{{ transition }}</i>)
-      {% endif %}
-    </dd>
-    <dt>Health Status:</dt>
-    <dd>
-      {{ device.get_health_status_display }}
-    </dd>
-    {% if device.current_job %}
-    <dt>Currently running:</dt>
-    <dd><a href="{{ device.current_job.get_absolute_url }}"
-      >Job {{ device.current_job }}</a></dd>
-    {% endif %}
-  </div>
-  <div style="clear: both"></div>
-</div>
-
-{% block content_columns %}
-{% endblock %}
-
-<details>
-  <summary>See status transitions</summary>
-  {% render_table transition_table %}
-</details>
-
-<script>
-$(document).ready(
-  function() {
-    $('html').addClass($.fn.details.support ? 'details' : 'no-details');
-    $('details').details();
-    $('script').css('visibility', 'hidden');
-{% if show_maintenance %}
-    $("#maintenance-button").button();
-    $("#maintenance-button").click(function (e) {
-        e.preventDefault();
-        $("#maintenance-dialog").dialog('open');
-    });
-    $("#maintenance-dialog").dialog(
-        {
-            autoOpen: false,
-            buttons: {'OK': function () {$("#maintenance-dialog").submit()}},
-            modal: true,
-            title: "Reason for offlining"
-        }
-    );
-
-{% endif %}
-{% if show_online %}
-    $("#online-button").button();
-    $("#online-button").click(function (e) {
-        e.preventDefault();
-        $("#online-dialog").dialog('open');
-    });
-    $("#online-dialog").dialog(
-        {
-            autoOpen: false,
-            buttons: {'OK': function () {$("#online-dialog").submit()}},
-            modal: true,
-            title: "Reason for onlining"
-        }
-    );
-{% endif %}
-  }
-);
-</script>
-
-{% endblock %}
-

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/alldevices.html'
--- lava_scheduler_app/templates/lava_scheduler_app/alldevices.html	2012-05-28 09:40:20 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/alldevices.html	1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block content %}
-
-<h2>All Devices</h2>
-
-{% render_table devices_table %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/alljobs.html'
--- lava_scheduler_app/templates/lava_scheduler_app/alljobs.html	2012-03-05 00:23:16 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/alljobs.html	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block content %}
-<h2>All Jobs</h2>
-
-{% render_table alljobs_table %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/device.html'
--- lava_scheduler_app/templates/lava_scheduler_app/device.html	2012-03-12 10:00:23 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/device.html	1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
-{% extends "lava_scheduler_app/_device_base.html" %}
-
-{% load django_tables2 %}
-
-{% block device_heading %}
-<h2>Device {{ device }}</h2>
-{% endblock %}
-
-{% block content_columns %}
-{% render_table recent_job_table %}
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/device_type.html'
--- lava_scheduler_app/templates/lava_scheduler_app/device_type.html	2012-05-24 09:12:26 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/device_type.html	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block content %}
-<h2>{{device_type}} Status</h2>
-
-{{running_jobs_num}} jobs running / {{queued_jobs_num}} jobs queued
-
-<h3>Health Job Summary</h3>
-{% render_table health_job_summary_table %}
-
-<h3>Devices Overview</h3>
-{% render_table devices_table_no_dt %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/failure_report.html'
--- lava_scheduler_app/templates/lava_scheduler_app/failure_report.html	2013-01-03 16:12:15 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/failure_report.html	1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block content %}
-<h2>Failure Report</h2>
-{% render_table failed_job_table %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/health_jobs.html'
--- lava_scheduler_app/templates/lava_scheduler_app/health_jobs.html	2012-03-09 02:49:54 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/health_jobs.html	1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
-{% extends "lava_scheduler_app/_device_base.html" %}
-
-{% load django_tables2 %}
-
-{% block device_heading %}
-<h2>Device {{ device }} Health Job List</h2>
-{% endblock %}
-
-{% block content_columns %}
-{% render_table health_job_table %}
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/index.html'
--- lava_scheduler_app/templates/lava_scheduler_app/index.html	2012-05-28 09:40:20 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/index.html	1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block content %}
-
-<h2>Device Type Overview</h2>
-<p>{{device_status}} devices online</p>
-<p>{{health_check_status}} health check jobs passed in 24 hours</p>
-
-{% render_table device_type_table %}
-
-<p><a href="{% url lava.scheduler.alldevices %}">All Devices</a></p>
-
-<p><a href="{% url lava.scheduler.labhealth %}">All Devices Health</a></p>
-
-<h2>Active Jobs</h2>
-
-{% render_table active_jobs_table %}
-
-<a href="{% url lava.scheduler.job.list %}">All jobs</a>
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job.html'
--- lava_scheduler_app/templates/lava_scheduler_app/job.html	2012-03-15 09:27:48 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job.html	1970-01-01 00:00:00 +0000
@@ -1,113 +0,0 @@
-{% extends "lava_scheduler_app/job_sidebar.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/jQuery.Rule.js"></script>
-{% endblock %}
-
-
-{% block content %}
-<h2>Dispatcher Log Summary</h2>
-{% if job.status < job.RUNNING %}
-No log file yet.
-{% else %}
-{% if job_file_present %}
-{% if job_has_error %}
-<div id="dispatcher-error">
-<h3>Dispatcher error or test failure</h3>
-<pre>{{ job_errors }}</pre>
-</div>
-{% endif %}
-<h3>Dispatcher Log messages (file size = {{ job_file_size|filesizeformat }}) &nbsp;  &nbsp; 
-    <a href="{% url lava.scheduler.job.log_file.plain job.pk %}">Download as text file</a>
-</h3>
-<span class="logbuttons">
-{% for level in levels %}
-{% if level.1 %}
-  <input type="checkbox" checked="checked" id="{{ level.0 }}"/><label for="{{ level.0 }}">{{ level.0 }}</label>
-{% else %}
-  <input type="checkbox" checked="checked" id="{{ level.0 }}" disabled="disabled"/><label for="{{ level.0 }}">{{ level.0 }}</label>
-{% endif %}
-{% endfor %}
-</span>
-<div id="log-messages">
-{% for log in job_log_messages %}
-<pre class="log {{log.0}} {{log.2}}">{{ log.1 }}</pre>
-{% endfor %}
-{% if job.status == job.RUNNING %}
-<img src="{{ STATIC_URL }}lava_scheduler_app/images/ajax-progress.gif"/>
-{% endif %}
-</div>
-{% else %}
-<p>
-Job file missing.
-</p>
-{% endif %}
-{% endif %}
-
-</p><script type="text/javascript">
-$('.logbuttons input').button()
-function showHideLogClick () {
-  var rule = rules[$(this).attr('id')];
-  if ($(this).is(':checked')) {
-    rule.css('display', 'block');
-  } else {
-    rule.css('display', 'none');
-  }
-}
-$('.logbuttons input').click(showHideLogClick)
-var rules = {
-{% for level in levels %}
- {{ level.0 }}: $.rule('pre.{{ level.0 }} {}').appendTo('style'),
-{% endfor %}
-'': undefined
-}
-
-{% if job.status == job.RUNNING and job_file_present %}
-var pollTimer = null, logLenth = '{{ job_file_size }}';
-
-function poll (start) {
-  $.ajax({
-    url: '{% url lava_scheduler_app.views.job_log_incremental pk=job.pk %}?start=' + logLenth,
-    dataType: 'json',
-    global: false,
-    success: function (data, success, xhr) {
-      var progressNode = $('#log-messages img');
-      for (var i = 0; i < data.length; i++) {
-          var d = data[i];
-          var node = $('<pre class="log"></pre>');
-          node.addClass(d[0]);
-          node.text(d[1]);
-          node.insertBefore(progressNode);
-          var toggleButton = $("#" + d[0]);
-          if (toggleButton.length) {
-                          console.log('a');
-              $("#" + d[0]).button('option', 'disabled', false);
-          } else {
-                          console.log('b');
-              var button = $('<input type="checkbox" checked="checked"/>').attr('id', d[0]);
-              var label = $('<label></label>').attr('for', d[0]).text(d[0]);
-              $('.logbuttons').append(button, label);
-              rules[d[0]] = $.rule('pre.'+d[0]+' {}').appendTo('style'),
-              button.button();
-              button.click(showHideLogClick);
-          }
-      }
-      logLenth = xhr.getResponseHeader('X-Current-Size');
-      if (xhr.getResponseHeader('X-Is-Finished')) {
-        $('#log-messages img').css('display', 'none');
-      } else {
-        pollTimer = setTimeout(poll, 1000);
-      }
-    }
-  });
-}
-$(document).ready(
-function () {
-pollTimer = setTimeout(poll, 1000);
-}
-);
-{% endif %}
-</script>
-{% endblock %}
-

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job_annotate_failure.html'
--- lava_scheduler_app/templates/lava_scheduler_app/job_annotate_failure.html	2013-01-03 16:12:15 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job_annotate_failure.html	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-{% extends "lava_scheduler_app/job_sidebar.html" %}
-
-{% block content %}
-<h2>Annotate Job Failure - {{ job.id }} </h2>
-
-{% if form.errors %}
-<h3>Errors found in submission</h3>
-{{ form.errors }}
-{% endif %}
-
-<form action="{% url lava.scheduler.job.annotate_failure job.pk %}" method="post">
-{% csrf_token %}
-{{ form }}
-<input type="submit" value="Submit" />
-</form>
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job_definition.html'
--- lava_scheduler_app/templates/lava_scheduler_app/job_definition.html	2013-09-11 19:21:44 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job_definition.html	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-{% extends "lava_scheduler_app/job_sidebar.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/shCore.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/shBrushJScript.js"></script>
-
-<link href="{{ STATIC_URL }}lava_scheduler_app/css/shCore.css" rel="stylesheet" type="text/css" />
-<link href="{{ STATIC_URL }}lava_scheduler_app/css/shThemeDefault.css" rel="stylesheet" type="text/css" />
-<link href="{{ STATIC_URL }}lava_scheduler_app/css/shThemeLAVA.css" rel="stylesheet" type="text/css" />
-{% endblock %}
-
-{% block content %}
-<h2>Job definition file - {{ job.id }} </h2>
-<a href="{% url lava.scheduler.job.definition.plain job.pk %}">Download as text file</a>
-<pre class="brush: js">{{ job.definition }}</pre>
-
-<script type="text/javascript">
-     SyntaxHighlighter.all()
-</script>
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job_log_file.html'
--- lava_scheduler_app/templates/lava_scheduler_app/job_log_file.html	2013-08-26 13:08:40 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job_log_file.html	1970-01-01 00:00:00 +0000
@@ -1,177 +0,0 @@
-{% extends "lava_scheduler_app/job_sidebar.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava_scheduler_app/css/logfile.css"/>
-{% endblock %}
-
-{% block content %}
-{% load linenumbers %}
-<h2>Dispatcher log file - {{ job.id }} </h1>
-<a href="{% url lava.scheduler.job.log_file.plain job.pk %}">Download as text file</a>
-
-<div id="logfile_content">
-{% for section in sections %}
-<a name="entry{{ forloop.counter0 }}"></a>
-{% if section.0 == 'console' and section.1 > 20 and not forloop.last %}
-<a href="#entry{{ forloop.counter }}">skip {{ section.1 }} lines to next log entry &rarr;</a>
-{% endif %}
-{% linenumbers section.2 forloop.counter0 section.0 %}
-{% endfor %}
-{% if job.status == job.RUNNING %}
-<img id="progress" src="{{ STATIC_URL }}lava_scheduler_app/images/ajax-progress.gif"/>
-{% endif %}
-</div>
-
-{% if job.status == job.RUNNING %}
-<script type="text/javascript">
-var pollTimer = null, logLenth = '{{ job_file_size }}';
-
-function poll (start) {
-  $.ajax({
-    url: '{% url lava_scheduler_app.views.job_full_log_incremental pk=job.pk %}?start=' + logLenth,
-    dataType: 'json',
-    global: false,
-    success: function (data, success, xhr) {
-      var progressNode = $('#progress');
-      for (var i = 0; i < data.length; i++) {
-          var d = data[i];
-          var cls = 'log_' + d[0];
-          var last_pre = $("#logfile_content pre:last");
-          var s = $("html"), w = $(window);
-          var atBottom = w.attr('innerHeight') + w.scrollTop() >= s.attr('scrollHeight')
-                      && w.attr('innerHeight') > progressNode.attr('offsetHeight');
-          if (last_pre.attr('class') == cls) {
-              append_to_section(last_pre, d);
-          } else {
-              var newNode = create_new_section_node(d);
-              newNode.insertBefore(progressNode);
-          }
-          if (atBottom) {
-            w.scrollTop(s.attr('scrollHeight'))
-          }
-      }
-      logLenth = xhr.getResponseHeader('X-Current-Size');
-      if (xhr.getResponseHeader('X-Is-Finished')) {
-        progressNode.css('display', 'none');
-      } else {
-        pollTimer = setTimeout(poll, 1000);
-      }
-    }
-  });
-}
-
-append_to_section = function (element, data) {
-
-    current_table = $("#logfile_content table:last");
-    data_arr = data[2].replace(/\r\n/, "\n").split("\n");
-    line_number = get_current_section_number()[1];
-
-    if (data_arr[data_arr.length-1] == "") {
-        data_arr.pop();
-    }
-
-    for (var i in data_arr) {
-        line_number++;
-        name = "L_" + section_number + "_" + line_number;
-        display = section_number + "." + line_number;
-
-        link_node = $("<a>", {
-            href: "#" + name,
-            html: display
-        });
-
-        section_line = $("<div>", {
-            class: "line",
-        }).append($("<a>", {
-            name: name,
-        })).append(link_node);
-
-        $(current_table).find("td:first").append(section_line);
-
-        line_node = $("<div>", {
-            id: name,
-            class: "line"
-        }).html("&nbsp;" + data_arr[i]);
-        element.append(line_node);
-    }
-}
-
-create_new_section_node = function(data) {
-
-    section_number++;
-    data_arr = data[2].split("\n");
-    if (data_arr[data_arr.length-1] == "") {
-        data_arr.pop();
-    }
-
-    section_node = $("<td>");
-    for (var i in data_arr) {
-        name = "L_" + section_number + "_" + i;
-        if (i == 0) {
-            display = "Section " + section_number;
-        } else {
-            display = section_number + "." + i;
-        }
-
-        link_node = $("<a>", {
-            href: "#" + name,
-            html: display
-        });
-
-        section_node.append($("<div>", {
-            class: "line",
-        }).append($("<a>", {
-            name: name,
-        })).append(link_node));
-    }
-
-    text_element = $("<pre>", {
-                  class: "log_" + data[0],
-              });
-    for (var i in data_arr) {
-        var id = "L_" + section_number + "_" + i;
-        text_element.append($("<div>", {
-            id: id,
-            class: "line"
-
-        }).html("&nbsp;" + data_arr[i]));
-    }
-
-    var text_node = $("<td>", {
-                      class: "code",
-                  }).append($("<div>",{
-                      class: "container",
-                  }).append(text_element));
-
-    var node = $("<table>")
-                .append($("<tr>")
-                .append(section_node)
-                .append(text_node)
-               );
-
-    return node;
-}
-
-get_current_section_number = function() {
-
-    last_div = $("#logfile_content div:last");
-
-    if ($(last_div).attr("id")) {
-        div_id_arr = $(last_div).attr("id").split('_');
-        return [div_id_arr[1], div_id_arr[2]];
-    }
-
-    return [-1, -1];
-}
-
-var section_line_number = get_current_section_number();
-var section_number = section_line_number[0];
-
-$(document).ready(function () {
-  pollTimer = setTimeout(poll, 1000);
-});
-</script>
-{% endif %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html'
--- lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html	2013-08-28 09:34:40 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html	1970-01-01 00:00:00 +0000
@@ -1,127 +0,0 @@
-{% extends "layouts/content_with_sidebar.html" %}
-
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava-server/css/demo_table_jui.css"/>
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava_scheduler_app/css/scheduler.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}lava-server/js/jquery.dataTables.min.js"></script>
-{% endblock %}
-
-
-{% block sidebar %}
-<h2>Job information</h2>
-<dl>
-    <dt>Submitted by:</dt>
-    <dd>{{ job.submitter }}</dd>
-
-    {% if job.requested_device %}
-    <dt>Requested device:</dt>
-    <dd>
-      <a href="{{ job.requested_device.get_absolute_url }}">{{ job.requested_device }}</a>
-    </dd>
-    {% endif %}
-
-    {% if job.requested_device_type %}
-    <dt>Requested type:</dt>
-    <dd>{{ job.requested_device_type }}</dd>
-    {% endif %}
-
-    {% for tag in job.tags.all %}
-    {% if forloop.first %}
-    {% if forloop.revcounter > 1 %}
-    <dt>Required Device Tags</dt>
-    {% else %}
-    <dt>Required Device Tag</dt>
-    {% endif %}
-    {% endif %}
-    <dd>{{ tag.name }}</dd>
-    {% endfor %}
-
-    {% if job.description %}
-    <dt>Description:</dt>
-    <dd>{{ job.description }}</dd>
-    {% endif %}
-     <dt>Status:</dt>
-    <dd>{{ job.get_status_display }}</dd>
-
-    <dt>Priority:</dt>
-    <dd>{{ job.get_priority_display }}</dd>
-
-    {% if job.actual_device %}
-    <dt>On device:</dt>
-    <dd>
-      <a href="{{ job.actual_device.get_absolute_url }}">{{ job.actual_device }}</a>
-    </dd>
-    {% endif %}
-     <dt>Submitted at:</dt>
-    <dd>{{ job.submit_time }}</dd>
-
-    <dt>Started at:</dt>
-    <dd>{{ job.start_time|default:"not started" }}</dd>
-
-    <dt>Finished at:</dt>
-    <dd>{{ job.end_time|default:"not finished" }}</dd>
-
-    {% if job.is_multinode %}
-    <dt>Sub Jobs:</dt>
-    {% for subjob in job.sub_jobs_list %}
-    <dd>
-      <a href="{% url lava.scheduler.job.detail subjob.pk %}">
-        {{ subjob.sub_id }}</a>
-    </dd>
-    {% endfor %}
-    {% endif %}
-
-</dl>
-<h2>Views</h2>
-<ul>
-    <li>
-        <a href="{% url lava.scheduler.job.detail job.pk %}">Summary</a>
-    </li>
-{% if job_file_present %}
-    <li>
-        <a href="{% url lava.scheduler.job.log_file job.pk %}">Complete log</a>
-    </li>
-{% endif %}
-    <li>
-        <a href="{% url lava.scheduler.job.definition job.pk %}">Definition</a>
-    </li>
-    {% if job.is_multinode %}
-    <li>
-        <a href="{% url lava.scheduler.job.multinode_definition job.pk %}"> Multinode Definition</a>
-    </li>
-    {% endif %}
-    {% if job.results_link %}
-    <li>
-        <a href="{{ job.results_link }}">Results Bundle</a>
-    </li>
-    {% endif %}
-
-</ul>
-{% if show_cancel or show_failure %}
-<h2>Job Actions</h2>
-{% if show_cancel %}
-<form method="POST"
-      action="{% url lava.scheduler.job.cancel job.pk %}">
-  {% csrf_token %}
-  <button id="cancel-button">Cancel</button>
-</form>
-{% endif %}
-{% if show_resubmit %}
-<form method="POST"
-      action="{% url lava.scheduler.job.resubmit job.pk %}">
-  {% csrf_token %}
-  <button>Re-submit</button>
-</form>
-{% endif %}
-{% if show_failure %}
-<form method="GET"
-      action="{% url lava.scheduler.job.annotate_failure job.pk %}">
-  <button>Annotate</button>
-</form>
-{% endif %}
-{% endif %}
-
-{% endblock %}
-

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job_submit.html'
--- lava_scheduler_app/templates/lava_scheduler_app/job_submit.html	2013-07-04 08:50:24 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job_submit.html	1970-01-01 00:00:00 +0000
@@ -1,77 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava_scheduler_app/css/jquery-linedtextarea.css"/>
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava_scheduler_app/css/scheduler.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/jquery-linedtextarea.js"></script>
-{% url lava.scheduler.get_remote_json as remote_json_url %}
-<script type="text/javascript">
-  var remote_json_url = '{{ remote_json_url }}';
-</script>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/job-submit.js"></script>
-{% endblock %}
-
-
-{% block content %}
-<h2>Submit Job</h2>
-
-{% if is_authorized %}
-
-{% if job_id %}
-
-{% url lava.scheduler.job.detail job_id as detail_url %}
-{% url lava.scheduler.job.list as list_url %}
-
-<div id="job-success">Job submission successfull!
-<br>
-<br>
-Job with ID <a href="{{ detail_url }}">{{ job_id }}</a> has been created.
-<br>
-To view the full job list click <a href="{{ list_url }}">here</a>.
-</div>
-
-{% elif job_list %}
-{% url lava.scheduler.job.list as list_url %}
-<div id="job-success">Multinode Job submission successfull!
-<br>
-<br>
-Jobs with ID {{ job_list }}</a> has been created.
-<br>
-To view the full job list click <a href="{{ list_url }}">here</a>.
-</div>
-
-{% else %}
-
-{% if error %}
-<div id="job-error">
-  Job submission error: {{ error }}
-</div>
-{% endif %}
-
-<p>Paste your job definition JSON here. Alternatively, you can paste a URL to your job definition file:</p>
-
-<form action="" method="post">
-  {% csrf_token %}
-  <textarea id="json-input" name="json-input" placeholder="Enter your job definition or link to a job definition here.">
-{% if json_input %}{{ json_input }}{% endif %}
-  </textarea>
-  <div id="json-valid-container">
-  </div>
-  <div id="submit-container">
-    <input id="submit" type="submit" value="Submit">
-  </div>
-</form>
-
-{% endif %}
-
-{% else %}
-<h3>
-Error:
-</h3>
-<p>Permission denied. You not have the required permissions to submit new jobs.
-<br>
-Please contact the administrators.</p>
-{% endif %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/job_summary_mail.txt'
--- lava_scheduler_app/templates/lava_scheduler_app/job_summary_mail.txt	2012-04-05 04:34:13 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/job_summary_mail.txt	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-Hi,
-
-The job with id {{ job.id }} has finished.  It took {{ job.start_time|timesince:job.end_time }}.
-
-The final status was {{ job.get_status_display }}.
-
-You can see more details at:
-
-  {{ url_prefix }}{{ job.get_absolute_url }}
-{% if job.results_bundle %}
-The results can be summarized as:
-
- +----------------------+--------+--------+
- | Test run             | Passes |  Total |
- +----------------------+--------+--------+
-{% for run in job.results_bundle.test_runs.all %}{% with results=run.get_summary_results %} | {{ run.test.test_id|ljust:20 }} | {{ results.pass|default:0|rjust:6 }} | {{ results.total|default:0|rjust:6 }} |
-{% endwith %}{% endfor %} +----------------------+--------+--------+
-
-For more details, please see:
-
-   {{ url_prefix }}{{ job.results_bundle.get_absolute_url }}
-
-{% else %}
-No results were reported to the dashboard for this run.
-
-{% endif %}LAVA
-Linaro Automated Validation

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/labhealth.html'
--- lava_scheduler_app/templates/lava_scheduler_app/labhealth.html	2012-03-01 23:14:16 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/labhealth.html	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block content %}
-<h2>Lab Health</h2>
-
-{% render_table device_health_table %}
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html'
--- lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html	2013-09-11 19:21:44 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-{% extends "lava_scheduler_app/job_sidebar.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/shCore.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/shBrushJScript.js"></script>
-
-<link href="{{ STATIC_URL }}lava_scheduler_app/css/shCore.css" rel="stylesheet" type="text/css" />
-<link href="{{ STATIC_URL }}lava_scheduler_app/css/shThemeDefault.css" rel="stylesheet" type="text/css" />
-<link href="{{ STATIC_URL }}lava_scheduler_app/css/shThemeLAVA.css" rel="stylesheet" type="text/css" />
-{% endblock %}
-
-{% block content %}
-<h2>Multinode Job definition file - {{ job.sub_id }} </h2>
-<a href="{% url lava.scheduler.job.multinode_definition.plain job.pk %}">Download as text file</a>
-<pre class="brush: js">{{ job.multinode_definition }}</pre>
-
-<script type="text/javascript">
-     SyntaxHighlighter.all()
-</script>
-
-{% endblock %}

=== removed file 'lava_scheduler_app/templates/lava_scheduler_app/reports.html'
--- lava_scheduler_app/templates/lava_scheduler_app/reports.html	2013-01-02 22:33:19 +0000
+++ lava_scheduler_app/templates/lava_scheduler_app/reports.html	1970-01-01 00:00:00 +0000
@@ -1,150 +0,0 @@
-{% extends "lava_scheduler_app/_content.html" %}
-
-{% block content %}
-
-<h2>Health Job Summary</h2>
-<div style="display:inline-block; padding-left:20px;">
-
-<h3>By Day</h3>
-<div id="placeholder-daily" style="width:300px;height:200px;"></div>
-<script type="text/javascript">
-$(document).ready(function() {
-var dpass = [];
-var ddates= [];
-{% for day in health_day_report %}
-  dpass.push([{{forloop.counter0}}, 100*{{day.pass}}/({{day.pass}}+{{day.fail}})]);
-  ddates.push([{{forloop.counter0}}, "<a href='{{day.failure_url}}'>{{day.date}}</a><br/>Pass: {{day.pass}}<br/>Fail: {{day.fail}}"]);
-{% endfor %}
-
-  var ddata = [
-    {'label': '% Pass', 'data': dpass, 'color': '#00FF00'},
-  ];
-
-  $.plot($("#placeholder-daily"), ddata, {
-    series: {
-      lines: { show: true, fill: true, steps: false },
-    },
-    xaxis: {
-      ticks: ddates,
-    },
-    yaxis: {
-      max: 100,
-    },
-  });
-}
-);
-</script>
-</div>
-
-<div style="display:inline-block; padding-left:40px;">
-
-<h3>By Week</h3>
-<div id="placeholder-weekly" style="width:500px;height:200px;"></div>
-<script type="text/javascript">
-$(document).ready(function() {
-var wpass = [];
-var wdates= [];
-{% for week in health_week_report %}
-  wpass.push([{{forloop.counter0}}, 100*{{week.pass}}/({{week.pass}}+{{week.fail}})]);
-  wdates.push([{{forloop.counter0}}, "<a href='{{week.failure_url}}'>{{week.date}}</a><br/>Pass: {{week.pass}}<br/>Fail: {{week.fail}}"]);
-{% endfor %}
-
-  var wdata = [
-    {'label': '% Pass', 'data': wpass, 'color': '#00FF00'},
-  ];
-
-  $.plot($("#placeholder-weekly"), wdata, {
-    series: {
-      lines: { show: true, fill: true, steps: false },
-    },
-    xaxis: {
-      ticks: wdates,
-    },
-    yaxis: {
-      max: 100,
-    },
-  });
-}
-);
-</script>
-</div>
-
-<h2>Test Job Summary</h2>
-<div style="display:inline-block; padding-left:20px;">
-
-<h3>By Day</h3>
-<div id="placeholder-job-daily" style="width:300px;height:200px;"></div>
-<script type="text/javascript">
-$(document).ready(function() {
-var jdpass = [];
-var jddates= [];
-{% for day in job_day_report %}
-  jdpass.push([{{forloop.counter0}}, 100*{{day.pass}}/({{day.pass}}+{{day.fail}})]);
-  jddates.push([{{forloop.counter0}}, "<a href='{{day.failure_url}}'>{{day.date}}</a><br/>Pass: {{day.pass}}<br/>Fail: {{day.fail}}"]);
-{% endfor %}
-
-  var jddata = [
-    {'label': '% Pass', 'data': jdpass, 'color': '#00FF00'},
-  ];
-
-  $.plot($("#placeholder-job-daily"), jddata, {
-    series: {
-      lines: { show: true, fill: true, steps: false },
-    },
-    xaxis: {
-      ticks: jddates,
-    },
-    yaxis: {
-      max: 100,
-    },
-  });
-}
-);
-</script>
-</div>
-
-<div style="display:inline-block; padding-left:40px;">
-
-<h3>By Week</h3>
-<div id="placeholder-job-weekly" style="width:500px;height:200px;"></div>
-<script type="text/javascript">
-$(document).ready(function() {
-var jwpass = [];
-var jwdates= [];
-{% for week in job_week_report %}
-  jwpass.push([{{forloop.counter0}}, 100*{{week.pass}}/({{week.pass}}+{{week.fail}})]);
-  jwdates.push([{{forloop.counter0}}, "<a href='{{week.failure_url}}'>{{week.date}}</a><br/>Pass: {{week.pass}}<br/>Fail: {{week.fail}}"]);
-{% endfor %}
-
-  var jwdata = [
-    {'label': '% Pass', 'data': jwpass, 'color': '#00FF00'},
-  ];
-
-  $.plot($("#placeholder-job-weekly"), jwdata, {
-    series: {
-      lines: { show: true, fill: true, steps: false },
-    },
-    xaxis: {
-      ticks: jwdates,
-    },
-    yaxis: {
-      max: 100,
-    },
-  });
-}
-);
-</script>
-</div>
-
-<h2>Longest Running Jobs</h2>
-{% if long_running|length_is:"0" %}
-There are no running jobs.
-{% else %}
-<ul>
-{% for job in long_running %}
-  <li><a href="{{job.get_absolute_url}}">{{job.id}}</a>: {{job.start_time}}</li>
-{% endfor %}
-</ul>
-{% endif %}
-
-{% endblock %}

=== removed directory 'lava_scheduler_app/templatetags'
=== removed file 'lava_scheduler_app/templatetags/__init__.py'
=== removed file 'lava_scheduler_app/templatetags/linenumbers.py'
--- lava_scheduler_app/templatetags/linenumbers.py	2013-08-26 13:08:40 +0000
+++ lava_scheduler_app/templatetags/linenumbers.py	1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
-from django import template
-from django.db.models import fields
-from django.utils.html import escape
-from django.utils.safestring import mark_safe
-
-register = template.Library()
-
-class LineNumbers(template.Node):
-    def __init__(self, text, prefix, style):
-        self.text = template.Variable(text)
-        self.prefix = template.Variable(prefix)
-        self.style = template.Variable(style)
-
-    def render(self, context):
-        text = self.text.resolve(context)
-        prefix = self.prefix.resolve(context)
-        style = self.style.resolve(context)
-        ret = "<table><tr><td>"
-        for i in range(0, len(text.splitlines())):
-            name = "L_%s_%s" % (prefix, i)
-            if (i == 0):
-                display = "Section %s" % (prefix)
-            else:
-                display = "%s.%s" % (prefix, i)
-            ret += "<div class=\"line\"><a name=\"%s\"></a> \
-                <a href=\"#%s\">%s</a></div>" % (name, name, display)
-
-        ret += "</td><td class=\"code\"><div class=\"containter\"> \
-            <pre class=\"log_%s\">" % (style)
-
-        for index, line in enumerate(text.splitlines()):
-            ret += "<div id=\"L_%s_%s\" class=\"line\"> &nbsp;%s</div>" % \
-                (prefix,
-                 index,
-                 mark_safe(escape(line).encode('ascii', 'xmlcharrefreplace')))
-
-        ret += "</pre></div></td><tr></table>"
-
-        return ret
-
-@register.tag('linenumbers')
-def do_linenumbers(parser, token):
-    try:
-        tag_name, text, prefix, style = token.split_contents()
-    except ValueError:
-        raise template.TemplateSyntaxError("%r tag requires 3 arguments" % \
-            token.contents.split()[0])
-    return LineNumbers(text, prefix, style)

=== removed file 'lava_scheduler_app/tests.py'
--- lava_scheduler_app/tests.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/tests.py	1970-01-01 00:00:00 +0000
@@ -1,731 +0,0 @@
-import cStringIO
-import datetime
-import json
-import xmlrpclib
-
-from dashboard_app.models import BundleStream
-
-from django.contrib.auth.models import Group, Permission, User
-from django.test import TransactionTestCase
-from django.test.client import Client
-
-from django_testscenarios.ubertest import TestCase
-
-from linaro_django_xmlrpc.models import AuthToken
-
-from lava_scheduler_app.models import (
-    Device,
-    DeviceType,
-    JSONDataError,
-    Tag,
-    TestJob)
-from lava_scheduler_daemon.dbjobsource import DatabaseJobSource
-
-
-# Based on http://www.technobabble.dk/2008/apr/02/xml-rpc-dispatching-through-django-test-client/
-class TestTransport(xmlrpclib.Transport):
-    """Handles connections to XML-RPC server through Django test client."""
-
-    def __init__(self, user=None, password=None):
-        self.client = Client()
-        if user:
-            success = self.client.login(username=user, password=password)
-            if not success:
-                raise AssertionError("Login attempt failed!")
-        self._use_datetime = True
-
-    def request(self, host, handler, request_body, verbose=0):
-        self.verbose = verbose
-        response = self.client.post(
-            handler, request_body, content_type="text/xml")
-        res = cStringIO.StringIO(response.content)
-        res.seek(0)
-        return self.parse_response(res)
-
-
-class ModelFactory(object):
-
-    def __init__(self):
-        self._int = 0
-
-    def getUniqueInteger(self):
-        self._int += 1
-        return self._int
-
-    def getUniqueString(self, prefix='generic'):
-        return '%s-%d' % (prefix, self.getUniqueInteger())
-
-    def make_user(self):
-        return User.objects.create_user(
-            self.getUniqueString(),
-            '%s@mail.invalid' % (self.getUniqueString(),),
-            self.getUniqueString())
-
-    def ensure_device_type(self, name=None):
-        if name is None:
-            name = self.getUniqueString('name')
-        return DeviceType.objects.get_or_create(name=name)[0]
-
-    def make_device_type(self, name=None, health_check_job=None):
-        if name is None:
-            name = self.getUniqueString('name')
-        device_type = DeviceType.objects.create(
-            name=name, health_check_job=health_check_job)
-        device_type.save()
-        return device_type
-
-    def ensure_tag(self, name):
-        return Tag.objects.get_or_create(name=name)[0]
-
-    def make_device(self, device_type=None, hostname=None, **kw):
-        if device_type is None:
-            device_type = self.ensure_device_type()
-        if hostname is None:
-            hostname = self.getUniqueString()
-        device = Device(device_type=device_type, hostname=hostname, **kw)
-        device.save()
-        return device
-
-    def make_job_data(self, actions=[], **kw):
-        data = {'actions': actions, 'timeout': 1, 'health_check': False}
-        data.update(kw)
-        if 'target' not in data and 'device_type' not in data:
-            if DeviceType.objects.all():
-                data['device_type'] = DeviceType.objects.all()[0].name
-            else:
-                data['device_type'] = self.ensure_device_type().name
-        return data
-
-    def make_job_json(self, **kw):
-        return json.dumps(self.make_job_data(**kw))
-
-    def make_testjob(self, definition=None, submitter=None, **kwargs):
-        if definition is None:
-            definition = self.make_job_json()
-        if submitter is None:
-            submitter = self.make_user()
-        if 'user' not in kwargs:
-            kwargs['user'] = submitter
-        testjob = TestJob(
-            definition=definition, submitter=submitter, **kwargs)
-        testjob.save()
-        return testjob
-
-
-class TestCaseWithFactory(TestCase):
-
-    def setUp(self):
-        TestCase.setUp(self)
-        self.factory = ModelFactory()
-
-
-class TestTestJob(TestCaseWithFactory):
-
-    def test_from_json_and_user_sets_definition(self):
-        definition = self.factory.make_job_json()
-        job = TestJob.from_json_and_user(definition, self.factory.make_user())
-        self.assertEqual(definition, job.definition)
-
-    def test_from_json_and_user_sets_submitter(self):
-        user = self.factory.make_user()
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(), user)
-        self.assertEqual(user, job.submitter)
-
-    def test_from_json_and_user_sets_device_type(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(device_type='panda'),
-            self.factory.make_user())
-        self.assertEqual(panda_type, job.requested_device_type)
-
-    def test_from_json_and_user_sets_target(self):
-        panda_board = self.factory.make_device(hostname='panda01')
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(target='panda01'),
-            self.factory.make_user())
-        self.assertEqual(panda_board, job.requested_device)
-
-    def test_from_json_and_user_does_not_set_device_type_from_target(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        self.factory.make_device(device_type=panda_type, hostname='panda01')
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(target='panda01'),
-            self.factory.make_user())
-        self.assertEqual(None, job.requested_device_type)
-
-    def test_from_json_and_user_sets_date_submitted(self):
-        before = datetime.datetime.now()
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(),
-            self.factory.make_user())
-        after = datetime.datetime.now()
-        self.assertTrue(before < job.submit_time < after)
-
-    def test_from_json_and_user_sets_status_to_SUBMITTED(self):
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(),
-            self.factory.make_user())
-        self.assertEqual(job.status, TestJob.SUBMITTED)
-
-    def test_from_json_and_user_sets_no_tags_if_no_tags(self):
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(device_tags=[]),
-            self.factory.make_user())
-        self.assertEqual(set(job.tags.all()), set([]))
-
-    def test_from_json_and_user_errors_on_unknown_tags(self):
-        self.assertRaises(
-            JSONDataError, TestJob.from_json_and_user,
-            self.factory.make_job_json(device_tags=['unknown']),
-            self.factory.make_user())
-
-    def test_from_json_and_user_sets_tag_from_device_tags(self):
-        self.factory.ensure_tag('tag')
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(device_tags=['tag']),
-            self.factory.make_user())
-        self.assertEqual(
-            set(tag.name for tag in job.tags.all()), set(['tag']))
-
-    def test_from_json_and_user_sets_multiple_tag_from_device_tags(self):
-        self.factory.ensure_device_type(name='panda')
-        self.factory.ensure_tag('tag1')
-        self.factory.ensure_tag('tag2')
-        job = TestJob.from_json_and_user(
-            self.factory.make_job_json(device_tags=['tag1', 'tag2']),
-            self.factory.make_user())
-        self.assertEqual(
-            set(tag.name for tag in job.tags.all()), set(['tag1', 'tag2']))
-
-    def test_from_json_and_user_reuses_tag_objects(self):
-        self.factory.ensure_device_type(name='panda')
-        self.factory.ensure_tag('tag')
-        job1 = TestJob.from_json_and_user(
-            self.factory.make_job_json(device_tags=['tag']),
-            self.factory.make_user())
-        job2 = TestJob.from_json_and_user(
-            self.factory.make_job_json(device_tags=['tag']),
-            self.factory.make_user())
-        self.assertEqual(
-            set(tag.pk for tag in job1.tags.all()),
-            set(tag.pk for tag in job2.tags.all()))
-
-    def test_from_json_and_user_rejects_invalid_json(self):
-        self.assertRaises(
-            ValueError, TestJob.from_json_and_user, '{',
-            self.factory.make_user())
-
-    def test_from_json_and_user_rejects_invalid_job(self):
-        # job data must have the 'actions' and 'timeout' properties, so this
-        # will be rejected.
-        self.assertRaises(
-            ValueError, TestJob.from_json_and_user, '{}',
-            self.factory.make_user())
-
-    def make_job_json_for_stream_name(self, stream_name):
-        return self.factory.make_job_json(
-            actions=[
-                {
-                    'command': 'submit_results',
-                    'parameters': {
-                        'server': '...',
-                        'stream': stream_name,
-                    }
-                }
-            ])
-
-    def test_from_json_and_user_sets_group_from_bundlestream(self):
-        group = Group.objects.create(name='group')
-        user = self.factory.make_user()
-        user.groups.add(group)
-        b = BundleStream.objects.create(
-            group=group, slug='blah', is_public=True)
-        b.save()
-        j = self.make_job_json_for_stream_name(b.pathname)
-        job = TestJob.from_json_and_user(j, user)
-        self.assertEqual(group, job.group)
-
-    def test_from_json_and_user_can_submit_to_anonymous(self):
-        user = self.factory.make_user()
-        anon_user = User.objects.get_or_create(username="anonymous-owner")[0]
-        b = BundleStream.objects.create(
-            slug='anonymous', is_anonymous=True, user=anon_user,
-            is_public=True)
-        b.save()
-        j = self.make_job_json_for_stream_name('/anonymous/anonymous/')
-        job = TestJob.from_json_and_user(j, user)
-        self.assertEqual(user, job.submitter)
-
-    def test_from_json_and_user_sets_is_public_from_bundlestream(self):
-        group = Group.objects.create(name='group')
-        user = self.factory.make_user()
-        user.groups.add(group)
-        b = BundleStream.objects.create(
-            group=group, slug='blah', is_public=False)
-        b.save()
-        j = self.make_job_json_for_stream_name(b.pathname)
-        job = TestJob.from_json_and_user(j, user)
-        self.assertEqual(False, job.is_public)
-
-    def test_from_json_and_user_rejects_missing_bundlestream(self):
-        user = self.factory.make_user()
-        j = self.make_job_json_for_stream_name('no such stream')
-        self.assertRaises(ValueError, TestJob.from_json_and_user, j, user)
-
-    def test_from_json_and_user_rejects_inaccessible_bundlestream(self):
-        stream_user = self.factory.make_user()
-        job_user = self.factory.make_user()
-        b = BundleStream.objects.create(
-            user=stream_user, slug='blah', is_public=True)
-        b.save()
-        j = self.make_job_json_for_stream_name(b.pathname)
-        self.assertRaises(ValueError, TestJob.from_json_and_user, j, job_user)
-
-
-class TestSchedulerAPI(TestCaseWithFactory):
-
-    def server_proxy(self, user=None, password=None):
-        return xmlrpclib.ServerProxy(
-            'http://localhost/RPC2/',
-            transport=TestTransport(user=user, password=password))
-
-    def test_submit_job_rejects_anonymous(self):
-        server = self.server_proxy()
-        try:
-            server.scheduler.submit_job("{}")
-        except xmlrpclib.Fault as f:
-            self.assertEqual(401, f.faultCode)
-        else:
-            self.fail("fault not raised")
-
-    def test_submit_job_rejects_unpriv_user(self):
-        User.objects.create_user('test', 'e@mail.invalid', 'test').save()
-        server = self.server_proxy('test', 'test')
-        try:
-            server.scheduler.submit_job("{}")
-        except xmlrpclib.Fault as f:
-            self.assertEqual(403, f.faultCode)
-        else:
-            self.fail("fault not raised")
-
-    def test_submit_job_sets_definition(self):
-        user = User.objects.create_user('test', 'e@mail.invalid', 'test')
-        user.user_permissions.add(
-            Permission.objects.get(codename='add_testjob'))
-        user.save()
-        server = self.server_proxy('test', 'test')
-        definition = self.factory.make_job_json()
-        job_id = server.scheduler.submit_job(definition)
-        job = TestJob.objects.get(id=job_id)
-        self.assertEqual(definition, job.definition)
-
-    def test_cancel_job_rejects_anonymous(self):
-        job = self.factory.make_testjob()
-        server = self.server_proxy()
-        try:
-            server.scheduler.cancel_job(job.id)
-        except xmlrpclib.Fault as f:
-            self.assertEqual(401, f.faultCode)
-        else:
-            self.fail("fault not raised")
-
-    def test_cancel_job_rejects_unpriv_user(self):
-        job = self.factory.make_testjob()
-        User.objects.create_user('test', 'e@mail.invalid', 'test').save()
-        server = self.server_proxy('test', 'test')
-        try:
-            server.scheduler.cancel_job(job.id)
-        except xmlrpclib.Fault as f:
-            self.assertEqual(403, f.faultCode)
-        else:
-            self.fail("fault not raised")
-
-    def test_cancel_job_cancels_job(self):
-        user = User.objects.create_user('test', 'e@mail.invalid', 'test')
-        user.save()
-        job = self.factory.make_testjob(submitter=user)
-        server = self.server_proxy('test', 'test')
-        server.scheduler.cancel_job(job.id)
-        job = TestJob.objects.get(pk=job.pk)
-        self.assertEqual(TestJob.CANCELED, job.status)
-
-
-class TransactionTestCaseWithFactory(TransactionTestCase):
-
-    def setUp(self):
-        TransactionTestCase.setUp(self)
-        self.factory = ModelFactory()
-
-
-class NonthreadedDatabaseJobSource(DatabaseJobSource):
-    deferToThread = staticmethod(lambda f, *args, **kw: f(*args, **kw))
-
-
-class TestDBJobSource(TransactionTestCaseWithFactory):
-
-    def setUp(self):
-        super(TestDBJobSource, self).setUp()
-        self.source = NonthreadedDatabaseJobSource()
-        # The lava-health user is created by a migration in production
-        # databases, but removed from the test database by the django
-        # machinery.
-        User.objects.create_user(
-            username='lava-health', email='lava@lava.invalid')
-
-    def test_getBoardList(self):
-        self.factory.make_device(hostname='panda01')
-        self.assertEqual(
-            [{'use_celery': False, 'hostname': 'panda01'}],
-            self.source.getBoardList())
-
-    def test_getJobForBoard_returns_json(self):
-        device = self.factory.make_device(hostname='panda01')
-        definition = self.factory.make_job_data(target='panda01')
-        self.factory.make_testjob(
-            requested_device=device, definition=json.dumps(definition))
-        self.assertEqual(
-            definition, self.source.getJobForBoard('panda01'))
-
-    @property
-    def health_job(self):
-        return self.factory.make_job_json(health_check=True)
-
-    @property
-    def ordinary_job(self):
-        return self.factory.make_job_json(health_check=False)
-
-    def assertHealthJobAssigned(self, device):
-        job_data = self.source.getJobForBoard(device.hostname)
-        if job_data is None:
-            self.fail("no job assigned")
-        self.assertTrue(
-            job_data['health_check'],
-            'getJobForBoard did not return health check job')
-
-    def assertHealthJobNotAssigned(self, device):
-        job_data = self.source.getJobForBoard(device.hostname)
-        if job_data is None:
-            self.fail("no job assigned")
-        self.assertFalse(
-            job_data['health_check'],
-            'getJobForBoard returned health check job')
-
-    def test_getJobForBoard_returns_health_check_if_no_last_health_job(self):
-        device_type = self.factory.make_device_type(
-            health_check_job=self.health_job)
-        device = self.factory.make_device(
-            device_type=device_type, health_status=Device.HEALTH_PASS)
-        self.factory.make_testjob(
-            requested_device=device, definition=self.ordinary_job)
-        self.assertHealthJobAssigned(device)
-
-    def test_getJobForBoard_returns_health_check_if_old_last_health_job(self):
-        device_type = self.factory.make_device_type(
-            health_check_job=self.health_job)
-        device = self.factory.make_device(
-            device_type=device_type, health_status=Device.HEALTH_PASS,
-            last_health_report_job=self.factory.make_testjob(
-                end_time=datetime.datetime.now() - datetime.timedelta(weeks=1)))
-        self.factory.make_testjob(
-            requested_device=device, definition=self.ordinary_job)
-        self.assertHealthJobAssigned(device)
-
-    def test_getJobForBoard_returns_job_if_healthy_and_last_health_job_recent(self):
-        device_type = self.factory.make_device_type(
-            health_check_job=self.health_job)
-        device = self.factory.make_device(
-            device_type=device_type, health_status=Device.HEALTH_PASS,
-            last_health_report_job=self.factory.make_testjob(
-                end_time=datetime.datetime.now() - datetime.timedelta(hours=1)))
-        self.factory.make_testjob(
-            requested_device=device, definition=self.ordinary_job)
-        self.assertHealthJobNotAssigned(device)
-
-    def test_getJobForBoard_returns_health_check_if_health_unknown(self):
-        device_type = self.factory.make_device_type(
-            health_check_job=self.health_job)
-        device = self.factory.make_device(
-            device_type=device_type, health_status=Device.HEALTH_UNKNOWN,
-            last_health_report_job=self.factory.make_testjob(
-                end_time=datetime.datetime.now() - datetime.timedelta(hours=1)))
-        self.factory.make_testjob(
-            requested_device=device, definition=self.ordinary_job)
-        self.assertHealthJobAssigned(device)
-
-    def test_getJobForBoard_returns_None_if_no_job(self):
-        self.factory.make_device(hostname='panda01')
-        self.assertEqual(
-            None, self.source.getJobForBoard('panda01'))
-
-    def test_getJobForBoard_considers_device_type(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        self.factory.make_device(hostname='panda01', device_type=panda_type)
-        definition = self.factory.make_job_data()
-        self.factory.make_testjob(
-            requested_device_type=panda_type,
-            definition=json.dumps(definition))
-        definition['target'] = 'panda01'
-        self.assertEqual(
-            definition, self.source.getJobForBoard('panda01'))
-
-    def test_getJobForBoard_prefers_older(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        panda01 = self.factory.make_device(
-            hostname='panda01', device_type=panda_type)
-        first_definition = self.factory.make_job_data(foo='bar', target='panda01')
-        second_definition = self.factory.make_job_data(foo='baz', target='panda01')
-        self.factory.make_testjob(
-            requested_device=panda01, definition=json.dumps(first_definition),
-            submit_time=datetime.datetime.now() - datetime.timedelta(days=1))
-        self.factory.make_testjob(
-            requested_device=panda01, definition=json.dumps(second_definition),
-            submit_time=datetime.datetime.now())
-        self.assertEqual(
-            first_definition,
-            self.source.getJobForBoard('panda01'))
-
-    def test_getJobForBoard_prefers_directly_targeted(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        panda01 = self.factory.make_device(
-            hostname='panda01', device_type=panda_type)
-        type_definition = self.factory.make_job_data()
-        self.factory.make_testjob(
-            requested_device_type=panda_type,
-            definition=json.dumps(type_definition),
-            submit_time=datetime.datetime.now() - datetime.timedelta(days=1))
-        device_definition = self.factory.make_job_data(
-            foo='baz', target='panda01')
-        self.factory.make_testjob(
-            requested_device=panda01,
-            definition=json.dumps(device_definition))
-        self.assertEqual(
-            device_definition,
-            self.source.getJobForBoard('panda01'))
-
-    def test_getJobForBoard_avoids_targeted_to_other_board_of_same_type(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        panda01 = self.factory.make_device(
-            hostname='panda01', device_type=panda_type)
-        self.factory.make_device(hostname='panda02', device_type=panda_type)
-        definition = self.factory.make_job_data(foo='bar', target='panda01')
-        self.factory.make_testjob(
-            requested_device=panda01,
-            definition=json.dumps(definition))
-        self.assertEqual(
-            None,
-            self.source.getJobForBoard('panda02'))
-
-    def _makeBoardWithTags(self, tags):
-        board = self.factory.make_device()
-        for tag_name in tags:
-            board.tags.add(Tag.objects.get_or_create(name=tag_name)[0])
-        return board
-
-    def _makeJobWithTagsForBoard(self, tags, board):
-        job = self.factory.make_testjob(requested_device=board)
-        for tag_name in tags:
-            job.tags.add(Tag.objects.get_or_create(name=tag_name)[0])
-        return job
-
-    def assertBoardWithTagsGetsJobWithTags(self, board_tags, job_tags):
-        board = self._makeBoardWithTags(board_tags)
-        self._makeJobWithTagsForBoard(job_tags, board)
-        self.assertEqual(
-            board.hostname,
-            self.source.getJobForBoard(board.hostname)['target'])
-
-    def assertBoardWithTagsDoesNotGetJobWithTags(self, board_tags, job_tags):
-        board = self._makeBoardWithTags(board_tags)
-        self._makeJobWithTagsForBoard(job_tags, board)
-        self.assertEqual(
-            None,
-            self.source.getJobForBoard(board.hostname))
-
-    def test_getJobForBoard_does_not_return_job_if_board_lacks_tag(self):
-        self.assertBoardWithTagsDoesNotGetJobWithTags([], ['tag'])
-
-    def test_getJobForBoard_returns_job_if_board_has_tag(self):
-        self.assertBoardWithTagsGetsJobWithTags(['tag'], ['tag'])
-
-    def test_getJobForBoard_returns_job_if_board_has_both_tags(self):
-        self.assertBoardWithTagsGetsJobWithTags(['tag1', 'tag2'], ['tag1', 'tag2'])
-
-    def test_getJobForBoard_returns_job_if_board_has_extra_tags(self):
-        self.assertBoardWithTagsGetsJobWithTags(['tag1', 'tag2'], ['tag1'])
-
-    def test_getJobForBoard_does_not_return_job_if_board_has_only_one_tag(self):
-        self.assertBoardWithTagsDoesNotGetJobWithTags(['tag1'], ['tag1', 'tag2'])
-
-    def test_getJobForBoard_does_not_return_job_if_board_has_unrelated_tag(self):
-        self.assertBoardWithTagsDoesNotGetJobWithTags(['tag1'], ['tag2'])
-
-    def test_getJobForBoard_does_not_return_job_if_only_one_tag_matches(self):
-        self.assertBoardWithTagsDoesNotGetJobWithTags(['tag1', 'tag2'], ['tag1', 'tag3'])
-
-    def test_getJobForBoard_sets_start_time(self):
-        device = self.factory.make_device(hostname='panda01')
-        job = self.factory.make_testjob(requested_device=device)
-        before = datetime.datetime.now()
-        self.source.getJobForBoard('panda01')
-        after = datetime.datetime.now()
-        # reload from the database
-        job = TestJob.objects.get(pk=job.pk)
-        self.assertTrue(before < job.start_time < after)
-
-    def test_getJobForBoard_set_statuses(self):
-        device = self.factory.make_device(hostname='panda01')
-        job = self.factory.make_testjob(requested_device=device)
-        self.source.getJobForBoard('panda01')
-        # reload from the database
-        job = TestJob.objects.get(pk=job.pk)
-        device = Device.objects.get(pk=device.pk)
-        self.assertEqual(
-            (Device.RUNNING, TestJob.RUNNING),
-            (device.status, job.status))
-
-    def test_getJobForBoard_sets_running_job(self):
-        device = self.factory.make_device(hostname='panda01')
-        job = self.factory.make_testjob(requested_device=device)
-        self.source.getJobForBoard('panda01')
-        # reload from the database
-        job = TestJob.objects.get(pk=job.pk)
-        device = Device.objects.get(pk=device.pk)
-        self.assertEqual(job, device.current_job)
-
-    def test_getJobForBoard_creates_token(self):
-        device = self.factory.make_device(hostname='panda01')
-        job = self.factory.make_testjob(requested_device=device)
-        self.source.getJobForBoard('panda01')
-        # reload from the database
-        job = TestJob.objects.get(pk=job.pk)
-        device = Device.objects.get(pk=device.pk)
-        self.assertIsNotNone(job.submit_token)
-        self.assertEqual(job.submitter, job.submit_token.user)
-
-    def test_getJobForBoard_inserts_target_into_json(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        self.factory.make_device(hostname='panda01', device_type=panda_type)
-        definition = self.factory.make_job_data(device_type='panda')
-        self.factory.make_testjob(
-            requested_device_type=panda_type,
-            definition=json.dumps(definition))
-        json_data = self.source.getJobForBoard('panda01')
-        self.assertIn('target', json_data)
-        self.assertEqual('panda01', json_data['target'])
-
-    def test_getJobForBoard_inserts_submit_token_into_json(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        self.factory.make_device(hostname='panda01', device_type=panda_type)
-        definition = {
-            'actions': [
-                {
-                    "command": "submit_results",
-                    "parameters":
-                    {
-                        "server": "http://test-server/RPC2/",
-                        "stream": "/private/personal/test/test/",
-                    }
-                }
-            ]
-        }
-        job = self.factory.make_testjob(
-            requested_device_type=panda_type,
-            definition=json.dumps(definition))
-        json_data = self.source.getJobForBoard('panda01')
-        job = TestJob.objects.get(pk=job.pk)
-        submit_job_params = json_data['actions'][0]['parameters']
-        self.assertIn('token', submit_job_params)
-        self.assertEqual(job.submit_token.secret, submit_job_params['token'])
-
-    def test_getJobForBoard_adds_user_to_url(self):
-        panda_type = self.factory.ensure_device_type(name='panda')
-        self.factory.make_device(hostname='panda01', device_type=panda_type)
-        user = User.objects.create_user('test', 'e@mail.invalid', 'test')
-        user.save()
-        definition = {
-            'actions': [
-                {
-                    "command": "submit_results",
-                    "parameters":
-                    {
-                        "server": "http://test-server/RPC2/",
-                        "stream": "/private/personal/test/test/",
-                    }
-                }
-            ]
-        }
-        job = self.factory.make_testjob(
-            requested_device_type=panda_type, submitter=user,
-            definition=json.dumps(definition))
-        json_data = self.source.getJobForBoard('panda01')
-        job = TestJob.objects.get(pk=job.pk)
-        submit_job_params = json_data['actions'][0]['parameters']
-        self.assertEqual("http://test@test-server/RPC2/", submit_job_params['server'])
-
-    def get_device_and_running_job(self):
-        device = self.factory.make_device(hostname='panda01')
-        job = self.factory.make_testjob(requested_device=device)
-        self.source.getJobForBoard('panda01')
-        return device, TestJob.objects.get(pk=job.pk)
-
-    def test_jobCompleted_set_statuses_success(self):
-        device, job = self.get_device_and_running_job()
-        self.source.jobCompleted('panda01', 0)
-        job = TestJob.objects.get(pk=job.pk)
-        device = Device.objects.get(pk=device.pk)
-        self.assertEqual(
-            (Device.IDLE, TestJob.COMPLETE),
-            (device.status, job.status))
-
-    def test_jobCompleted_set_statuses_failure(self):
-        device, job = self.get_device_and_running_job()
-        self.source.jobCompleted('panda01', 1)
-        job = TestJob.objects.get(pk=job.pk)
-        device = Device.objects.get(pk=device.pk)
-        self.assertEqual(
-            (Device.IDLE, TestJob.INCOMPLETE),
-            (device.status, job.status))
-
-    def test_jobCompleted_works_on_device_type_targeted(self):
-        device = self.factory.make_device(hostname='panda01')
-        job = self.factory.make_testjob(
-            requested_device_type=device.device_type)
-        self.source.getJobForBoard('panda01')
-        self.source.jobCompleted('panda01', 0)
-        job = TestJob.objects.get(pk=job.pk)
-        device = Device.objects.get(pk=device.pk)
-        self.assertEqual(
-            (Device.IDLE, TestJob.COMPLETE),
-            (device.status, job.status))
-
-    def test_jobCompleted_sets_end_time(self):
-        device, job = self.get_device_and_running_job()
-        before = datetime.datetime.now()
-        self.source.jobCompleted('panda01', 0)
-        after = datetime.datetime.now()
-        job = TestJob.objects.get(pk=job.pk)
-        self.assertTrue(before < job.end_time < after)
-
-    def test_jobCompleted_clears_current_job(self):
-        device, job = self.get_device_and_running_job()
-        self.source.jobCompleted('panda01', 0)
-        device = Device.objects.get(pk=device.pk)
-        self.assertEquals(None, device.current_job)
-
-    def test_jobCompleted_deletes_token(self):
-        device, job = self.get_device_and_running_job()
-        token = job.submit_token
-        self.source.jobCompleted('panda01', 0)
-        self.assertRaises(
-            AuthToken.DoesNotExist,
-            AuthToken.objects.get, pk=token.pk)
-
-    def test_getLogFileForJobOnBoard_returns_writable_file(self):
-        device, job = self.get_device_and_running_job()
-        definition = {'foo': 'bar'}
-        self.factory.make_testjob(
-            requested_device=device, definition=json.dumps(definition))
-        log_file = self.source.getLogFileForJobOnBoard('panda01')
-        log_file.write('a')
-        log_file.close()

=== removed file 'lava_scheduler_app/urls.py'
--- lava_scheduler_app/urls.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_app/urls.py	1970-01-01 00:00:00 +0000
@@ -1,120 +0,0 @@
-from django.conf.urls.defaults import url, patterns
-
-
-urlpatterns = patterns(
-    'lava_scheduler_app.views',
-    url(r'^$',
-        'index',
-        name='lava.scheduler'),
-    url(r'^reports$',
-        'reports',
-        name='lava.scheduler.reports'),
-    url(r'^reports/failures$',
-        'failure_report',
-        name='lava.scheduler.failure_report'),
-    url(r'^reports/failures_json$',
-        'failed_jobs_json',
-        name='lava.scheduler.failed_jobs_json'),
-    url(r'^active_jobs_json$',
-        'index_active_jobs_json',
-        name='lava.scheduler.active_jobs_json'),
-    url(r'^devices_json$',
-        'index_devices_json',
-        name='lava.scheduler.index_devices_json'),
-    url(r'^alljobs$',
-        'job_list',
-        name='lava.scheduler.job.list'),
-    url(r'^jobsubmit$',
-        'job_submit',
-        name='lava.scheduler.job.submit'),
-    url(r'^alljobs_json$',
-        'alljobs_json',
-        name='lava.scheduler.job.list_json'),
-    url(r'^device_type/(?P<pk>[-_a-zA-Z0-9]+)$',
-        'device_type_detail',
-        name='lava.scheduler.device_type.detail'),
-    url(r'^device_type_json$',
-        'device_type_json',
-        name='lava.scheduler.device_type.device_type_json'),
-    url(r'^device_type/(?P<pk>[-_a-zA-Z0-9]+)/index_nodt_devices_json$',
-        'index_nodt_devices_json',
-        name='lava.scheduler.device_type.index_nodt_devices_json'),
-    url(r'^alldevices$',
-        'device_list',
-        name='lava.scheduler.alldevices'),
-    url(r'^device/(?P<pk>[-_a-zA-Z0-9]+)$',
-        'device_detail',
-        name='lava.scheduler.device.detail'),
-    url(r'^device/(?P<pk>[-_a-zA-Z0-9]+)/recent_jobs_json$',
-        'recent_jobs_json',
-        name='lava.scheduler.device.recent_jobs_json'),
-    url(r'^device/(?P<pk>[-_a-zA-Z0-9]+)/transition_json$',
-        'transition_json',
-        name='lava.scheduler.device.transition_json'),
-    url(r'^device/(?P<pk>[-_a-zA-Z0-9]+)/maintenance$',
-        'device_maintenance_mode',
-        name='lava.scheduler.device.maintenance'),
-    url(r'^device/(?P<pk>[-_a-zA-Z0-9]+)/looping$',
-        'device_looping_mode',
-        name='lava.scheduler.device.looping'),
-    url(r'^device/(?P<pk>[-_a-zA-Z0-9]+)/online$',
-        'device_online',
-        name='lava.scheduler.device.online'),
-    url(r'^labhealth/$',
-        'lab_health',
-        name='lava.scheduler.labhealth'),
-    url(r'^labhealth/health_json$',
-        'lab_health_json',
-        name='lava.scheduler.labhealth_json'),
-    url(r'^labhealth/device/(?P<pk>[-_a-zA-Z0-9]+)$',
-        'health_job_list',
-        name='lava.scheduler.labhealth.detail'),
-    url(r'^labhealth/device/(?P<pk>[-_a-zA-Z0-9]+)/job_json$',
-        'health_jobs_json',
-        name='lava.scheduler.labhealth.health_jobs_json'),
-    url(r'^job/(?P<pk>[0-9]+)$',
-        'job_detail',
-        name='lava.scheduler.job.detail'),
-    url(r'^job/(?P<pk>[0-9]+)/definition$',
-        'job_definition',
-        name='lava.scheduler.job.definition'),
-    url(r'^job/(?P<pk>[0-9]+)/definition/plain$',
-        'job_definition_plain',
-        name='lava.scheduler.job.definition.plain'),
-    url(r'^job/(?P<pk>[0-9]+)/multinode_definition$',
-        'multinode_job_definition',
-        name='lava.scheduler.job.multinode_definition'),
-    url(r'^job/(?P<pk>[0-9]+)/multinode_definition/plain$',
-        'multinode_job_definition_plain',
-        name='lava.scheduler.job.multinode_definition.plain'),
-    url(r'^job/(?P<pk>[0-9]+)/log_file$',
-        'job_log_file',
-        name='lava.scheduler.job.log_file'),
-    url(r'^job/(?P<pk>[0-9]+)/log_file/plain$',
-        'job_log_file_plain',
-        name='lava.scheduler.job.log_file.plain'),
-    url(r'^job/(?P<pk>[0-9]+)/cancel$',
-        'job_cancel',
-        name='lava.scheduler.job.cancel'),
-    url(r'^job/(?P<pk>[0-9]+)/resubmit$',
-        'job_resubmit',
-        name='lava.scheduler.job.resubmit'),
-    url(r'^job/(?P<pk>[0-9]+)/annotate_failure$',
-        'job_annotate_failure',
-        name='lava.scheduler.job.annotate_failure'),
-    url(r'^job/(?P<pk>[0-9]+)/json$',
-        'job_json',
-        name='lava.scheduler.job.json'),
-    url(r'^job/(?P<pk>[0-9]+)/output$',
-        'job_output',
-        name='lava.scheduler.job.output'),
-    url(r'^job/(?P<pk>[0-9]+)/log_incremental$',
-        'job_log_incremental',
-        name='lava.scheduler.job.log_incremental'),
-    url(r'^job/(?P<pk>[0-9]+)/full_log_incremental$',
-        'job_full_log_incremental',
-        name='lava.scheduler.job.full_log_incremental'),
-    url(r'^get-remote-json',
-        'get_remote_json',
-        name='lava.scheduler.get_remote_json'),
-)

=== removed file 'lava_scheduler_app/utils.py'
--- lava_scheduler_app/utils.py	2013-09-17 14:59:18 +0000
+++ lava_scheduler_app/utils.py	1970-01-01 00:00:00 +0000
@@ -1,145 +0,0 @@
-# Copyright (C) 2013 Linaro Limited
-#
-# Author: Neil Williams <neil.williams@linaro.org>
-#         Senthil Kumaran <senthil.kumaran@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-import re
-import copy
-import socket
-import urlparse
-import simplejson
-import models
-
-
-def rewrite_hostname(result_url):
-    """If URL has hostname value as localhost/127.0.0.*, change it to the
-    actual server FQDN.
-
-    Returns the RESULT_URL (string) re-written with hostname.
-
-    See https://cards.linaro.org/browse/LAVA-611
-    """
-    host = urlparse.urlparse(result_url).netloc
-    if host == "localhost":
-        result_url = result_url.replace("localhost", socket.getfqdn())
-    elif host.startswith("127.0.0"):
-        ip_pat = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
-        result_url = re.sub(ip_pat, socket.getfqdn(), result_url)
-    return result_url
-
-
-def split_multi_job(json_jobdata, target_group):
-    node_json = {}
-    all_nodes = {}
-    node_actions = {}
-    node_lmp = {}
-    
-    # Check if we are operating on multinode job data. Else return the job
-    # data as it is.
-    if "device_group" in json_jobdata and target_group:
-        pass
-    else:
-        return json_jobdata
-
-    # get all the roles and create node action list for each role.
-    for group in json_jobdata["device_group"]:
-        node_actions[group["role"]] = []
-        node_lmp[group["role"]] = []
-
-    # Take each action and assign it to proper roles. If roles are not
-    # specified for a specific action, then assign it to all the roles.
-    all_actions = json_jobdata["actions"]
-    for role in node_actions.keys():
-        for action in all_actions:
-            new_action = copy.deepcopy(action)
-            if 'parameters' in new_action \
-                    and 'role' in new_action["parameters"]:
-                if new_action["parameters"]["role"] == role:
-                    new_action["parameters"].pop('role', None)
-                    node_actions[role].append(new_action)
-            else:
-                node_actions[role].append(new_action)
-
-    # For LMP init in multinode case
-    all_lmp_modules = json_jobdata["lmp_module"]
-    for role in node_lmp.keys():
-        for lmp in all_lmp_modules:
-            new_lmp = copy.deepcopy(lmp)
-            if 'parameters' in new_lmp \
-                    and 'role' in new_lmp["parameters"]:
-                if new_lmp["parameters"]["role"] == role:
-                    new_lmp["parameters"].pop('role', None)
-                    node_lmp[role].append(new_lmp)
-            else:
-                node_lmp[role].append(new_lmp)
-
-    group_count = 0
-    for clients in json_jobdata["device_group"]:
-        group_count += int(clients["count"])
-    if group_count <= 1:
-        raise models.JSONDataError("Only one device requested in a MultiNode job submission.")
-    for clients in json_jobdata["device_group"]:
-        role = str(clients["role"])
-        count = int(clients["count"])
-        node_json[role] = []
-        for c in range(0, count):
-            node_json[role].append({})
-            node_json[role][c]["timeout"] = json_jobdata["timeout"]
-            if json_jobdata.get("job_name", False):
-                node_json[role][c]["job_name"] = json_jobdata["job_name"]
-            if clients.get("tags", False):
-                node_json[role][c]["tags"] = clients["tags"]
-            node_json[role][c]["group_size"] = group_count
-            node_json[role][c]["target_group"] = target_group
-            node_json[role][c]["actions"] = node_actions[role]
-            node_json[role][c]["lmp_module"] = node_lmp[role]
-
-            node_json[role][c]["role"] = role
-            # multinode node stage 2
-            if json_jobdata.get("logging_level", False):
-                node_json[role][c]["logging_level"] = \
-                    json_jobdata["logging_level"]
-            if json_jobdata.get("priority", False):
-                node_json[role][c]["priority"] = json_jobdata["priority"]
-            node_json[role][c]["device_type"] = clients["device_type"]
-
-    return node_json
-
-
-def requested_device_count(json_data):
-    """Utility function check the requested number of devices for each
-    device_type in a multinode job.
-
-    JSON_DATA is the job definition string.
-
-    Returns requested_device which is a dictionary of the following format:
-
-    {'kvm': 1, 'qemu': 3, 'panda': 1}
-
-    If the job is not a multinode job, then return an empty dictionary.
-    """
-    job_data = simplejson.loads(json_data)
-    requested_devices = {}
-    if 'device_group' in job_data:
-        for device_group in job_data['device_group']:
-            device_type = device_group['device_type']
-            count = device_group['count']
-            if device_type in requested_devices:
-                requested_devices[device_type] += count
-            else:
-                requested_devices[device_type] = count
-    return requested_devices

=== removed file 'lava_scheduler_app/views.py'
--- lava_scheduler_app/views.py	2013-09-12 06:28:07 +0000
+++ lava_scheduler_app/views.py	1970-01-01 00:00:00 +0000
@@ -1,1037 +0,0 @@
-from collections import defaultdict
-import logging
-import os
-import simplejson
-import StringIO
-import datetime
-import urllib2
-from dateutil.relativedelta import relativedelta
-
-from django import forms
-
-from django.conf import settings
-from django.core.exceptions import PermissionDenied
-from django.core.urlresolvers import reverse
-from django.db.models import Count
-from django.http import (
-    HttpResponse,
-    HttpResponseBadRequest,
-    HttpResponseForbidden,
-    HttpResponseNotAllowed,
-)
-from django.shortcuts import (
-    get_object_or_404,
-    redirect,
-    render_to_response,
-)
-from django.template import RequestContext
-from django.template import defaultfilters as filters
-from django.utils.html import escape
-from django.utils.safestring import mark_safe
-from django.db import models
-from django.db.models import Q
-
-from django_tables2 import Attrs, Column
-
-from lava.utils.data_tables.tables import DataTablesTable
-
-from lava_server.views import index as lava_index
-from lava_server.bread_crumbs import (
-    BreadCrumb,
-    BreadCrumbTrail,
-)
-
-from lava_scheduler_app.logfile_helper import (
-    formatLogFile,
-    getDispatcherErrors,
-    getDispatcherLogMessages
-)
-from lava_scheduler_app.models import (
-    Device,
-    DeviceType,
-    DeviceStateTransition,
-    TestJob,
-    JSONDataError,
-    validate_job_json,
-    DevicesUnavailableException,
-)
-
-
-def post_only(func):
-    def decorated(request, *args, **kwargs):
-        if request.method != 'POST':
-            return HttpResponseNotAllowed('Only POST here')
-        return func(request, *args, **kwargs)
-    return decorated
-
-
-class DateColumn(Column):
-
-    def __init__(self, **kw):
-        self._format = kw.get('date_format', settings.DATETIME_FORMAT)
-        super(DateColumn, self).__init__(**kw)
-
-    def render(self, value):
-        return filters.date(value, self._format)
-
-
-def pklink(record):
-    job_id = record.pk
-    try:
-        if record.sub_id:
-            job_id = record.sub_id
-    except:
-        pass
-    return mark_safe(
-        '<a href="%s">%s</a>' % (
-            record.get_absolute_url(),
-            escape(job_id)))
-
-
-class IDLinkColumn(Column):
-
-    def __init__(self, verbose_name="ID", **kw):
-        kw['verbose_name'] = verbose_name
-        super(IDLinkColumn, self).__init__(**kw)
-
-    def render(self, record):
-        return pklink(record)
-
-
-class RestrictedIDLinkColumn(IDLinkColumn):
-
-    def render(self, record, table):
-        if record.is_accessible_by(table.context.get('request').user):
-            return pklink(record)
-        else:
-            return record.pk
-
-
-def all_jobs_with_device_sort():
-    jobs = TestJob.objects.select_related("actual_device", "requested_device",
-                                          "requested_device_type", "submitter", "user", "group")\
-        .extra(select={'device_sort': 'coalesce(actual_device_id, '
-                                      'requested_device_id, requested_device_type_id)'}).all()
-    return jobs.order_by('submit_time')
-
-
-class JobTable(DataTablesTable):
-
-    def render_device(self, record):
-        if record.actual_device:
-            return pklink(record.actual_device)
-        elif record.requested_device:
-            return pklink(record.requested_device)
-        else:
-            return mark_safe(
-                '<i>' + escape(record.requested_device_type.pk) + '</i>')
-
-    def render_description(self, value):
-        if value:
-            return value
-        else:
-            return ''
-
-    sub_id = RestrictedIDLinkColumn()
-    status = Column()
-    priority = Column()
-    device = Column(accessor='device_sort')
-    description = Column(attrs=Attrs(width="30%"))
-    submitter = Column()
-    submit_time = DateColumn()
-    end_time = DateColumn()
-    duration = Column()
-
-    datatable_opts = {
-        'aaSorting': [[6, 'desc']],
-    }
-    searchable_columns = ['description']
-
-
-class IndexJobTable(JobTable):
-    def get_queryset(self):
-        return all_jobs_with_device_sort()\
-            .filter(status__in=[TestJob.SUBMITTED, TestJob.RUNNING])
-
-    class Meta:
-        exclude = ('end_time',)
-
-
-def index_active_jobs_json(request):
-    return IndexJobTable.json(request)
-
-
-class DeviceTable(DataTablesTable):
-
-    def get_queryset(self):
-        return Device.objects.select_related("device_type")
-
-    hostname = IDLinkColumn("hostname")
-    device_type = Column()
-    status = Column()
-    health_status = Column()
-
-    searchable_columns = ['hostname']
-
-
-def index_devices_json(request):
-    return DeviceTable.json(request)
-
-
-def health_jobs_in_hr(hr=-24):
-    return TestJob.objects.filter(health_check=True,
-                                  start_time__gte=(datetime.datetime.now() +
-                                                   relativedelta(hours=hr)))\
-        .exclude(status__in=[TestJob.SUBMITTED, TestJob.RUNNING])
-
-
-def _online_total():
-    """ returns a tuple of (num_online, num_not_retired) """
-    r = Device.objects.all().values('status').annotate(count=Count('status'))
-    offline = total = 0
-    for res in r:
-        if res['status'] in [Device.OFFLINE, Device.OFFLINING]:
-            offline += res['count']
-        if res['status'] != Device.RETIRED:
-            total += res['count']
-
-    return total - offline, total
-
-
-@BreadCrumb("Scheduler", parent=lava_index)
-def index(request):
-    return render_to_response(
-        "lava_scheduler_app/index.html",
-        {
-            'device_status': "%d/%d" % _online_total(),
-            'health_check_status': "%s/%s" % (
-                health_jobs_in_hr().filter(status=TestJob.COMPLETE).count(),
-                health_jobs_in_hr().count()),
-            'device_type_table': DeviceTypeTable('devicetype', reverse(device_type_json)),
-            'devices_table': DeviceTable('devices', reverse(index_devices_json)),
-            'active_jobs_table': IndexJobTable(
-                'active_jobs', reverse(index_active_jobs_json)),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(index),
-        },
-        RequestContext(request))
-
-
-def job_report(start_day, end_day, health_check):
-    now = datetime.datetime.now()
-    start_date = now + datetime.timedelta(start_day)
-    end_date = now + datetime.timedelta(end_day)
-
-    res = TestJob.objects.filter(health_check=health_check,
-                                 start_time__range=(start_date, end_date),
-                                 status__in=(TestJob.COMPLETE, TestJob.INCOMPLETE,
-                                             TestJob.CANCELED, TestJob.CANCELING),).values('status')
-    url = reverse('lava.scheduler.failure_report')
-    params = 'start=%s&end=%s&health_check=%d' % (start_day, end_day, health_check)
-    return {
-        'pass': res.filter(status=TestJob.COMPLETE).count(),
-        'fail': res.exclude(status=TestJob.COMPLETE).count(),
-        'date': start_date.strftime('%m-%d'),
-        'failure_url': '%s?%s' % (url, params),
-    }
-
-
-@BreadCrumb("Reports", parent=lava_index)
-def reports(request):
-    health_day_report = []
-    health_week_report = []
-    job_day_report = []
-    job_week_report = []
-    for day in reversed(range(7)):
-        health_day_report.append(job_report(day * -1 - 1, day * -1, True))
-        job_day_report.append(job_report(day * -1 - 1, day * -1, False))
-    for week in reversed(range(10)):
-        health_week_report.append(job_report(week * -7 - 7, week * -7, True))
-        job_week_report.append(job_report(week * -7 - 7, week * -7, False))
-
-    long_running = TestJob.objects.filter(status__in=[TestJob.RUNNING,
-                                                      TestJob.CANCELING]).order_by('start_time')[:5]
-
-    return render_to_response(
-        "lava_scheduler_app/reports.html",
-        {
-            'health_week_report': health_week_report,
-            'health_day_report': health_day_report,
-            'job_week_report': job_week_report,
-            'job_day_report': job_day_report,
-            'long_running': long_running,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(index),
-        },
-        RequestContext(request))
-
-
-class TagsColumn(Column):
-
-    def render(self, value):
-        return ', '.join([x.name for x in value.all()])
-
-
-class FailedJobTable(JobTable):
-    failure_tags = TagsColumn()
-    failure_comment = Column()
-
-    def get_queryset(self, request):
-        failures = [TestJob.INCOMPLETE, TestJob.CANCELED, TestJob.CANCELING]
-        jobs = TestJob.objects.filter(status__in=failures)
-
-        health = request.GET.get('health_check', None)
-        if health:
-            jobs = jobs.filter(health_check=_str_to_bool(health))
-
-        dt = request.GET.get('device_type', None)
-        if dt:
-            jobs = jobs.filter(actual_device__device_type__name=dt)
-
-        device = request.GET.get('device', None)
-        if device:
-            jobs = jobs.filter(actual_device__hostname=device)
-
-        start = request.GET.get('start', None)
-        if start:
-            now = datetime.datetime.now()
-            start = now + datetime.timedelta(int(start))
-
-            end = request.GET.get('end', None)
-            if end:
-                end = now + datetime.timedelta(int(end))
-                jobs = jobs.filter(start_time__range=(start, end))
-        return jobs
-
-    class Meta:
-        exclude = ('status', 'submitter', 'end_time', 'priority', 'description')
-
-    datatable_opts = {
-        'aaSorting': [[2, 'desc']],
-    }
-
-
-def failed_jobs_json(request):
-    return FailedJobTable.json(request, params=(request,))
-
-
-def _str_to_bool(string):
-    return string.lower() in ['1', 'true', 'yes']
-
-
-@BreadCrumb("Failure Report", parent=reports)
-def failure_report(request):
-    return render_to_response(
-        "lava_scheduler_app/failure_report.html",
-        {
-            'failed_job_table': FailedJobTable(
-                'failure_report',
-                reverse(failed_jobs_json),
-                params=(request,)
-            ),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(reports),
-        },
-        RequestContext(request))
-
-
-@BreadCrumb("All Devices", parent=index)
-def device_list(request):
-    return render_to_response(
-        "lava_scheduler_app/alldevices.html",
-        {
-            'devices_table': DeviceTable('devices', reverse(index_devices_json)),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(device_list),
-        },
-        RequestContext(request))
-
-
-def get_restricted_job(user, pk):
-    job = get_object_or_404(TestJob.objects, pk=pk)
-    if not job.is_accessible_by(user):
-        raise PermissionDenied()
-    return job
-
-
-class SumIfSQL(models.sql.aggregates.Aggregate):
-    is_ordinal = True
-    sql_function = 'SUM'
-    sql_template = 'SUM((%(condition)s)::int)'
-
-
-class SumIf(models.Aggregate):
-    name = 'SumIf'
-
-    def add_to_query(self, query, alias, col, source, is_summary):
-        aggregate = SumIfSQL(col,
-                             source=source, is_summary=is_summary, **self.extra)
-        query.aggregates[alias] = aggregate
-
-
-class DeviceTypeTable(DataTablesTable):
-
-    def get_queryset(self):
-        return DeviceType.objects.filter(display=True)\
-            .annotate(idle=SumIf('device', condition='status=%s' % Device.IDLE),
-                      offline=SumIf('device', condition='status in (%s,%s)' %
-                                                        (Device.OFFLINE, Device.OFFLINING)),
-                      busy=SumIf('device', condition='status in (%s,%s)' %
-                                                     (Device.RUNNING, Device.RESERVED)),).order_by('name')
-
-    def render_status(self, record):
-        return "%s idle, %s offline, %s busy" % (record.idle,
-                                                 record.offline, record.busy)
-
-    datatable_opts = {
-        "iDisplayLength": 25
-    }
-
-    name = IDLinkColumn("name")
-    status = Column()
-
-    searchable_columns = ['name']
-
-
-class HealthJobSummaryTable(DataTablesTable):
-    """
-    The Table will return 1 day, 1 week, 1 month offset health job count.
-    The value is defined when table instance is created in device_type_detail()
-    """
-
-    def render_Duration(self, record):
-        matrix = {-24: "24hours", -24 * 7: "Week", -24 * 7 * 30: "Month"}
-        return matrix[record]
-
-    def render_Complete(self, record):
-        device_type = self.params[0]
-        num = health_jobs_in_hr(record).filter(actual_device__in=Device.objects.filter(device_type=device_type),
-                                               status=TestJob.COMPLETE).count()
-        return num
-
-    def render_Failed(self, record):
-        device_type = self.params[0]
-        num = health_jobs_in_hr(record).filter(actual_device__in=Device.objects.filter(device_type=device_type),
-                                               status__in=[TestJob.INCOMPLETE,
-                                                           TestJob.CANCELED, TestJob.CANCELING]).count()
-        return num
-
-    Duration = Column()
-    Complete = Column()
-    Failed = Column()
-
-
-def device_type_json(request):
-    return DeviceTypeTable.json(request)
-
-
-class NoDTDeviceTable(DeviceTable):
-    def get_queryset(self, device_type):
-        return Device.objects.filter(device_type=device_type)
-
-    class Meta:
-        exclude = ('device_type',)
-
-
-def index_nodt_devices_json(request, pk):
-    device_type = get_object_or_404(DeviceType, pk=pk)
-    return NoDTDeviceTable.json(request, params=(device_type,))
-
-
-@BreadCrumb("Device Type {pk}", parent=index, needs=['pk'])
-def device_type_detail(request, pk):
-    dt = get_object_or_404(DeviceType, pk=pk)
-    return render_to_response(
-        "lava_scheduler_app/device_type.html",
-        {
-            'device_type': dt,
-            'running_jobs_num': TestJob.objects.filter(
-                actual_device__in=Device.objects.filter(device_type=dt),
-                status=TestJob.RUNNING).count(),
-            'queued_jobs_num': TestJob.objects.filter(
-                Q(status=TestJob.SUBMITTED), Q(requested_device_type=dt)
-                | Q(requested_device__in=Device.objects.filter(device_type=dt))).count(),
-            # data return 1 day, 1 week, 1 month offset
-            'health_job_summary_table': HealthJobSummaryTable('device_type',
-                                                              params=(dt,), data=[-24, -24 * 7, -24 * 7 * 30]),
-            'devices_table_no_dt': NoDTDeviceTable('devices', reverse(index_nodt_devices_json,
-                                                                      kwargs=dict(pk=pk)), params=(dt,)),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(device_type_detail, pk=pk),
-        },
-        RequestContext(request))
-
-
-class DeviceHealthTable(DataTablesTable):
-
-    def get_queryset(self):
-        return Device.objects.select_related(
-            "hostname", "last_health_report_job")
-
-    def render_hostname(self, record):
-        return mark_safe('<a href="%s">%s</a>' % (
-            record.get_device_health_url(), escape(record.pk)))
-
-    def render_last_health_report_job(self, record):
-        report = record.last_health_report_job
-        if report is None:
-            return ''
-        else:
-            return pklink(report)
-
-    hostname = Column("hostname")
-    health_status = Column()
-    last_report_time = DateColumn(
-        verbose_name="last report time",
-        accessor="last_health_report_job.end_time")
-    last_health_report_job = Column("last report job")
-
-    searchable_columns = ['hostname']
-    datatable_opts = {
-        "iDisplayLength": 25
-    }
-
-
-def lab_health_json(request):
-    return DeviceHealthTable.json(request)
-
-
-@BreadCrumb("All Device Health", parent=index)
-def lab_health(request):
-    return render_to_response(
-        "lava_scheduler_app/labhealth.html",
-        {
-            'device_health_table': DeviceHealthTable(
-                'device_health', reverse(lab_health_json)),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(lab_health),
-        },
-        RequestContext(request))
-
-
-class HealthJobTable(JobTable):
-
-    def get_queryset(self, device):
-        return TestJob.objects.select_related("submitter",)\
-            .filter(actual_device=device, health_check=True)
-
-    class Meta:
-        exclude = ('description', 'device')
-
-    datatable_opts = {
-        'aaSorting': [[4, 'desc']],
-    }
-
-
-def health_jobs_json(request, pk):
-    device = get_object_or_404(Device, pk=pk)
-    return HealthJobTable.json(params=(device,))
-
-
-@BreadCrumb("All Health Jobs on Device {pk}", parent=index, needs=['pk'])
-def health_job_list(request, pk):
-    device = get_object_or_404(Device, pk=pk)
-
-    return render_to_response(
-        "lava_scheduler_app/health_jobs.html",
-        {
-            'device': device,
-            'transition_table': DeviceTransitionTable(
-                'transitions', reverse(transition_json, kwargs=dict(pk=device.pk)),
-                params=(device,)),
-            'health_job_table': HealthJobTable(
-                'health_jobs', reverse(health_jobs_json, kwargs=dict(pk=pk)),
-                params=(device,)),
-            'show_maintenance': device.can_admin(request.user) and
-            device.status in [Device.IDLE, Device.RUNNING, Device.RESERVED],
-            'show_online': device.can_admin(request.user) and
-            device.status in [Device.OFFLINE, Device.OFFLINING],
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(health_job_list, pk=pk),
-        },
-        RequestContext(request))
-
-
-class AllJobsTable(JobTable):
-
-    def get_queryset(self):
-        return all_jobs_with_device_sort()
-
-    datatable_opts = JobTable.datatable_opts.copy()
-
-    datatable_opts.update({
-        'iDisplayLength': 25,
-    })
-
-
-def alljobs_json(request):
-    return AllJobsTable.json(request)
-
-
-@BreadCrumb("All Jobs", parent=index)
-def job_list(request):
-    return render_to_response(
-        "lava_scheduler_app/alljobs.html",
-        {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(job_list),
-            'alljobs_table': AllJobsTable('alljobs', reverse(alljobs_json)),
-        },
-        RequestContext(request))
-
-
-@BreadCrumb("Submit Job", parent=index)
-def job_submit(request):
-
-    is_authorized = False
-    if request.user and request.user.has_perm(
-            'lava_scheduler_app.add_testjob'):
-        is_authorized = True
-
-    response_data = {
-        'is_authorized': is_authorized,
-        'bread_crumb_trail': BreadCrumbTrail.leading_to(job_submit),
-    }
-
-    if request.method == "POST" and is_authorized:
-        if request.is_ajax():
-            try:
-                validate_job_json(request.POST.get("json-input"))
-                return HttpResponse(simplejson.dumps("success"))
-            except Exception as e:
-                return HttpResponse(simplejson.dumps(str(e)),
-                                    mimetype="application/json")
-
-        else:
-            try:
-                job = TestJob.from_json_and_user(
-                    request.POST.get("json-input"), request.user)
-
-                if isinstance(job, type(list())):
-                    response_data["job_list"] = job
-                else:
-                    response_data["job_id"] = job.id
-                return render_to_response(
-                    "lava_scheduler_app/job_submit.html",
-                    response_data, RequestContext(request))
-
-            except (JSONDataError, ValueError, DevicesUnavailableException) \
-                    as e:
-                response_data["error"] = str(e)
-                response_data["json_input"] = request.POST.get("json-input")
-                return render_to_response(
-                    "lava_scheduler_app/job_submit.html",
-                    response_data, RequestContext(request))
-
-    else:
-        return render_to_response(
-            "lava_scheduler_app/job_submit.html",
-            response_data, RequestContext(request))
-
-
-@BreadCrumb("Job #{pk}", parent=index, needs=['pk'])
-def job_detail(request, pk):
-    job = get_restricted_job(request.user, pk)
-
-    data = {
-        'job': job,
-        'show_cancel': job.can_cancel(request.user),
-        'show_failure': job.can_annotate(request.user),
-        'show_resubmit': job.can_resubmit(request.user),
-        'bread_crumb_trail': BreadCrumbTrail.leading_to(job_detail, pk=pk),
-        'show_reload_page': job.status <= TestJob.RUNNING,
-    }
-
-    log_file = job.output_file()
-
-    if log_file:
-        job_errors = getDispatcherErrors(job.output_file())
-        job_log_messages = getDispatcherLogMessages(job.output_file())
-
-        levels = defaultdict(int)
-        for kl in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
-            levels[kl] = 0
-        for level, msg, _ in job_log_messages:
-            levels[level] += 1
-        levels = sorted(levels.items(), key=lambda (k, v): logging._levelNames.get(k))
-        with job.output_file() as f:
-            f.seek(0, 2)
-            job_file_size = f.tell()
-        data.update({
-            'job_file_present': True,
-            'job_errors': job_errors,
-            'job_has_error': len(job_errors) > 0,
-            'job_log_messages': job_log_messages,
-            'levels': levels,
-            'job_file_size': job_file_size,
-        })
-    else:
-        data.update({
-            'job_file_present': False,
-        })
-
-    return render_to_response(
-        "lava_scheduler_app/job.html", data, RequestContext(request))
-
-
-def job_definition(request, pk):
-    job = get_restricted_job(request.user, pk)
-    log_file = job.output_file()
-    return render_to_response(
-        "lava_scheduler_app/job_definition.html",
-        {
-            'job': job,
-            'job_file_present': bool(log_file),
-        },
-        RequestContext(request))
-
-
-def job_definition_plain(request, pk):
-    job = get_restricted_job(request.user, pk)
-    response = HttpResponse(job.definition, mimetype='text/plain')
-    response['Content-Disposition'] = "attachment; filename=job_%d.json" % job.id
-    return response
-
-
-def multinode_job_definition(request, pk):
-    job = get_restricted_job(request.user, pk)
-    log_file = job.output_file()
-    return render_to_response(
-        "lava_scheduler_app/multinode_job_definition.html",
-        {
-            'job': job,
-            'job_file_present': bool(log_file),
-        },
-        RequestContext(request))
-
-
-def multinode_job_definition_plain(request, pk):
-    job = get_restricted_job(request.user, pk)
-    response = HttpResponse(job.multinode_definition, mimetype='text/plain')
-    response['Content-Disposition'] = "attachment; filename=multinode_job_%d.json" % job.id
-    return response
-
-
-@BreadCrumb("Complete log", parent=job_detail, needs=['pk'])
-def job_log_file(request, pk):
-    job = get_restricted_job(request.user, pk)
-    content = formatLogFile(job.output_file())
-    with job.output_file() as f:
-        f.seek(0, 2)
-        job_file_size = f.tell()
-    return render_to_response(
-        "lava_scheduler_app/job_log_file.html",
-        {
-            'job': TestJob.objects.get(pk=pk),
-            'job_file_present': bool(job.output_file()),
-            'sections': content,
-            'job_file_size': job_file_size,
-        },
-        RequestContext(request))
-
-
-def job_log_file_plain(request, pk):
-    job = get_restricted_job(request.user, pk)
-    response = HttpResponse(job.output_file(), mimetype='text/plain')
-    response['Content-Disposition'] = "attachment; filename=job_%d.log" % job.id
-    return response
-
-
-def job_log_incremental(request, pk):
-    start = int(request.GET.get('start', 0))
-    job = get_restricted_job(request.user, pk)
-    log_file = job.output_file()
-    log_file.seek(start)
-    new_content = log_file.read()
-    m = getDispatcherLogMessages(StringIO.StringIO(new_content))
-    response = HttpResponse(
-        simplejson.dumps(m), content_type='application/json')
-    response['X-Current-Size'] = str(start + len(new_content))
-    if job.status not in [TestJob.RUNNING, TestJob.CANCELING]:
-        response['X-Is-Finished'] = '1'
-    return response
-
-
-def job_full_log_incremental(request, pk):
-    start = int(request.GET.get('start', 0))
-    job = get_restricted_job(request.user, pk)
-    log_file = job.output_file()
-    log_file.seek(start)
-    new_content = log_file.read()
-    nl_index = new_content.rfind('\n', -NEWLINE_SCAN_SIZE)
-    if nl_index >= 0:
-        new_content = new_content[:nl_index + 1]
-    m = formatLogFile(StringIO.StringIO(new_content))
-    response = HttpResponse(
-        simplejson.dumps(m), content_type='application/json')
-    response['X-Current-Size'] = str(start + len(new_content))
-    if job.status not in [TestJob.RUNNING, TestJob.CANCELING]:
-        response['X-Is-Finished'] = '1'
-    return response
-
-
-LOG_CHUNK_SIZE = 512 * 1024
-NEWLINE_SCAN_SIZE = 80
-
-
-def job_output(request, pk):
-    start = request.GET.get('start', 0)
-    try:
-        start = int(start)
-    except ValueError:
-        return HttpResponseBadRequest("invalid start")
-    count_present = 'count' in request.GET
-    job = get_restricted_job(request.user, pk)
-    log_file = job.output_file()
-    log_file.seek(0, os.SEEK_END)
-    size = int(request.GET.get('count', log_file.tell()))
-    if size - start > LOG_CHUNK_SIZE and not count_present:
-        log_file.seek(-LOG_CHUNK_SIZE, os.SEEK_END)
-        content = log_file.read(LOG_CHUNK_SIZE)
-        nl_index = content.find('\n', 0, NEWLINE_SCAN_SIZE)
-        if nl_index > 0 and not count_present:
-            content = content[nl_index + 1:]
-        skipped = size - start - len(content)
-    else:
-        skipped = 0
-        log_file.seek(start, os.SEEK_SET)
-        content = log_file.read(size - start)
-    nl_index = content.rfind('\n', -NEWLINE_SCAN_SIZE)
-    if nl_index >= 0 and not count_present:
-        content = content[:nl_index + 1]
-    response = HttpResponse(content)
-    if skipped:
-        response['X-Skipped-Bytes'] = str(skipped)
-    response['X-Current-Size'] = str(start + len(content))
-    if job.status not in [TestJob.RUNNING, TestJob.CANCELING]:
-        response['X-Is-Finished'] = '1'
-    return response
-
-
-@post_only
-def job_cancel(request, pk):
-    job = get_restricted_job(request.user, pk)
-    if job.can_cancel(request.user):
-        if job.is_multinode:
-            multinode_jobs = TestJob.objects.all().filter(
-                target_group=job.target_group)
-            for multinode_job in multinode_jobs:
-                multinode_job.cancel()
-        else:
-            job.cancel()
-        return redirect(job)
-    else:
-        return HttpResponseForbidden(
-            "you cannot cancel this job", content_type="text/plain")
-
-
-@post_only
-def job_resubmit(request, pk):
-
-    response_data = {
-        'is_authorized': False,
-        'bread_crumb_trail': BreadCrumbTrail.leading_to(job_list),
-        }
-
-    job = get_restricted_job(request.user, pk)
-    if job.can_resubmit(request.user):
-        response_data["is_authorized"] = True
-
-        if job.is_multinode:
-            definition = job.multinode_definition
-        else:
-            definition = job.definition
-
-        try:
-            job = TestJob.from_json_and_user(definition, request.user)
-
-            if isinstance(job, type(list())):
-                response_data["job_list"] = job
-                return render_to_response(
-                    "lava_scheduler_app/job_submit.html",
-                    response_data, RequestContext(request))
-            else:
-                return redirect(job)
-        except (JSONDataError, ValueError, DevicesUnavailableException) as e:
-            response_data["error"] = str(e)
-            response_data["json_input"] = definition
-            return render_to_response(
-                "lava_scheduler_app/job_submit.html",
-                response_data, RequestContext(request))
-
-    else:
-        return HttpResponseForbidden(
-            "you cannot re-submit this job", content_type="text/plain")
-
-
-class FailureForm(forms.ModelForm):
-    class Meta:
-        model = TestJob
-        fields = ('failure_tags', 'failure_comment')
-
-
-def job_annotate_failure(request, pk):
-    job = get_restricted_job(request.user, pk)
-    if not job.can_annotate(request.user):
-        raise PermissionDenied()
-
-    if request.method == 'POST':
-        form = FailureForm(request.POST, instance=job)
-        if form.is_valid():
-            form.save()
-            return redirect(job)
-    else:
-        form = FailureForm(instance=job)
-
-    return render_to_response(
-        "lava_scheduler_app/job_annotate_failure.html",
-        {
-            'form': form,
-            'job': job,
-        },
-        RequestContext(request))
-
-
-def job_json(request, pk):
-    job = get_restricted_job(request.user, pk)
-    json_text = simplejson.dumps({
-        'status': job.get_status_display(),
-        'results_link': request.build_absolute_uri(job.results_link),
-    })
-    content_type = 'application/json'
-    if 'callback' in request.GET:
-        json_text = '%s(%s)' % (request.GET['callback'], json_text)
-        content_type = 'text/javascript'
-    return HttpResponse(json_text, content_type=content_type)
-
-
-@post_only
-def get_remote_json(request):
-    """Fetches remote json file."""
-    url = request.POST.get("url")
-
-    try:
-        data = urllib2.urlopen(url).read()
-        # Validate that the data at the location is really JSON.
-        # This is security based check so noone can misuse this url.
-        simplejson.loads(data)
-    except Exception as e:
-        return HttpResponse(simplejson.dumps(str(e)),
-                            mimetype="application/json")
-
-    return HttpResponse(data)
-
-
-class RecentJobsTable(JobTable):
-
-    def get_queryset(self, device):
-        return device.recent_jobs()
-
-    class Meta:
-        exclude = ('device',)
-
-
-def recent_jobs_json(request, pk):
-    device = get_object_or_404(Device, pk=pk)
-    return RecentJobsTable.json(request, params=(device,))
-
-
-class DeviceTransitionTable(DataTablesTable):
-
-    def get_queryset(self, device):
-        qs = device.transitions.select_related('created_by')
-        qs = qs.extra(select={'prev': """
-        select t.created_on
-          from lava_scheduler_app_devicestatetransition as t
-         where t.device_id=%s and t.created_on < lava_scheduler_app_devicestatetransition.created_on
-         order by t.created_on desc
-         limit 1 """},
-                      select_params=[device.pk])
-        return qs
-
-    def render_created_on(self, record):
-        t = record
-        base = filters.date(t.created_on, "Y-m-d H:i")
-        if t.prev:
-            base += ' (after %s)' % (filters.timesince(t.prev, t.created_on))
-        return base
-
-    def render_transition(self, record):
-        t = record
-        return mark_safe(
-            '%s &rarr; %s' % (t.get_old_state_display(), t.get_new_state_display(),))
-
-    def render_message(self, value):
-        if value is None:
-            return ''
-        else:
-            return value
-
-    created_on = Column('when', attrs=Attrs(width="40%"))
-    transition = Column('transition', sortable=False)
-    created_by = Column('by')
-    message = Column('reason')
-
-    datatable_opts = {
-        'aaSorting': [[0, 'desc']],
-    }
-
-
-def transition_json(request, pk):
-    device = get_object_or_404(Device, pk=pk)
-    return DeviceTransitionTable.json(request, params=(device,))
-
-
-@BreadCrumb("Device {pk}", parent=index, needs=['pk'])
-def device_detail(request, pk):
-    device = get_object_or_404(Device, pk=pk)
-    if device.status in [Device.OFFLINE, Device.OFFLINING]:
-        try:
-            transition = device.transitions.filter(message__isnull=False).latest('created_on').message
-        except DeviceStateTransition.DoesNotExist:
-            transition = None
-    else:
-        transition = None
-    return render_to_response(
-        "lava_scheduler_app/device.html",
-        {
-            'device': device,
-            'transition': transition,
-            'transition_table': DeviceTransitionTable(
-                'transitions', reverse(transition_json, kwargs=dict(pk=device.pk)),
-                params=(device,)),
-            'recent_job_table': RecentJobsTable(
-                'jobs', reverse(recent_jobs_json, kwargs=dict(pk=device.pk)),
-                params=(device,)),
-            'show_maintenance': device.can_admin(request.user) and
-            device.status in [Device.IDLE, Device.RUNNING, Device.RESERVED],
-            'show_online': device.can_admin(request.user) and
-            device.status in [Device.OFFLINE, Device.OFFLINING],
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(device_detail, pk=pk),
-        },
-        RequestContext(request))
-
-
-@post_only
-def device_maintenance_mode(request, pk):
-    device = Device.objects.get(pk=pk)
-    if device.can_admin(request.user):
-        device.put_into_maintenance_mode(request.user, request.POST.get('reason'))
-        return redirect(device)
-    else:
-        return HttpResponseForbidden(
-            "you cannot administer this device", content_type="text/plain")
-
-
-@post_only
-def device_online(request, pk):
-    device = Device.objects.get(pk=pk)
-    if device.can_admin(request.user):
-        device.put_into_online_mode(request.user, request.POST.get('reason'))
-        return redirect(device)
-    else:
-        return HttpResponseForbidden(
-            "you cannot administer this device", content_type="text/plain")
-
-
-@post_only
-def device_looping_mode(request, pk):
-    device = Device.objects.get(pk=pk)
-    if device.can_admin(request.user):
-        device.put_into_looping_mode(request.user)
-        return redirect(device)
-    else:
-        return HttpResponseForbidden(
-            "you cannot administer this device", content_type="text/plain")

=== removed directory 'lava_scheduler_daemon'
=== removed file 'lava_scheduler_daemon/__init__.py'
=== removed file 'lava_scheduler_daemon/config.py'
--- lava_scheduler_daemon/config.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_daemon/config.py	1970-01-01 00:00:00 +0000
@@ -1,36 +0,0 @@
-from ConfigParser import ConfigParser
-import os
-from StringIO import StringIO
-
-#from xdg.BaseDirectory import load_config_paths
-
-defaults = {
-    'logging': StringIO(
-    '''
-[logging]
-level = INFO
-destination = -
-'''),
-}
-
-
-# python xdg isn't installable via pip, so...
-def load_config_paths(name):
-    for directory in os.path.expanduser("~/.config"), '/etc/xdg':
-        path = os.path.join(directory, name)
-        if os.path.isdir(path):
-            yield path
-
-
-def get_config(name):
-    config_files = []
-    for directory in load_config_paths('lava-scheduler'):
-        path = os.path.join(directory, '%s.conf' % name)
-        if os.path.exists(path):
-            config_files.append(path)
-    config_files.reverse()
-    fp = ConfigParser()
-    if name in defaults:
-        fp.readfp(defaults[name])
-    fp.read(config_files)
-    return fp

=== removed file 'lava_scheduler_daemon/dbjobsource.py'
--- lava_scheduler_daemon/dbjobsource.py	2013-09-02 18:14:25 +0000
+++ lava_scheduler_daemon/dbjobsource.py	1970-01-01 00:00:00 +0000
@@ -1,412 +0,0 @@
-import datetime
-import logging
-import os
-import shutil
-import urlparse
-import copy
-
-from dashboard_app.models import Bundle
-
-from django.contrib.auth.models import User
-from django.core.files.base import ContentFile
-from django.db import connection
-from django.db import IntegrityError, transaction
-from django.db.models import Q
-from django.db.utils import DatabaseError
-
-from linaro_django_xmlrpc.models import AuthToken
-
-import simplejson
-
-from twisted.internet.threads import deferToThread
-
-from zope.interface import implements
-
-import lava_dispatcher.config as dispatcher_config
-
-from lava_scheduler_app.models import (
-    Device,
-    DeviceStateTransition,
-    JSONDataError,
-    TestJob)
-from lava_scheduler_daemon.jobsource import IJobSource
-
-
-try:
-    from psycopg2 import InterfaceError, OperationalError
-except ImportError:
-    class InterfaceError(Exception):
-        pass
-
-    class OperationalError(Exception):
-        pass
-
-
-class DatabaseJobSource(object):
-
-    implements(IJobSource)
-
-    def __init__(self):
-        self.logger = logging.getLogger(__name__ + '.DatabaseJobSource')
-
-    deferToThread = staticmethod(deferToThread)
-
-    def deferForDB(self, func, *args, **kw):
-        def wrapper(*args, **kw):
-            # If there is no db connection yet on this thread, create a
-            # connection and immediately commit, because rolling back the
-            # first transaction on a connection loses the effect of
-            # settings.TIME_ZONE when using postgres (see
-            # https://code.djangoproject.com/ticket/17062).
-            transaction.enter_transaction_management()
-            transaction.managed()
-            try:
-                if connection.connection is None:
-                    connection.cursor().close()
-                    assert connection.connection is not None
-                    transaction.commit()
-                try:
-                    return func(*args, **kw)
-                except (DatabaseError, OperationalError, InterfaceError), error:
-                    message = str(error)
-                    if message == 'connection already closed' or \
-                            message.startswith(
-                            'terminating connection due to administrator command') or \
-                            message.startswith(
-                            'could not connect to server: Connection refused'):
-                        self.logger.warning(
-                            'Forcing reconnection on next db access attempt')
-                        if connection.connection:
-                            if not connection.connection.closed:
-                                connection.connection.close()
-                            connection.connection = None
-                    raise
-            finally:
-                # In Django 1.2, the commit_manually() etc decorators only
-                # commit or rollback the transaction if Django thinks there's
-                # been a write to the database.  We don't want to leave
-                # transactions dangling under any circumstances so we
-                # unconditionally issue a rollback.  This might be a teensy
-                # bit wastful, but it wastes a lot less time than figuring out
-                # why your south migration appears to have got stuck...
-                transaction.rollback()
-                transaction.leave_transaction_management()
-        return self.deferToThread(wrapper, *args, **kw)
-
-    def _get_health_check_jobs(self):
-        """Gets the list of configured boards and checks which are the boards
-        that require health check.
-
-        Returns JOB_LIST which is a set of health check jobs. If no health
-        check jobs are available returns an empty set.
-        """
-        job_list = set()
-        configured_boards = [
-            x.hostname for x in dispatcher_config.get_devices()]
-        boards = []
-        for d in Device.objects.all():
-            if d.hostname in configured_boards:
-                boards.append(d)
-
-        for device in boards:
-            if device.status != Device.IDLE:
-                continue
-            if not device.device_type.health_check_job:
-                run_health_check = False
-            elif device.health_status == Device.HEALTH_UNKNOWN:
-                run_health_check = True
-            elif device.health_status == Device.HEALTH_LOOPING:
-                run_health_check = True
-            elif not device.last_health_report_job:
-                run_health_check = True
-            else:
-                run_health_check = device.last_health_report_job.end_time < \
-                    datetime.datetime.now() - datetime.timedelta(days=1)
-            if run_health_check:
-                job_list.add(self._getHealthCheckJobForBoard(device))
-        return job_list
-
-    def _fix_device(self, device, job):
-        """Associate an available/idle DEVICE to the given JOB.
-
-        If the MultiNode job is waiting as Submitted, the device
-        could be running a different job.
-        Returns the job with actual_device set to DEVICE.
-
-        If we are unable to grab the DEVICE then we return None.
-        """
-        if device.status == Device.RUNNING:
-            return None
-        DeviceStateTransition.objects.create(
-            created_by=None, device=device, old_state=device.status,
-            new_state=Device.RESERVED, message=None, job=job).save()
-        device.status = Device.RESERVED
-        device.current_job = job
-        try:
-            # The unique constraint on current_job may cause this to
-            # fail in the case of concurrent requests for different
-            # boards grabbing the same job.  If there are concurrent
-            # requests for the *same* board they may both return the
-            # same job -- this is an application level bug though.
-            device.save()
-        except IntegrityError:
-            self.logger.info(
-                "job %s has been assigned to another board -- rolling back",
-                job.id)
-            transaction.rollback()
-            return None
-        else:
-            job.actual_device = device
-            job.log_file.save(
-                'job-%s.log' % job.id, ContentFile(''), save=False)
-            job.submit_token = AuthToken.objects.create(user=job.submitter)
-            job.definition = simplejson.dumps(self._get_json_data(job),
-                                              sort_keys=True,
-                                              indent=4 * ' ')
-            job.save()
-            transaction.commit()
-        return job
-
-    def getJobList_impl(self):
-        jobs = TestJob.objects.all().filter(
-            status=TestJob.SUBMITTED).order_by('-priority', 'submit_time')
-        job_list = self._get_health_check_jobs()
-        devices = None
-        configured_boards = [
-            x.hostname for x in dispatcher_config.get_devices()]
-        self.logger.debug("Number of configured_devices: %d" % len(configured_boards))
-        for job in jobs:
-            if job.actual_device:
-                job_list.add(job)
-            elif job.requested_device:
-                self.logger.debug("Checking Requested Device")
-                devices = Device.objects.all().filter(
-                    hostname=job.requested_device.hostname,
-                    status=Device.IDLE)
-            elif job.requested_device_type:
-                self.logger.debug("Checking Requested Device Type")
-                devices = Device.objects.all().filter(
-                    device_type=job.requested_device_type,
-                    status=Device.IDLE)
-            else:
-                continue
-            if devices:
-                for d in devices:
-                    self.logger.debug("Checking %s" % d.hostname)
-                    if d.hostname in configured_boards:
-                        if job:
-                            job = self._fix_device(d, job)
-                        if job:
-                            job_list.add(job)
-
-        # Remove scheduling multinode jobs until all the jobs in the
-        # target_group are assigned devices.
-        final_job_list = copy.deepcopy(job_list)
-        for job in job_list:
-            if job.is_multinode:
-                multinode_jobs = TestJob.objects.all().filter(
-                    target_group=job.target_group)
-
-                jobs_with_device = 0
-                for multinode_job in multinode_jobs:
-                    if multinode_job.actual_device:
-                        jobs_with_device += 1
-
-                if len(multinode_jobs) != jobs_with_device:
-                    final_job_list.difference_update(set(multinode_jobs))
-                
-        return final_job_list
-
-    def getJobList(self):
-        return self.deferForDB(self.getJobList_impl)
-
-    def _get_json_data(self, job):
-        json_data = simplejson.loads(job.definition)
-        if job.actual_device:
-            json_data['target'] = job.actual_device.hostname
-        elif job.requested_device:
-            json_data['target'] = job.requested_device.hostname
-        for action in json_data['actions']:
-            if not action['command'].startswith('submit_results'):
-                continue
-            params = action['parameters']
-            params['token'] = job.submit_token.secret
-            parsed = urlparse.urlsplit(params['server'])
-            netloc = job.submitter.username + '@' + parsed.hostname
-            if parsed.port:
-                netloc += ':' + str(parsed.port)
-            parsed = list(parsed)
-            parsed[1] = netloc
-            params['server'] = urlparse.urlunsplit(parsed)
-        json_data['health_check'] = job.health_check
-        return json_data
-
-    def _getHealthCheckJobForBoard(self, device):
-        job_json = device.device_type.health_check_job
-        if not job_json:
-            # This should never happen, it's a logic error.
-            self.logger.error(
-                "no job_json in getHealthCheckJobForBoard for %r", device)
-            device.put_into_maintenance_mode(
-                None, "no job_json in getHealthCheckJobForBoard")
-            return None
-        else:
-            user = User.objects.get(username='lava-health')
-            job_data = simplejson.loads(job_json)
-            job_data['target'] = device.hostname
-            job_json = simplejson.dumps(job_data)
-            try:
-                return TestJob.from_json_and_user(job_json, user, True)
-            except (JSONDataError, ValueError) as e:
-                self.logger.exception(
-                    "TestJob.from_json_and_user failed in _getHealthCheckJobForBoard")
-                device.put_into_maintenance_mode(
-                    None, "TestJob.from_json_and_user failed for health job: %s" % e)
-                return None
-
-    def _getJobFromQueue(self, device):
-        jobs_for_device = TestJob.objects.all().filter(
-            Q(requested_device=device)
-            | Q(requested_device_type=device.device_type),
-            status=TestJob.SUBMITTED)
-        jobs_for_device = jobs_for_device.extra(
-            select={
-                'is_targeted': 'requested_device_id is not NULL',
-            },
-            where=[
-                # In human language, this is saying "where the number of
-                # tags that are on the job but not on the device is 0"
-                '''(select count(*) from lava_scheduler_app_testjob_tags
-                     where testjob_id = lava_scheduler_app_testjob.id
-                       and tag_id not in (select tag_id
-                                            from lava_scheduler_app_device_tags
-                                           where device_id = '%s')) = 0'''
-                % device.hostname,
-            ],
-            order_by=['-is_targeted', '-priority', 'submit_time'])
-        jobs = jobs_for_device[:1]
-        if jobs:
-            return jobs[0]
-        else:
-            return None
-
-    def getJobDetails_impl(self, job):
-        job.status = TestJob.RUNNING
-        # need to set the device RUNNING if device was RESERVED
-        if job.actual_device.status == Device.RESERVED:
-            DeviceStateTransition.objects.create(
-                created_by=None, device=job.actual_device, old_state=job.actual_device.status,
-                new_state=Device.RUNNING, message=None, job=job).save()
-            job.actual_device.status = Device.RUNNING
-            job.actual_device.current_job = job
-            job.actual_device.save()
-        job.start_time = datetime.datetime.utcnow()
-        shutil.rmtree(job.output_dir, ignore_errors=True)
-        job.log_file.save('job-%s.log' % job.id, ContentFile(''), save=False)
-        job.submit_token = AuthToken.objects.create(user=job.submitter)
-        job.save()
-        json_data = self._get_json_data(job)
-        transaction.commit()
-        return json_data
-
-    def getJobDetails(self, job):
-        return self.deferForDB(self.getJobDetails_impl, job)
-
-    def getOutputDirForJobOnBoard_impl(self, board_name):
-        device = Device.objects.get(hostname=board_name)
-        job = device.current_job
-        return job.output_dir
-
-    def getOutputDirForJobOnBoard(self, board_name):
-        return self.deferForDB(self.getOutputDirForJobOnBoard_impl, board_name)
-
-    def jobCompleted_impl(self, board_name, exit_code, kill_reason):
-        self.logger.debug('marking job as complete on %s', board_name)
-        device = Device.objects.get(hostname=board_name)
-        old_device_status = device.status
-        if device.status == Device.RUNNING:
-            device.status = Device.IDLE
-        elif device.status == Device.OFFLINING:
-            device.status = Device.OFFLINE
-        elif device.status == Device.RESERVED:
-            device.status = Device.IDLE
-        else:
-            self.logger.error(
-                "Unexpected device state in jobCompleted: %s" % device.status)
-            device.status = Device.IDLE
-        job = device.current_job
-        device.device_version = _get_device_version(job.results_bundle)
-        device.current_job = None
-        if job.status == TestJob.RUNNING:
-            if exit_code == 0:
-                job.status = TestJob.COMPLETE
-            else:
-                job.status = TestJob.INCOMPLETE
-        elif job.status == TestJob.CANCELING:
-            job.status = TestJob.CANCELED
-        else:
-            self.logger.error(
-                "Unexpected job state in jobCompleted: %s" % job.status)
-            job.status = TestJob.COMPLETE
-        DeviceStateTransition.objects.create(
-            created_by=None, device=device, old_state=old_device_status,
-            new_state=device.status, message=None, job=job).save()
-
-        if job.health_check:
-            device.last_health_report_job = job
-            if device.health_status != Device.HEALTH_LOOPING:
-                if job.status == TestJob.INCOMPLETE:
-                    device.health_status = Device.HEALTH_FAIL
-                    device.put_into_maintenance_mode(None, "Health Check Job Failed")
-                elif job.status == TestJob.COMPLETE:
-                    device.health_status = Device.HEALTH_PASS
-
-        bundle_file = os.path.join(job.output_dir, 'result-bundle')
-        if os.path.exists(bundle_file):
-            with open(bundle_file) as f:
-                results_link = f.read().strip()
-            job._results_link = results_link
-            sha1 = results_link.strip('/').split('/')[-1]
-            try:
-                bundle = Bundle.objects.get(content_sha1=sha1)
-            except Bundle.DoesNotExist:
-                pass
-            else:
-                job._results_bundle = bundle
-
-        job.end_time = datetime.datetime.utcnow()
-        token = job.submit_token
-        job.submit_token = None
-        device.save()
-        job.save()
-        token.delete()
-        try:
-            job.send_summary_mails()
-        except:
-            # Better to catch all exceptions here and log it than have this
-            # method fail.
-            self.logger.exception(
-                'sending job summary mails for job %r failed', job.pk)
-        transaction.commit()
-
-    def jobCompleted(self, board_name, exit_code, kill_reason):
-        return self.deferForDB(self.jobCompleted_impl, board_name, exit_code, kill_reason)
-
-    def jobCheckForCancellation_impl(self, board_name):
-        device = Device.objects.get(hostname=board_name)
-        job = device.current_job
-        return job.status != TestJob.RUNNING
-
-    def jobCheckForCancellation(self, board_name):
-        return self.deferForDB(self.jobCheckForCancellation_impl, board_name)
-
-
-def _get_device_version(bundle):
-    if bundle is None:
-        return None
-    try:
-        lava_test_run = bundle.test_runs.filter(test__test_id='lava')[0]
-        version_attribute = lava_test_run.attributes.filter(name='target.device_version')[0]
-        return version_attribute.value
-    except IndexError:
-        return 'unknown'

=== removed file 'lava_scheduler_daemon/job.py'
--- lava_scheduler_daemon/job.py	2013-08-28 13:13:46 +0000
+++ lava_scheduler_daemon/job.py	1970-01-01 00:00:00 +0000
@@ -1,281 +0,0 @@
-# Copyright (C) 2013 Linaro Limited
-#
-# Author: Senthil Kumaran <senthil.kumaran@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-import json
-import os
-import signal
-import tempfile
-import logging
-
-from twisted.internet.error import ProcessDone, ProcessExitedAlready
-from twisted.internet.protocol import ProcessProtocol
-from twisted.internet import defer, task
-
-
-def catchall_errback(logger):
-    def eb(failure):
-        logger.error(
-            '%s: %s\n%s', failure.type.__name__, failure.value,
-            failure.getTraceback())
-    return eb
-
-
-class DispatcherProcessProtocol(ProcessProtocol):
-
-    def __init__(self, deferred, job):
-        self.logger = logging.getLogger(__name__ + '.DispatcherProcessProtocol')
-        self.deferred = deferred
-        self.log_size = 0
-        self.job = job
-
-    def childDataReceived(self, childFD, data):
-        self.log_size += len(data)
-        if self.log_size > self.job.daemon_options['LOG_FILE_SIZE_LIMIT']:
-            if not self.job._killing:
-                self.job.cancel("exceeded log size limit")
-
-    def childConnectionLost(self, childFD):
-        self.logger.info("childConnectionLost for %s: %s",
-                         self.job.board_name, childFD)
-
-    def processExited(self, reason):
-        self.logger.info("processExited for %s: %s",
-                         self.job.board_name, reason.value)
-
-    def processEnded(self, reason):
-        self.logger.info("processEnded for %s: %s",
-                         self.job.board_name, reason.value)
-        self.deferred.callback(reason.value.exitCode)
-
-
-class Job(object):
-
-    def __init__(self, job_data, dispatcher, source, board_name, reactor,
-                 daemon_options):
-        self.job_data = job_data
-        self.dispatcher = dispatcher
-        self.source = source
-        self.board_name = board_name
-        self.logger = logging.getLogger(__name__ + '.Job.' + board_name)
-        self.reactor = reactor
-        self.daemon_options = daemon_options
-        self._json_file = None
-        self._source_lock = defer.DeferredLock()
-        self._checkCancel_call = task.LoopingCall(self._checkCancel)
-        self._signals = ['SIGINT', 'SIGINT', 'SIGTERM', 'SIGTERM', 'SIGKILL']
-        self._time_limit_call = None
-        self._killing = False
-        self._kill_reason = ''
-
-    def _checkCancel(self):
-        if self._killing:
-            self.cancel()
-        else:
-            return self._source_lock.run(
-                self.source.jobCheckForCancellation,
-                self.board_name).addCallback(self._maybeCancel)
-
-    def cancel(self, reason=None):
-        if not self._killing:
-            if reason is None:
-                reason = "killing job for unknown reason"
-            self._kill_reason = reason
-            self.logger.info(reason)
-        self._killing = True
-        if self._signals:
-            signame = self._signals.pop(0)
-        else:
-            self.logger.warning("self._signals is empty!")
-            signame = 'SIGKILL'
-        self.logger.info(
-            'attempting to kill job with signal %s' % signame)
-        try:
-            self._protocol.transport.signalProcess(getattr(signal, signame))
-        except ProcessExitedAlready:
-            pass
-
-    def _maybeCancel(self, cancel):
-        if cancel:
-            self.cancel("killing job by user request")
-        else:
-            logging.debug('not cancelling')
-
-    def _time_limit_exceeded(self):
-        self._time_limit_call = None
-        self.cancel("killing job for exceeding timeout")
-
-    def run(self):
-        d = self.source.getOutputDirForJobOnBoard(self.board_name)
-        return d.addCallback(self._run).addErrback(
-            catchall_errback(self.logger))
-
-    def _run(self, output_dir):
-        d = defer.Deferred()
-        json_data = self.job_data
-        fd, self._json_file = tempfile.mkstemp()
-        with os.fdopen(fd, 'wb') as f:
-            json.dump(json_data, f)
-        self._protocol = DispatcherProcessProtocol(d, self)
-        self.reactor.spawnProcess(
-            self._protocol, self.dispatcher, args=[
-                self.dispatcher, self._json_file, '--output-dir', output_dir],
-            childFDs={0: 0, 1: 'r', 2: 'r'}, env=None)
-        self._checkCancel_call.start(10)
-        timeout = max(
-            json_data['timeout'], self.daemon_options['MIN_JOB_TIMEOUT'])
-        self._time_limit_call = self.reactor.callLater(
-            timeout, self._time_limit_exceeded)
-        d.addBoth(self._exited)
-        return d
-
-    def _exited(self, exit_code):
-        self.logger.info("job finished on %s", self.job_data['target'])
-        if self._json_file is not None:
-            os.unlink(self._json_file)
-        self.logger.info("reporting job completed")
-        if self._time_limit_call is not None:
-            self._time_limit_call.cancel()
-        self._checkCancel_call.stop()
-        return self._source_lock.run(
-            self.source.jobCompleted,
-            self.board_name,
-            exit_code,
-            self._killing).addCallback(
-                lambda r: exit_code)
-
-
-class SchedulerMonitorPP(ProcessProtocol):
-
-    def __init__(self, d, board_name):
-        self.d = d
-        self.board_name = board_name
-        self.logger = logging.getLogger(__name__ + '.SchedulerMonitorPP')
-
-    def childDataReceived(self, childFD, data):
-        self.logger.warning(
-            "scheduler monitor for %s produced output: %r on fd %s",
-            self.board_name, data, childFD)
-
-    def processEnded(self, reason):
-        if not reason.check(ProcessDone):
-            self.logger.error(
-                "scheduler monitor for %s crashed: %s",
-                self.board_name, reason)
-        self.d.callback(None)
-
-
-class MonitorJob(object):
-
-    def __init__(self, job_data, dispatcher, source, board_name, reactor,
-                 daemon_options):
-        self.logger = logging.getLogger(__name__ + '.MonitorJob')
-        self.job_data = job_data
-        self.dispatcher = dispatcher
-        self.source = source
-        self.board_name = board_name
-        self.reactor = reactor
-        self.daemon_options = daemon_options
-        self._json_file = None
-
-    def run(self):
-        d = defer.Deferred()
-        json_data = self.job_data
-        fd, self._json_file = tempfile.mkstemp()
-        with os.fdopen(fd, 'wb') as f:
-            json.dump(json_data, f)
-
-        childFDs = {0: 0, 1: 1, 2: 2}
-        args = [
-            'setsid', 'lava-server', 'manage', 'schedulermonitor',
-            self.dispatcher, str(self.board_name), self._json_file,
-            '-l', self.daemon_options['LOG_LEVEL']]
-        if self.daemon_options['LOG_FILE_PATH']:
-            args.extend(['-f', self.daemon_options['LOG_FILE_PATH']])
-            childFDs = None
-        self.logger.info('executing "%s"', ' '.join(args))
-        self.reactor.spawnProcess(
-            SchedulerMonitorPP(d, self.board_name), 'setsid',
-            childFDs=childFDs, env=None, args=args)
-        d.addBoth(self._exited)
-        return d
-
-    def _exited(self, result):
-        if self._json_file is not None:
-            os.unlink(self._json_file)
-        return result
-
-
-class JobRunner(object):
-    job_cls = MonitorJob
-
-    def __init__(self, source, job, dispatcher, reactor, daemon_options,
-                 job_cls=None):
-        self.source = source
-        self.dispatcher = dispatcher
-        self.reactor = reactor
-        self.daemon_options = daemon_options
-        self.job = job
-        if job.actual_device:
-            self.board_name = job.actual_device.hostname
-        elif job.requested_device:
-            self.board_name = job.requested_device.hostname
-        if job_cls is not None:
-            self.job_cls = job_cls
-        self.running_job = None
-        self.logger = logging.getLogger(__name__ + '.JobRunner.' + str(job.id))
-
-    def start(self):
-        self.logger.debug("processing job")
-        if self.job is None:
-            self.logger.debug("no job found for processing")
-            return
-        self.source.getJobDetails(self.job).addCallbacks(
-            self._startJob, self._ebStartJob)
-
-    def _startJob(self, job_data):
-        if job_data is None:
-            self.logger.debug("no job found")
-            return
-        self.logger.info("starting job %r", job_data)
-
-        self.running_job = self.job_cls(
-            job_data, self.dispatcher, self.source, self.board_name,
-            self.reactor, self.daemon_options)
-        d = self.running_job.run()
-        d.addCallbacks(self._cbJobFinished, self._ebJobFinished)
-
-    def _ebStartJob(self, result):
-        self.logger.error(
-            '%s: %s\n%s', result.type.__name__, result.value,
-            result.getTraceback())
-        return
-
-    def stop(self):
-        self.logger.debug("stopping")
-
-        if self.running_job is not None:
-            self.logger.debug("job running; deferring stop")
-        else:
-            self.logger.debug("stopping immediately")
-            return defer.succeed(None)
-
-    def _ebJobFinished(self, result):
-        self.logger.exception(result.value)
-
-    def _cbJobFinished(self, result):
-        self.running_job = None

=== removed file 'lava_scheduler_daemon/jobsource.py'
--- lava_scheduler_daemon/jobsource.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_daemon/jobsource.py	1970-01-01 00:00:00 +0000
@@ -1,94 +0,0 @@
-import json
-import logging
-
-from twisted.internet import defer
-
-from zope.interface import (
-    implements,
-    Interface,
-)
-
-logger = logging.getLogger(__name__)
-
-
-class IJobSource(Interface):
-
-    def getBoardList():
-        """Get the list of currently configured board names."""
-
-    def getJobForBoard(board_name):
-        """Return the json data of a job for board_name and a log file.
-
-        The job should be marked as started before it is returned.
-        """
-
-    def jobCompleted(board_name):
-        """Mark the job currently running on `board_name` as completed."""
-
-
-class DirectoryJobSource(object):
-
-    implements(IJobSource)
-
-    logger = logging.getLogger(__name__ + '.DirectoryJobSource')
-
-    def __init__(self, directory):
-        self.directory = directory
-        if not self.directory.isdir():
-            self.logger.critical("%s is not a directory", self.directory)
-            raise RuntimeError("%s must be a directory" % self.directory)
-        boards = self.directory.child('boards')
-        if not boards.isdir():
-            self.logger.critical("%s is not a directory", boards)
-            raise RuntimeError("%s must be a directory" % boards)
-        for subdir in 'incoming', 'completed', 'broken':
-            subdir = self.directory.child(subdir)
-            if not subdir.isdir():
-                subdir.createDirectory()
-        self.logger.info("starting to look for jobs in %s", self.directory)
-
-    def _getBoardList(self):
-        return self.directory.child('boards').listdir()
-
-    def getBoardList(self):
-        return defer.maybeDeferred(self._getBoardList)
-
-    def _jsons(self, kind):
-        files = self.directory.child(kind).globChildren("*.json")
-        for json_file in files:
-            yield (json.load(json_file.open()), json_file)
-
-    def _board_dir(self, board_name):
-        return self.directory.child('boards').child(board_name)
-
-    def _getJobForBoard(self, board_name):
-        self.logger.debug('getting job for %s', board_name)
-        board_dir = self._board_dir(board_name)
-        if board_dir.listdir() != []:
-            self.logger.debug('board %s busy', board_name)
-            return None
-        for json_data, json_file in self._jsons('incoming'):
-            self.logger.debug('considering %s for %s', json_file, board_name)
-            if json_data['target'] == board_name:
-                self.logger.debug('running %s on %s', json_file, board_name)
-                json_file.moveTo(board_dir.child(json_file.basename()))
-                return json_data, open('/dev/null', 'w')
-        else:
-            return None
-
-    def getJobForBoard(self, board_name):
-        return defer.maybeDeferred(self._getJobForBoard, board_name)
-
-    def _jobCompleted(self, board_name):
-        [json_file] = self._board_dir(board_name).children()
-        completed = self.directory.child('completed')
-        counter = 0
-        while True:
-            fname = '%03d%s' % (counter, json_file.basename())
-            if not completed.child(fname).exists():
-                break
-            counter += 1
-        json_file.moveTo(completed.child(fname))
-
-    def jobCompleted(self, board_name):
-        return defer.maybeDeferred(self._jobCompleted, board_name)

=== removed file 'lava_scheduler_daemon/service.py'
--- lava_scheduler_daemon/service.py	2013-09-02 18:14:53 +0000
+++ lava_scheduler_daemon/service.py	1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-# Copyright (C) 2013 Linaro Limited
-#
-# Author: Senthil Kumaran <senthil.kumaran@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-import logging
-import lava_dispatcher.config as dispatcher_config
-
-from twisted.application.service import Service
-from twisted.internet import defer
-from twisted.internet.task import LoopingCall
-
-from lava_scheduler_daemon.job import JobRunner, catchall_errback
-
-
-class JobQueue(Service):
-
-    def __init__(self, source, dispatcher, reactor, daemon_options):
-        self.logger = logging.getLogger(__name__ + '.JobQueue')
-        self.source = source
-        self.dispatcher = dispatcher
-        self.reactor = reactor
-        self.daemon_options = daemon_options
-        self._check_job_call = LoopingCall(self._checkJobs)
-        self._check_job_call.clock = reactor
-
-    def _checkJobs(self):
-        self.logger.debug("Refreshing jobs")
-        return self.source.getJobList().addCallback(
-            self._cbCheckJobs).addErrback(catchall_errback(self.logger))
-
-    def _cbCheckJobs(self, job_list):
-        configured_boards = [
-            x.hostname for x in dispatcher_config.get_devices()]
-
-        for job in job_list:
-            if job.actual_device and job.actual_device.hostname in configured_boards:
-                new_job = JobRunner(self.source, job, self.dispatcher,
-                                    self.reactor, self.daemon_options)
-                self.logger.info("Starting Job: %d " % job.id)
-
-                new_job.start()
-
-    def startService(self):
-        self._check_job_call.start(20)
-
-    def stopService(self):
-        self._check_job_call.stop()
-        return None

=== removed directory 'lava_scheduler_daemon/tests'
=== removed file 'lava_scheduler_daemon/tests/__init__.py'
=== removed file 'lava_scheduler_daemon/tests/test_board.py'
--- lava_scheduler_daemon/tests/test_board.py	2013-08-28 15:13:07 +0000
+++ lava_scheduler_daemon/tests/test_board.py	1970-01-01 00:00:00 +0000
@@ -1,172 +0,0 @@
-from collections import defaultdict
-import logging
-
-from twisted.internet import defer
-from twisted.internet.task import Clock
-from twisted.trial.unittest import TestCase
-
-from lava_scheduler_daemon.board import Board
-
-
-def stub_method(method_name):
-    def method_impl(self, board_name, *args):
-        assert method_name not in self._requests[board_name], (
-            'overlapping call to %s on %s' % (method_name, board_name))
-        d = self._requests[method_name][board_name] = defer.Deferred()
-
-        def _remove_request(result):
-            del self._requests[method_name][board_name]
-            return result
-        d.addBoth(_remove_request)
-        self._calls[board_name][method_name].append(args)
-        return d
-    return method_impl
-
-
-class TestJobSource(object):
-
-    def __init__(self):
-        self._calls = defaultdict(lambda: defaultdict(list))
-        self._requests = defaultdict(dict)
-
-    jobCompleted = stub_method('jobCompleted')
-    getJobForBoard = stub_method('getJobForBoard')
-
-    def _completeCall(self, method_name, board_name, result):
-        self._requests[method_name][board_name].callback(result)
-
-
-class TestJob(object):
-
-    def __init__(self, job_data, dispatcher, source, board_name, reactor, options):
-        self.json_data = job_data
-        self.dispatcher = dispatcher
-        self.reactor = reactor
-        self.source = source
-        self.board_name = board_name
-        self.deferred = defer.Deferred()
-
-    def run(self):
-        return self.deferred
-
-
-class AppendingHandler(logging.Handler):
-
-    def __init__(self, target_list):
-        logging.Handler.__init__(self)
-        self.target_list = target_list
-
-    def emit(self, record):
-        self.target_list.append((record.levelno, self.format(record)))
-
-
-class TestBoard(TestCase):
-
-    def setUp(self):
-        TestCase.setUp(self)
-        self.clock = Clock()
-        self.source = TestJobSource()
-        self._log_messages = []
-        self._handler = AppendingHandler(self._log_messages)
-        self.addCleanup(self._checkNoLogs)
-
-    def _checkNoLogs(self):
-        warnings = [message for (level, message) in self._log_messages
-                    if level >= logging.WARNING]
-        if warnings:
-            self.fail("Logged warnings: %s" % warnings)
-
-    def make_board(self, board_name):
-        board = Board(
-            self.source, board_name, 'script', self.clock, None, job_cls=TestJob)
-        board.logger.addHandler(self._handler)
-        board.logger.setLevel(logging.DEBUG)
-        return board
-
-    def test_initial_state_is_stopped(self):
-        b = self.make_board('board')
-        self.assertEqual('S', b._state_name())
-
-    def test_start_checks(self):
-        b = self.make_board('board')
-        b.start()
-        self.assertEqual('C', b._state_name())
-
-    def test_no_job_waits(self):
-        b = self.make_board('board')
-        b.start()
-        self.source._completeCall('getJobForBoard', 'board', None)
-        self.assertEqual('W', b._state_name())
-
-    def test_actual_job_runs(self):
-        b = self.make_board('board')
-        b.start()
-        self.source._completeCall('getJobForBoard', 'board', ({}, None))
-        self.assertEqual('R', b._state_name())
-
-    def test_check_again_on_completion(self):
-        b = self.make_board('board')
-        b.start()
-        self.source._completeCall('getJobForBoard', 'board', ({}, None))
-        b.running_job.deferred.callback('path')
-        self.assertEqual('C', b._state_name())
-
-    def test_stop_while_checking_moves_to_check_plus_stop(self):
-        b = self.make_board('board')
-        b.start()
-        b.stop()
-        self.assertEqual('C+S', b._state_name())
-
-    def test_stop_while_checking_no_job_stops(self):
-        b = self.make_board('board')
-        b.start()
-        s = b.stop()
-        stop_results = []
-        s.addCallback(stop_results.append)
-        self.assertEqual(0, len(stop_results))
-        self.source._completeCall('getJobForBoard', 'board', None)
-        self.assertEqual(1, len(stop_results))
-        self.assertEqual('S', b._state_name())
-
-    def test_stop_while_checking_actual_job_runs(self):
-        b = self.make_board('board')
-        b.start()
-        s = b.stop()
-        stop_results = []
-        s.addCallback(stop_results.append)
-        self.assertEqual(0, len(stop_results))
-        self.source._completeCall('getJobForBoard', 'board', ({}, None))
-        self.assertEqual(0, len(stop_results))
-        self.assertEqual('R+S', b._state_name())
-
-    def test_stop_while_checking_actual_job_stops_on_complete(self):
-        b = self.make_board('board')
-        b.start()
-        s = b.stop()
-        stop_results = []
-        s.addCallback(stop_results.append)
-        self.assertEqual(0, len(stop_results))
-        self.source._completeCall('getJobForBoard', 'board', ({}, None))
-        b.running_job.deferred.callback(None)
-        self.assertEqual(1, len(stop_results))
-        self.assertEqual('S', b._state_name())
-
-    def test_stop_while_running_job_stops_on_complete(self):
-        b = self.make_board('board')
-        b.start()
-        self.source._completeCall('getJobForBoard', 'board', ({}, None))
-        self.assertEqual('R', b._state_name())
-        s = b.stop()
-        stop_results = []
-        s.addCallback(stop_results.append)
-        self.assertEqual(0, len(stop_results))
-        b.running_job.deferred.callback(None)
-        self.assertEqual(1, len(stop_results))
-        self.assertEqual('S', b._state_name())
-
-    def test_wait_expires_check_again(self):
-        b = self.make_board('board')
-        b.start()
-        self.source._completeCall('getJobForBoard', 'board', None)
-        self.clock.advance(10000)  # hack: the delay should be config data
-        self.assertEqual('C', b._state_name())

=== removed file 'setup.cfg'
--- setup.cfg	2011-08-17 21:37:36 +0000
+++ setup.cfg	1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-[upload]
-sign=True

=== removed file 'setup.py'
--- setup.py	2012-03-15 02:56:22 +0000
+++ setup.py	1970-01-01 00:00:00 +0000
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of LAVA Scheduler.
-#
-# LAVA Scheduler is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License version 3 as
-# published by the Free Software Foundation
-#
-# LAVA Scheduler 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 Affero General Public License
-# along with LAVA Scheduler.  If not, see <http://www.gnu.org/licenses/>.
-
-from setuptools import setup, find_packages
-
-setup(
-    name='lava-scheduler',
-    version=":versiontools:lava_scheduler_app:",
-    author="Michael Hudson-Doyle",
-    author_email="michael.hudson@linaro.org",
-    packages=find_packages(),
-    license="AGPL",
-    description="LAVA Scheduler Application",
-    entry_points="""
-    [lava_server.extensions]
-    scheduler = lava_scheduler_app.extension:SchedulerExtension
-    """,
-    install_requires=[
-        "django-restricted-resource >= 0.2.7",
-        "django-tables2 >= 0.9.4",
-        "lava-dashboard",
-        "lava-dispatcher >= 0.5.9",
-        "lava-server >= 0.11",
-        "simplejson",
-        "south >= 0.7.3",
-        "twisted",
-        "versiontools >= 1.8",
-    ],
-    setup_requires=[
-        "versiontools >= 1.8",
-    ],
-    tests_require=[
-        "django-testscenarios",
-    ],
-    zip_safe=False,
-    include_package_data=True)

