diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 94031bb..a151ba1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ test: script: - apt-get update - - apt-get install python pip + - apt-get install -y python3 git - git clone https://github.com/YunoHost/package_linter - - python package_linter/package_linter.py . + - python3 package_linter/package_linter.py . diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dbbe355 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + 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 . + +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 +. diff --git a/conf/_show.html.haml b/conf/_show.html.haml deleted file mode 100644 index 17ca8cd..0000000 --- a/conf/_show.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -.container{style: "padding-top: 5%;"} - .hero-unit - %h2 diaspora* - %hr/ - %p - %b Vous êtes sur le point de changer Internet en utilisant un réseau social anonyme et distribué. - %br - %b Rejoignez-nous et récupérez votre liberté, votre vie privée et vos données avec YunoHost et diaspora* ! - %p - = link_to "Créer un compte ! »", new_user_registration_path, class: "btn btn-primary btn-large" - .row - .span4 - %h2 diaspora* - %p Découvrez l'ambition du projet pour créer un réseau social universel où vous gardez le contrôle. - %p - %a.btn{:href => "https://diasporafoundation.org/"} Fondation Diaspora » - .span4 - %h2 Auto-hébergez-vous - %p Le site (pod) sur lequel vous êtes est propulsé par YunoHost. Une distribution simple basée sur des outils libres pour créer votre propre "cloud" ! - %p - %a.btn{:href => "https://yunohost.org/"} YunoHost » - .span4 - %h2 Créez votre "Pod" - %p A l'aide de Yunohost et de son application diaspora*, hébergez simplement votre "pod". - %p - %a.btn{:href => "https://github.com/aymhce/diaspora_ynh"} Application diaspora* pour YunoHost » diff --git a/conf/app.src b/conf/app.src deleted file mode 100644 index af975e1..0000000 --- a/conf/app.src +++ /dev/null @@ -1,6 +0,0 @@ -SOURCE_URL=https://github.com/diaspora/diaspora/archive/v0.6.7.0.zip -SOURCE_SUM=8bed8a84a336d51a7983636eab9670d85fdd1fc5 -SOURCE_SUM_PRG=sha256 -SOURCE_FORMAT=zip -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME= diff --git a/conf/database.yml b/conf/database.yml index 7da801a..5e8f934 100644 --- a/conf/database.yml +++ b/conf/database.yml @@ -1,40 +1,40 @@ +postgresql: &postgresql + adapter: postgresql + host: "localhost" + port: 5432 + username: "{{ app }}" + password: "{{ db_pass }}" + encoding: unicode + mysql: &mysql adapter: mysql2 host: "localhost" port: 3306 - username: "DBUSERTOCHANGE" - password: "DBPASSTOCHANGE" + username: "root" + password: "" # socket: /tmp/mysql.sock - charset: utf8mb4 + encoding: utf8mb4 collation: utf8mb4_bin -postgres: &postgres - adapter: postgresql - host: localhost - port: 5432 - username: postgres - password: - encoding: unicode -# Comment the the mysql line and uncomment the postgres line -# if you want to use postgres +# Comment the postgresql line and uncomment the mysql line +# if you want to use mysql common: &common # Choose one of the following - <<: *mysql - #<<: *postgres + <<: *postgresql + #<<: *mysql # Should match environment.sidekiq.concurrency #pool: 25 - + ################################################## #### CONFIGURE ABOVE ############################# ################################################## # Normally you don't need to touch anything here +# ynh note: we actually do :-) how about having different database name for +# different instances on the same postgres cluster? -postgres_travis: &postgres_travis - adapter: postgresql - username: postgres combined: &combined <<: *common development: @@ -42,10 +42,10 @@ development: database: diaspora_development production: <<: *combined - database: diaspora_production + database: {{ app }} test: <<: *combined - database: "diaspora_test" + database: diaspora_test integration1: <<: *combined database: diaspora_integration1 diff --git a/conf/diaspora.target b/conf/diaspora.target index 938aad1..c834654 100644 --- a/conf/diaspora.target +++ b/conf/diaspora.target @@ -1,8 +1,7 @@ [Unit] -Description=Diaspora social network -Wants=redis.service mysqld.service -After=redis.service mysqld.service -StopWhenUnneeded=true +Description=Diaspora social network (instance {{ app}}) +Wants=redis.service postgresql.service +After=redis.service postgresql.service [Install] WantedBy=multi-user.target diff --git a/conf/diaspora.tmpfiles.d b/conf/diaspora.tmpfiles.d new file mode 100644 index 0000000..ffe6df2 --- /dev/null +++ b/conf/diaspora.tmpfiles.d @@ -0,0 +1 @@ +d /run/{{ app }} 0755 {{ app }} {{ app }} - - diff --git a/conf/diaspora.yml b/conf/diaspora.yml index 89e8ab4..1f5b8d3 100644 --- a/conf/diaspora.yml +++ b/conf/diaspora.yml @@ -21,7 +21,7 @@ ## - Specify lists/arrays as comma-separated values ## ## - For example, on Heroku: -## heroku config:set SERVICES_FACEBOOK_APP_ID=yourappid SERVICES_FACEBOOK_SECRET=yourappsecret +## heroku config:set SERVICES_TWITTER_KEY=yourkey SERVICES_TWITTER_SECRET=yoursecret configuration: ## Section @@ -36,13 +36,13 @@ configuration: ## Section ## However changing http to https is okay and has no consequences. ## If you do change the URL, you will have to start again as the URL ## will be hardcoded into the database. - url: "FULLURLTOCHANGE" + url: "https://{{ domain }}{{ path_url }}" ## Set the bundle of certificate authorities (CA) certificates. ## This is specific to your operating system. ## Examples (uncomment the relevant one or add your own): ## For Debian, Ubuntu, Archlinux, Gentoo (package ca-certificates): - #certificate_authorities: '/etc/ssl/certs/ca-certificates.crt' + certificate_authorities: '/etc/ssl/certs/ca-certificates.crt' ## For CentOS, Fedora: #certificate_authorities: '/etc/pki/tls/certs/ca-bundle.crt' @@ -82,7 +82,7 @@ configuration: ## Section ## Number of times a job is retried (default=10). ## There's an exponential effect to this: if you set this too high you ## might get too many jobs building up in the queue. - ## Set it to false to disable it completely. + ## Set it to 0 to disable it completely. #retry: 10 ## Lines of backtrace that are stored on failure (default=15). @@ -175,19 +175,20 @@ configuration: ## Section ## Where the appserver should listen to (default=unix:tmp/diaspora.sock) #listen: 'unix:tmp/diaspora.sock' #listen: 'unix:/run/diaspora/diaspora.sock' - listen: '127.0.0.1:3986' + #listen: '127.0.0.1:3000' + listen: unix:/run/{{ app }}/diaspora.sock ## Set the path for the PID file of the unicorn master process (default=tmp/pids/web.pid) - #pid: 'tmp/pids/web.pid' + pid: '/run/{{ app }}/diaspora.pid' ## Rails environment (default='development'). ## The environment in which the server should be started by default. ## Change this to 'production' if you wish to run a production environment. - #rails_environment: 'development' + rails_environment: 'production' ## Write unicorn stderr and stdout log. - #stderr_log: '/usr/local/app/diaspora/log/unicorn-stderr.log' - #stdout_log: '/usr/local/app/diaspora/log/unicorn-stdout.log' + stderr_log: 'log/unicorn-stderr.log' + stdout_log: 'log/unicorn-stdout.log' ## Number of Unicorn worker processes (default=2). ## Increase this if you have many users. @@ -208,68 +209,6 @@ configuration: ## Section ## increase environment.sidekiq.concurrency instead! #sidekiq_workers: 1 - ## Diaspora has an internal XMPP web-client. If you want to enable the chat - ## functionality or want to use a custom XMPP server, then you should edit - ## the following configuration. - chat: ## Section - - ## Enable the chat service and all its components. - ## - ## Please make sure that you followed the Installation-Instructions first: - ## https://wiki.diasporafoundation.org/Integration/Chat#Installation.2FUpdate - #enabled: true - - ## Custom XMPP server configuration goes here. - server: ## Section - - ## Use the configuration bridge to prosody (default=true). - ## In case you want to run your own server or want to configure - ## prosody on your own, you should disable it. - #enabled: false - - ## Set the directory in which to look for virtual hosts TLS certificates. - #certs: 'config/certs' - - ## XEP-0124 BOSH requests - ## The easiest way of avoiding certificate and mixed-content issues - ## is to use a proxy, e.g.: - ## - ## Apache: https://wiki.diasporafoundation.org/Integration/Chat#Apache2 - ## Nginx: https://wiki.diasporafoundation.org/Integration/Chat#Nginx - ## - ## If you configured your proxy correctly, - ## you should set the proxy option to 'true' - bosh: ## Section - - ## If you'd like to use a proxy, you should set the proxy - ## option to true, otherwise jsxc always tries to - ## connect directly to the port specified below. - #proxy: true - - ## Configure the protocol used to access the BOSH endpoint - #proto: http - - ## Configure the address that prosody should listen on. - #address: '0.0.0.0' - - ## Configure the BOSH port. - #port: 5280 - - ## Configure the bind endpoint. - #bind: '/http-bind' - - ## Specify log behaviour here. - log: ## Section - - ## Log file location. - #info: 'log/prosody.log' - - ## Error log file location. - #error: 'log/prosody.err' - - ## The debug level logs all XML sent and received by the server. - #debug: false - ## Displays the location of a post in a map. Per default we are using the map ## tiles of the Heidelberg University (http://giscience.uni-hd.de). ## You also have the possibility to use the map tiles of https://www.mapbox.com @@ -300,21 +239,16 @@ configuration: ## Section ## Piwik Tracking (disabled by default). ## Provide a site ID and the host piwik is running on to enable ## tracking through Piwik. + # TODO ? Check implications... piwik: ## Section #enable: true #host: 'stats.example.org' #site_id: 1 - ## Mixpanel event tracking (disabled by default). - #mixpanel_uid: - - ## Chartbeat tracking (disabled by default). - #chartbeat_uid: - ## Statistics ## Your pod will report its name, software version and whether - ## or not registrations are open via /statistics.json. + ## or not registrations are open via /statistics and NodeInfo. ## Uncomment the options below to enable more statistics. statistics: ## Section @@ -367,7 +301,8 @@ configuration: ## Section ## Set this to false to prevent people from signing up to your pod ## without an invitation. Note that this needs to be set to true ## (or commented out) to enable the first registration (you). - #enable_registrations: true + # TODO ynh settings + enable_registrations: false ## Auto-follow on sign-up (default=true) ## Users will automatically follow a specified account on creation. @@ -461,6 +396,11 @@ configuration: ## Section ## of your Sidekiq workers. #typhoeus_concurrency: 20 + ## Maximum number of parallel user data export jobs (default=1) + ## Be careful, exports of big/old profiles can use a lot of memory, running + ## many of them in parallel can be a problem for small servers. + #export_concurrency: 1 + ## Captcha settings captcha: ## Section @@ -537,7 +477,7 @@ configuration: ## Section ## Source code URL ## URL to the source code your pod is currently running. ## If not set your pod will provide a downloadable archive. - #source_url: 'https://example.org/username/diaspora' + source_url: 'https://github.com/diaspora/diaspora' ## Changelog URL ## URL to the changelog of the diaspora-version your pod is currently running. @@ -567,14 +507,15 @@ configuration: ## Section ## party domains from services that are included in diaspora*, like OEmbed ## scripts, so you can safely activate it by setting `report_only` to false. If ## you customized diaspora* (edited templates or added own JS), additional work - ## may be required. You can test the policy with the "report_uri". Our default CSP + ## may be required. You can test the policy with the `report_uri`. Our default CSP ## does not work with Google analytics or Piwik, because they inject JS code that ## is blocked by CSP. csp: - ## Report-Only header (default=true) - ## By default diaspora* adds only a "Content-Security-Policy-Report-Only" header. If you set - ## this to false, the "Content-Security-Policy" header is added instead. - #report_only: false + + ## Report-Only header (default=false) + ## By default diaspora* adds a "Content-Security-Policy" header. If you set + ## this to true, the "Content-Security-Policy-Report-Only" header is added instead. + #report_only: true ## CSP report URI (default=) ## You can set an URI here, where the user agent reports violations as JSON document via a POST request. @@ -583,20 +524,6 @@ configuration: ## Section ## Posting from Diaspora to external services (all are disabled by default). services: ## Section - ## OAuth credentials for Facebook - facebook: ## Section - - #enable: true - #app_id: 'abcdef' - #secret: 'change_me' - - ## This setting is required to define whether the Facebook app has permissions to post - ## false == No permissions (default) - ## true == Permissions for all users to post. App MUST have 'publish_actions' approved by Facebook! - ## "username" == Set to local username to allow a single user to cross-post. The person who has created - ## the Facebook app will always be able to cross-post, even without 'publish_actions'. - #authorized: false - ## OAuth credentials for Twitter twitter: ## Section @@ -623,14 +550,14 @@ configuration: ## Section mail: ## Section ## First you need to enable it. - #enable: true + enable: true ## Sender address used in mail sent by Diaspora. - #sender_address: 'no-reply@example.org' + sender_address: 'no-reply@{{ domain }}' ## This selects which mailer should be used. Use 'smtp' for a smtp ## connection or 'sendmail' to use the sendmail binary. - #method: 'smtp' + method: 'sendmail' ## Ignore if method isn't 'smtp'. smtp: ## Section @@ -667,7 +594,7 @@ configuration: ## Section sendmail: ## Section ## The path to the sendmail binary (default='/usr/sbin/sendmail') - #location: '/usr/sbin/sendmail' + location: '/usr/sbin/sendmail' ## Use exim and sendmail (default=false) #exim_fix: false @@ -679,10 +606,10 @@ configuration: ## Section ## This doesn't make the user an admin but is used when a generic ## admin contact is needed, much like the postmaster role in mail ## systems. Set only the username, NOT the full ID. - #account: "podmaster" + account: "{{ admin }}" ## E-mail address to contact the administrator. - #podmin_email: 'podmin@example.org' + podmin_email: '{{ admin_email }}' ## Settings related to relays relay: ## Section @@ -695,13 +622,13 @@ configuration: ## Section outbound: ## Section ## Enable this setting to send out public posts from this pod to a relay - #send: false + send: true ## Change default remote relay url used for sending out here #url: 'https://relay.iliketoast.net/receive/public' inbound: ## Section ## Enable this to receive public posts from relays - #subscribe: false + subscribe: true ## Scope is either 'all' or 'tags' (default). ## - 'all', means this pod wants to receive all public posts from a relay @@ -710,7 +637,7 @@ configuration: ## Section ## If scope is 'tags', should we include tags that users on this pod follow? ## These are added in addition to 'pod_tags', if set. - #include_user_tags: false + include_user_tags: true ## If scope is 'tags', a comma separated list of tags here can be set. ## For example "linux,diaspora", to receive posts related to these tags @@ -725,4 +652,3 @@ production: ## Section development: ## Section environment: ## Section #redis: 'redis://production.example.org:6379' - diff --git a/conf/diaspora_appserver.service b/conf/diaspora_appserver.service deleted file mode 100644 index 194b76e..0000000 --- a/conf/diaspora_appserver.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=Diaspora social network (application server) -PartOf=diaspora.target -StopWhenUnneeded=true - -[Service] -User=diaspora -WorkingDirectory=/var/www/diaspora -Environment=RAILS_ENV=production -ExecStart=/var/www/diaspora/.rvm/scripts/extras/chruby.sh 2.2 -- bin/bundle exec puma -b unix:///var/run/diaspora/diaspora.sock -e $RAILS_ENV -Restart=always -CPUAccounting=true -MemoryAccounting=true -BlockIOAccounting=true - -[Install] -WantedBy=diaspora.target diff --git a/conf/diaspora_sidekiq.service b/conf/diaspora_sidekiq.service new file mode 100644 index 0000000..c653811 --- /dev/null +++ b/conf/diaspora_sidekiq.service @@ -0,0 +1,13 @@ +[Unit] +Description=Diaspora social network (sidekiq - instance {{ app }}) +PartOf={{ app }}.target + +[Service] +User={{ app }} +Environment=RAILS_ENV=production +WorkingDirectory={{ final_path }}/diaspora +ExecStart=/bin/bash -lc "bin/bundle exec sidekiq" +Restart=always + +[Install] +WantedBy={{ app }}.target diff --git a/conf/diaspora_web.service b/conf/diaspora_web.service new file mode 100644 index 0000000..d87354a --- /dev/null +++ b/conf/diaspora_web.service @@ -0,0 +1,15 @@ +[Unit] +Description=Diaspora social network (unicorn - instance {{ app }}) +PartOf={{ app }}.target + +[Service] +User={{ app }} +Environment=RAILS_ENV=production +WorkingDirectory={{ final_path }}/diaspora +PIDFile=/run/{{ app }}/diaspora.pid +ExecStart=/bin/bash -lc "bin/bundle exec unicorn -c config/unicorn.rb -E production" +ExecReload=/bin/kill -USR2 $MAINPID +Restart=always + +[Install] +WantedBy={{ app }}.target diff --git a/conf/diaspora_worker1.service b/conf/diaspora_worker1.service deleted file mode 100644 index 42d3b6c..0000000 --- a/conf/diaspora_worker1.service +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Diaspora social network (worker %i) -PartOf=diaspora.target -StopWhenUnneeded=true - -[Service] -User=diaspora -WorkingDirectory=/var/www/diaspora -Environment=RAILS_ENV=production -ExecStart=/var/www/diaspora/.rvm/scripts/extras/chruby.sh 2.2 -- bin/bundle exec sidekiq -Restart=always -CPUAccounting=true -MemoryAccounting=true -BlockIOAccounting=true - -[Install] -WantedBy=diaspora.target -DefaultInstance=worker1 diff --git a/conf/diaspora_ynh b/conf/diaspora_ynh deleted file mode 100644 index 79323a3..0000000 --- a/conf/diaspora_ynh +++ /dev/null @@ -1,224 +0,0 @@ -#! /bin/sh -### BEGIN INIT INFO -# Provides: diaspora_ynh -# Required-Start: $remote_fs $syslog mysql redis-server -# Required-Stop: $remote_fs $syslog mysql redis-server -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Diaspora application server -# Description: Start / stop the Diaspora app server -### END INIT INFO - -# Author: FABIAN Tamas Laszlo -# Updated: Pirate Praveen -# Updated: aymhce - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -# Note: /usr/local/bin for foreman gem -PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin -DESC="Diaspora application server" -NAME=diaspora -DIASPORA_HOME="/var/www/diaspora" - -STARTSCRIPT="./script/server" - -LOGFILE=$DIASPORA_HOME/log/startscript.log -SCRIPTNAME=$0 -USER=diaspora -STARTUP_TIMEOUT=100 - -. /lib/init/vars.sh -. /lib/lsb/init-functions - -check_unicorn() { - pgrep -f "unicorn_rails master" -} - -check_sidekiq() { - pgrep -f "sidekiq 3" -} - -check_foreman() { - pgrep -f "foreman-runner" -} - -check_foreman_start() { - pgrep -f "foreman start" -} - -check_script_server() { - pgrep -f "script/server" -} - -do_start() -{ - if ! touch $LOGFILE; then - log_failure_msg "Could not touch logfile" - return 2 - fi - - if ! chown $USER $LOGFILE; then - log_failure_msg "Could not chown logfile" - return 2 - fi - - if check_unicorn && check_sidekiq; then - log_warning_msg "Diaspora is already running" - return 1 - fi - - if check_foreman || check_foreman_start || check_script_server; then - log_warning_msg "Diaspora is starting" - return 1 - fi - - export SERVERNAME=localhost - export ENVIRONMENT_URL=http://localhost - export RAILS_ENV=production - export DB=mysql - - cd $DIASPORA_HOME - sudo su - $USER -c " . ~/.bashrc && cd $DIASPORA_HOME && $STARTSCRIPT >> $LOGFILE 2>&1 " & - if [ $? -gt 0 ] - then - log_failure_msg "Could not run start script" - return 2 - else - log_success_msg "Starting diaspora server..." - return 0 - fi - - [ "$VERBOSE" != no ] && log_action_msg "Waiting for Diaspora processes... " - c=0 - while ! check_unicorn > /dev/null || ! check_sidekiq > /dev/null; do - if [ $c -gt $STARTUP_TIMEOUT ]; then - log_failure_msg "Timeout waiting for Diaspora processes" - return 2 - fi - c=`expr $c + 1` - sleep 1 - [ "$VERBOSE" != no ] && echo -n "." - done - [ "$VERBOSE" != no ] && log_action_end_msg 0 -} - -do_stop() -{ - for i in `check_unicorn`; do - [ "$VERBOSE" != no ] && log_action_msg "Killing unicorn master with PID $i" - kill -TERM $i - [ "$VERBOSE" != no ] && log_action_end_msg $? - done - - for i in `check_sidekiq`; do - [ "$VERBOSE" != no ] && log_action_msg "Killing sidekiq with PID $i" - kill -TERM $i - [ "$VERBOSE" != no ] && log_action_end_msg $? - done - - return 0 -} - -case "$1" in - start) - [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" - do_start - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - *) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - stop) - [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" - do_stop - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - status) - log_daemon_msg 'Checking for running Diaspora processes' - - if ! check_unicorn - then - log_action_msg "unicorn not found" - unicorn_running=false - else - for i in `check_unicorn`; do - log_action_msg "Found unicorn master with PID $i" - unicorn_running=true - done - fi - - if ! check_foreman - then - log_action_msg "foreman not found" - foreman_running=false - else - for i in `check_foreman`; do - log_action_msg "Found foreman with pid $i" - foreman_running=true - done - fi - - if ! check_sidekiq - then - log_action_msg "sidekiq is not found" - sidekiq_running=false - else - for i in `check_sidekiq`; do - log_action_msg "Found sidekiq with PID $i" - sidekiq_running=true - done - fi - - if $foreman_running && ! $unicorn_running; then - log_action_msg "Diaspora is starting, check after some time..." - log_end_msg 0 - return 0 - fi - if $unicorn_running && $sidekiq_running; then - log_action_msg "Diaspora health is OK" - log_end_msg 0 - else - if $unicorn_running; then - log_failure_msg "Unicorn is RUNNING, but sidekiq is DOWN!" - log_end_msg 1 - return 1 - fi - if $sidekiq_running; then - log_failure_msg "Sidekiq is RUNNING, but unicorn is DOWN!" - log_end_msg 1 - return 1 - fi - log_daemon_msg "All Diaspora processes are DOWN" - log_end_msg 0 - fi - ;; - restart|force-reload) - [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" - do_stop - ret=$? - sleep 5 - case "$ret" in - 0|1) - do_start - case "$?" in - 0) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 1) [ "$VERBOSE" != no ] && log_failure_msg "old process is still running" && log_end_msg 1 ;; - *) [ "$VERBOSE" != no ] && log_failure_msg "failed to start" && log_end_msg 1 ;; - esac - ;; - *) - [ "$VERBOSE" != no ] && log_failure_msg "failed to stop" - [ "$VERBOSE" != no ] && log_end_msg 1 - ;; - esac - ;; - *) - echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 - exit 3 - ;; -esac - -: diff --git a/conf/mpapis@gmail.com.pgp b/conf/mpapis@gmail.com.pgp new file mode 100644 index 0000000..e2aedda --- /dev/null +++ b/conf/mpapis@gmail.com.pgp @@ -0,0 +1,1129 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +AgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp +KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImK +kpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj +5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJ +Cgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGh +scEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ +WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1 +tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEA +AhEDEQA/APWBSk80YpMYpEi07rTKcOlACgUcUHPajmmAntSNgc54rB1/xXZ6EhVv +31x/zzU9Pqe1eSeJPHGpaxMUWV4IP+ecRIHfr61rCk5anHVxkIy5Y6s9k1LxHpGk +4+2X0SMf4c5P5CqEPj7wzM4QaogYjPzKwH54xXz9POZCAWLEfjTfuoGJwe2K09jE +x+t1Nz6Efx14ajyf7UjOP7qsf5CreneKdE1OTy7TUoXk/usdp/I4r52iYGPJPNIZ +WBHHFP2Ee5KxlS+x9QghhlSCPY06vnKw8V6lpEiG2vJVweFLZH5GvQvDvxXt7yRL +fV4PIfp56cqT7jtWcqLW2p0U8WpfErHpXU0EZqOGeO4iWSJ1eNhkMpyDUvIrE607 +idOKDRmkoGJ9aKTdz0pcCgBxpabS0gDGKUUh5pAc0APqnq1/Hpmny3UmcKOMevar +Y+tcP8Rr8x2sFnG3LAyP/If1rajDnmkcuMrOlRclueVeJ76e41GRzKTvO4nPXNYi +JNIDsBPrXa+GfB1z4muPNmylqhwX9favVdP8B6PZRIBbKzL/ABMK3q1YwdjhwuFq +Tpq33nz/AB6VeEgrExOMkbTVn+w7zy9zQPgc19HroFiMfuEyO+KmfRLRk2mFMDti +sPrHZHX9Qk95HzamnPCMPC4Pbiq8kGMqVZa+ip/C9jJ1hX8RWDqngezuAfLjAbOa +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 +=quCp +-----END PGP PUBLIC KEY BLOCK----- diff --git a/conf/nginx.conf b/conf/nginx.conf index 54bb4f3..8faded4 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,22 +1,33 @@ # Proxy if requested file not found -try_files $uri @diaspora; -root ROOTOCHANGE/public; +location __PATH__ { -location @diaspora { - # Configure maximum picture size - # Note that Diaspora has a client side check set at 4M - client_max_body_size 5M; - client_body_buffer_size 256K; - - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - proxy_set_header Host $http_host; - proxy_redirect off; - - proxy_pass http://diaspora_server; + root __FINALPATH__/diaspora/public; - # Include SSOWAT user panel. - include conf.d/yunohost_panel.conf.inc; +# Configure maximum picture size +# Note that Diaspora has a client side check set at 4M + client_max_body_size 5M; + client_body_buffer_size 256K; + +# Proxy if requested file not found + try_files $uri @diaspora; + + location __PATH__/assets/ { + expires max; + add_header Cache-Control public; + } + +# Include SSOWAT user panel. +# TODO check that + include conf.d/yunohost_panel.conf.inc; } +location @diaspora { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header Host $http_host; + proxy_redirect off; + + proxy_pass http://unix:/run/__NAME__/diaspora.sock; + +} diff --git a/conf/nginx_upstream.conf b/conf/nginx_upstream.conf deleted file mode 100644 index 15bc320..0000000 --- a/conf/nginx_upstream.conf +++ /dev/null @@ -1,5 +0,0 @@ - -upstream diaspora_server { - server 127.0.0.1:3986; -} - diff --git a/conf/piotr.kuczynski@gmail.com.pgp b/conf/piotr.kuczynski@gmail.com.pgp new file mode 100644 index 0000000..ca9ee6b --- /dev/null +++ b/conf/piotr.kuczynski@gmail.com.pgp @@ -0,0 +1,132 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +iWTuv7mXY0bNG+s= +=SF+D +-----END PGP PUBLIC KEY BLOCK----- diff --git a/manifest.json b/manifest.json index 78147f5..dac2192 100644 --- a/manifest.json +++ b/manifest.json @@ -1,57 +1,65 @@ { - "name": "Diaspora", - "id": "diaspora", - "url": "https://diasporafoundation.org", - "packaging_format": 1, - "description": { - "en": "Distributed social networking service", - "fr": "Service de réseau social distribué" - }, - "license": "free", - "version": "1.0", - "maintainer": { - "name": "rafi59", - "email": "" - }, - "requirements": { - "yunohost": ">= 2.7.2" - }, - "multi_instance": "false", - "services": [ - "nginx", - "php5-fpm", - "mysql" - ], - "arguments": { - "install" : [ - { - "name": "domain", - "type": "domain", - "ask": { - "en": "Choose a domain for diaspora*", - "fr": "Choisissez un domaine pour diaspora*" - }, - "example": "domain.org" - }, - { - "name": "path", - "type": "path", - "ask": { - "en": "Choose a path for ynhexample", - "fr": "Choisissez un chemin pour diaspora (uniquement / est accepté)" - }, - "example": "/", - "default": "/" -}, - { - "name": "is_public", - "type": "boolean", - "ask": { - "en": "Is it a public Diaspora site?", - "fr": "Est-ce un site public ?" - }, - "default": true - } - ] - } + "name": "Diaspora", + "id": "diaspora", + "url": "https://diasporafoundation.org", + "packaging_format": 1, + "description": { + "en": "Distributed social networking service", + "fr": "Service de réseau social distribué" + }, + "license": "AGPL-3.0", + "version": "0.7.13.0~ynh1", + "maintainer": { + "name": "rafi59", + "email": "" + }, + "requirements": { + "yunohost": ">= 3.6.0" + }, + "multi_instance": true, + "services": [ + "nginx", + "postgresql" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain for diaspora*", + "fr": "Choisissez un domaine pour diaspora*" + }, + "example": "domain.org" + }, + { + "name": "path", + "type": "path", + "ask": { + "en": "Choose a path for ynhexample (only / is accepted for now)", + "fr": "Choisissez un chemin pour diaspora (pour l'instant, uniquement / est accepté)" + }, + "example": "/", + "default": "/" + }, + { + "name": "admin", + "type": "user", + "ask": { + "en": "Choose the diaspora* administrator (must be an existing YunoHost user)", + "fr": "Choisissez l'administrateur de diaspora* (doit être un utilisateur YunoHost)" + }, + "example": "johndoe" + }, + { + "name": "admin_password", + "type": "password", + "ask": { + "en": "Admin password. Must contain at least 10 characters, one lowercase letter, one uppercase letter, one number, and one symbol (e.g. '~!@#$%^&*()').", + "fr": "Mot de passe pour l’administrateur. Doit contenir au moins 10 caractères, une majuscule, une minuscule, un chiffre, et une ponctuation (ex. '~!@#$%^&*()')." + }, + "optional": false + } + ] + } } diff --git a/scripts/_common.sh b/scripts/_common.sh index b179bb1..75c1b47 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -1,848 +1,4 @@ #!/bin/bash -#================================================= -#================================================= -# TESTING -#================================================= -#================================================= - -YNH_EXECUTION_DIR="." - -ynh_backup_abstract () { - # A intégrer à ynh_backup directement. - ynh_backup "$@" - echo "$2" "$1" >> backup_list -} - -ynh_restore_file () { - file_and_dest=$(grep "^$1" backup_list) - backup_file=${file_and_dest%% *} - backup_dest=${file_and_dest#* } - if [ -f "$backup_dest" ]; then - ynh_die "There is already a file at this path: $backup_dest" - fi - if test -d "$backup_file"; then - sudo cp -a "$backup_file/." "$backup_dest" - else - sudo cp -a "$backup_file" "$backup_dest" - fi -} - -ynh_fpm_config () { - finalphpconf="/etc/php5/fpm/pool.d/$app.conf" - ynh_backup_if_checksum_is_different "$finalphpconf" 1 - sudo cp ../conf/php-fpm.conf "$finalphpconf" - ynh_replace_string "__NAMETOCHANGE__" "$app" "$finalphpconf" - ynh_replace_string "__FINALPATH__" "$final_path" "$finalphpconf" - ynh_replace_string "__USER__" "$app" "$finalphpconf" - sudo chown root: "$finalphpconf" - ynh_store_file_checksum "$finalphpconf" - - if [ -e "../conf/php-fpm.ini" ] - then - finalphpini="/etc/php5/fpm/conf.d/20-$app.ini" - ynh_backup_if_checksum_is_different "$finalphpini" 1 - sudo cp ../conf/php-fpm.ini "$finalphpini" - sudo chown root: "$finalphpini" - ynh_store_file_checksum "$finalphpini" - fi - - sudo systemctl reload php5-fpm -} - -ynh_remove_fpm_config () { - ynh_secure_remove "/etc/php5/fpm/pool.d/$app.conf" - ynh_secure_remove "/etc/php5/fpm/conf.d/20-$app.ini" - sudo systemctl reload php5-fpm -} - -ynh_nginx_config () { - finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf" - ynh_backup_if_checksum_is_different "$finalnginxconf" 1 - sudo cp ../conf/nginx.conf "$finalnginxconf" - - # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable. - # Substitute in a nginx config file only if the variable is not empty - if test -n "${path_url:-}"; then - ynh_replace_string "__PATH__" "$path_url" "$finalnginxconf" - fi - if test -n "${domain:-}"; then - ynh_replace_string "__DOMAIN__" "$domain" "$finalnginxconf" - fi - if test -n "${port:-}"; then - ynh_replace_string "__PORT__" "$port" "$finalnginxconf" - fi - if test -n "${app:-}"; then - ynh_replace_string "__NAME__" "$app" "$finalnginxconf" - fi - if test -n "${final_path:-}"; then - ynh_replace_string "__FINALPATH__" "$final_path" "$finalnginxconf" - fi - ynh_store_file_checksum "$finalnginxconf" - - sudo systemctl reload nginx -} - -ynh_remove_nginx_config () { - ynh_secure_remove "/etc/nginx/conf.d/$domain.d/$app.conf" - sudo systemctl reload nginx -} - -ynh_systemd_config () { - finalsystemdconf="/etc/systemd/system/$app.service" - ynh_backup_if_checksum_is_different "$finalsystemdconf" 1 - sudo cp ../conf/systemd.service "$finalsystemdconf" - - # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable. - # Substitute in a nginx config file only if the variable is not empty - if test -n "${final_path:-}"; then - ynh_replace_string "__FINALPATH__" "$final_path" "$finalsystemdconf" - fi - if test -n "${app:-}"; then - ynh_replace_string "__APP__" "$app" "$finalsystemdconf" - fi - ynh_store_file_checksum "$finalsystemdconf" - - sudo chown root: "$finalsystemdconf" - sudo systemctl enable $app - sudo systemctl daemon-reload -} - -ynh_remove_systemd_config () { - finalsystemdconf="/etc/systemd/system/$app.service" - if [ -e "$finalsystemdconf" ]; then - sudo systemctl stop $app - sudo systemctl disable $app - ynh_secure_remove "$finalsystemdconf" - fi -} - -#================================================= -#================================================= - -#================================================= -# CHECKING -#================================================= - -CHECK_DOMAINPATH () { # Vérifie la disponibilité du path et du domaine. - sudo yunohost app checkurl $domain$path_url -a $app -} - -CHECK_FINALPATH () { # Vérifie que le dossier de destination n'est pas déjà utilisé. - final_path=/var/www/$app - test ! -e "$final_path" || ynh_die "This path already contains a folder" -} - -#================================================= -# DISPLAYING -#================================================= - -NO_PRINT () { # Supprime l'affichage dans stdout pour la commande en argument. - set +x - $@ - set -x -} - -WARNING () { # Écrit sur le canal d'erreur pour passer en warning. - $@ >&2 -} - -SUPPRESS_WARNING () { # Force l'écriture sur la sortie standard - $@ 2>&1 -} - -QUIET () { # Redirige la sortie standard dans /dev/null - $@ > /dev/null -} - -ALL_QUIET () { # Redirige la sortie standard et d'erreur dans /dev/null - $@ > /dev/null 2>&1 -} - -#================================================= -# BACKUP -#================================================= - -BACKUP_FAIL_UPGRADE () { - WARNING echo "Upgrade failed." - app_bck=${app//_/-} # Replace all '_' by '-' - if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number; then # Vérifie l'existence de l'archive avant de supprimer l'application et de restaurer - sudo yunohost app remove $app # Supprime l'application avant de la restaurer. - sudo yunohost backup restore --ignore-hooks $app_bck-pre-upgrade$backup_number --apps $app --force # Restore the backup if upgrade failed - ynh_die "The app was restored to the way it was before the failed upgrade." - fi -} - -BACKUP_BEFORE_UPGRADE () { # Backup the current version of the app, restore it if the upgrade fails - backup_number=1 - old_backup_number=2 - app_bck=${app//_/-} # Replace all '_' by '-' - if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1; then # Vérifie l'existence d'une archive déjà numéroté à 1. - backup_number=2 # Et passe le numéro de l'archive à 2 - old_backup_number=1 - fi - - sudo yunohost backup create --ignore-hooks --apps $app --name $app_bck-pre-upgrade$backup_number # Créer un backup différent de celui existant. - if [ "$?" -eq 0 ]; then # Si le backup est un succès, supprime l'archive précédente. - if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number; then # Vérifie l'existence de l'ancienne archive avant de la supprimer, pour éviter une erreur. - QUIET sudo yunohost backup delete $app_bck-pre-upgrade$old_backup_number - fi - else # Si le backup a échoué - ynh_die "Backup failed, the upgrade process was aborted." - fi -} - -HUMAN_SIZE () { # Transforme une taille en Ko en une taille lisible pour un humain - human=$(numfmt --to=iec --from-unit=1K $1) - echo $human -} - -CHECK_SIZE () { # Vérifie avant chaque backup que l'espace est suffisant - file_to_analyse=$1 - backup_size=$(sudo du --summarize "$file_to_analyse" | cut -f1) - free_space=$(sudo df --output=avail "/home/yunohost.backup" | sed 1d) - - if [ $free_space -le $backup_size ] - then - WARNING echo "Espace insuffisant pour sauvegarder $file_to_analyse." - WARNING echo "Espace disponible: $(HUMAN_SIZE $free_space)" - ynh_die "Espace nécessaire: $(HUMAN_SIZE $backup_size)" - fi -} - -#================================================= -# PACKAGE CHECK BYPASSING... -#================================================= - -IS_PACKAGE_CHECK () { # Détermine une exécution en conteneur (Non testé) - return $(uname -n | grep -c 'pchecker_lxc') -} - -#================================================= -# NODEJS -#================================================= - -sudo_path () { - sudo env "PATH=$PATH" $@ -} - -# INFOS -# nvm utilise la variable PATH pour stocker le path de la version de node à utiliser. -# C'est ainsi qu'il change de version -# En attendant une généralisation de root, il est possible d'utiliser sudo aevc le helper temporaire sudo_path -# Il permet d'utiliser sudo en gardant le $PATH modifié -# ynh_install_nodejs installe la version de nodejs demandée en argument, avec nvm -# ynh_use_nodejs active une version de nodejs dans le script courant -# 3 variables sont mises à disposition, et 2 sont stockées dans la config de l'app -# - nodejs_path: Le chemin absolu de cette version de node -# Utilisé pour des appels directs à npm ou node. -# - nodejs_version: Simplement le numéro de version de nodejs pour cette application -# - nodejs_use_version: Un alias pour charger une version de node dans le shell courant. -# Utilisé pour démarrer un service ou un script qui utilise node ou npm -# Dans ce cas, c'est $PATH qui contient le chemin de la version de node. Il doit être propagé sur les autres shell si nécessaire. - -nvm_install_dir="/opt/nvm" -ynh_use_nodejs () { - nodejs_path=$(ynh_app_setting_get $app nodejs_path) - nodejs_version=$(ynh_app_setting_get $app nodejs_version) - - # And store the command to use a specific version of node. Equal to `nvm use version` - nodejs_use_version="source $nvm_install_dir/nvm.sh; nvm use \"$nodejs_version\"" - - # Desactive set -u for this script. - set +u - eval $nodejs_use_version - set -u -} - -ynh_install_nodejs () { - local nodejs_version="$1" - local nvm_install_script="https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh" - - local nvm_exec="source $nvm_install_dir/nvm.sh; nvm" - - sudo mkdir -p "$nvm_install_dir" - - # If nvm is not previously setup, install it - "$nvm_exec --version" > /dev/null 2>&1 || \ - ( cd "$nvm_install_dir" - echo "Installation of NVM" - sudo wget --no-verbose "$nvm_install_script" -O- | sudo NVM_DIR="$nvm_install_dir" bash > /dev/null) - - # Install the requested version of nodejs - sudo su -c "$nvm_exec install \"$nodejs_version\" > /dev/null" - - # Store the ID of this app and the version of node requested for it - echo "$YNH_APP_ID:$nodejs_version" | sudo tee --append "$nvm_install_dir/ynh_app_version" - - # Get the absolute path of this version of node - nodejs_path="$(dirname "$(sudo su -c "$nvm_exec which \"$nodejs_version\"")")" - - # Store nodejs_path and nodejs_version into the config of this app - ynh_app_setting_set $app nodejs_path $nodejs_path - ynh_app_setting_set $app nodejs_version $nodejs_version - - ynh_use_nodejs -} - -ynh_remove_nodejs () { - nodejs_version=$(ynh_app_setting_get $app nodejs_version) - - # Remove the line for this app - sudo sed --in-place "/$YNH_APP_ID:$nodejs_version/d" "$nvm_install_dir/ynh_app_version" - - # If none another app uses this version of nodejs, remove it. - if ! grep --quiet "$nodejs_version" "$nvm_install_dir/ynh_app_version" - then - sudo su -c "source $nvm_install_dir/nvm.sh; nvm deactivate; nvm uninstall \"$nodejs_version\" > /dev/null" - fi - - # If none another app uses nvm, remove nvm and clean the root's bashrc file - if [ ! -s "$nvm_install_dir/ynh_app_version" ] - then - ynh_secure_remove "$nvm_install_dir" - sudo sed --in-place "/NVM_DIR/d" /root/.bashrc - fi -} - -#================================================= -#================================================= -# FUTUR YNH HELPERS -#================================================= -# Importer ce fichier de fonction avant celui des helpers officiel -# Ainsi, les officiels prendront le pas sur ceux-ci le cas échéant -#================================================= - -# Normalize the url path syntax -# Handle the slash at the beginning of path and its absence at ending -# Return a normalized url path -# -# example: url_path=$(ynh_normalize_url_path $url_path) -# ynh_normalize_url_path example -> /example -# ynh_normalize_url_path /example -> /example -# ynh_normalize_url_path /example/ -> /example -# ynh_normalize_url_path / -> / -# -# usage: ynh_normalize_url_path path_to_normalize -# | arg: url_path_to_normalize - URL path to normalize before using it -ynh_normalize_url_path () { - path_url=$1 - test -n "$path_url" || ynh_die "ynh_normalize_url_path expect a URL path as first argument and received nothing." - if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a / - path_url="/$path_url" # Add / at begin of path variable - fi - if [ "${path_url:${#path_url}-1}" == "/" ] && [ ${#path_url} -gt 1 ]; then # If the last character is a / and that not the only character. - path_url="${path_url:0:${#path_url}-1}" # Delete the last character - fi - echo $path_url -} - -# Check if a mysql user exists -# -# usage: ynh_mysql_user_exists user -# | arg: user - the user for which to check existence -function ynh_mysql_user_exists() -{ - local user=$1 - if [[ -z $(ynh_mysql_execute_as_root "SELECT User from mysql.user WHERE User = '$user';") ]] - then - return 1 - else - return 0 - fi -} - -# Create a database, an user and its password. Then store the password in the app's config -# -# After executing this helper, the password of the created database will be available in $db_pwd -# It will also be stored as "mysqlpwd" into the app settings. -# -# usage: ynh_mysql_setup_db user name [pwd] -# | arg: user - Owner of the database -# | arg: name - Name of the database -# | arg: pwd - Password of the database. If not given, a password will be generated -ynh_mysql_setup_db () { - local db_user="$1" - local db_name="$2" - local new_db_pwd=$(ynh_string_random) # Generate a random password - db_pwd=${3:-$new_db_pwd} - ynh_mysql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database - ynh_app_setting_set $app mysqlpwd $db_pwd # Store the password in the app's config -} - -# Remove a database if it exists, and the associated user -# -# usage: ynh_mysql_remove_db user name -# | arg: user - Owner of the database -# | arg: name - Name of the database -ynh_mysql_remove_db () { - local db_user="$1" - local db_name="$2" - local mysql_root_password=$(sudo cat $MYSQL_ROOT_PWD_FILE) - if mysqlshow -u root -p$mysql_root_password | grep -q "^| $db_name"; then # Check if the database exists - echo "Removing database $db_name" >&2 - ynh_mysql_drop_db $db_name # Remove the database - else - echo "Database $db_name not found" >&2 - fi - - # Remove mysql user if it exists - if $(ynh_mysql_user_exists $db_user); then - ynh_mysql_drop_user $db_user - fi -} - -# Correct the name given in argument for mariadb -# -# Avoid invalid name for your database -# -# Exemple: dbname=$(ynh_make_valid_dbid $app) -# -# usage: ynh_make_valid_dbid name -# | arg: name - name to correct -# | ret: the corrected name -ynh_make_valid_dbid () { - dbid=${1//[-.]/_} # Mariadb doesn't support - and . in the name of databases. It will be replace by _ - echo $dbid -} - -# Manage a fail of the script -# -# Print a warning to inform that the script was failed -# Execute the ynh_clean_setup function if used in the app script -# -# usage of ynh_clean_setup function -# This function provide a way to clean some residual of installation that not managed by remove script. -# To use it, simply add in your script: -# ynh_clean_setup () { -# instructions... -# } -# This function is optionnal. -# -# Usage: ynh_exit_properly is used only by the helper ynh_abort_if_errors. -# You must not use it directly. -ynh_exit_properly () { - exit_code=$? - if [ "$exit_code" -eq 0 ]; then - exit 0 # Exit without error if the script ended correctly - fi - - trap '' EXIT # Ignore new exit signals - set +eu # Do not exit anymore if a command fail or if a variable is empty - - echo -e "!!\n $app's script has encountered an error. Its execution was cancelled.\n!!" >&2 - - if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script. - ynh_clean_setup # Call the function to do specific cleaning for the app. - fi - - ynh_die # Exit with error status -} - -# Exit if an error occurs during the execution of the script. -# -# Stop immediatly the execution if an error occured or if a empty variable is used. -# The execution of the script is derivate to ynh_exit_properly function before exit. -# -# Usage: ynh_abort_if_errors -ynh_abort_if_errors () { - set -eu # Exit if a command fail, and if a variable is used unset. - trap ynh_exit_properly EXIT # Capturing exit signals on shell script -} - -# Define and install dependencies with a equivs control file -# This helper can/should only be called once per app -# -# usage: ynh_install_app_dependencies dep [dep [...]] -# | arg: dep - the package name to install in dependence -ynh_install_app_dependencies () { - dependencies=$@ - manifest_path="../manifest.json" - if [ ! -e "$manifest_path" ]; then - manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place - fi - version=$(sudo grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file. - dep_app=${app//_/-} # Replace all '_' by '-' - - if ynh_package_is_installed "${dep_app}-ynh-deps"; then - echo "A package named ${dep_app}-ynh-deps is already installed" >&2 - else - cat > ./${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build -Section: misc -Priority: optional -Package: ${dep_app}-ynh-deps -Version: ${version} -Depends: ${dependencies// /, } -Architecture: all -Description: Fake package for ${app} (YunoHost app) dependencies - This meta-package is only responsible of installing its dependencies. -EOF - ynh_package_install_from_equivs ./${dep_app}-ynh-deps.control \ - || ynh_die "Unable to install dependencies" # Install the fake package and its dependencies - ynh_app_setting_set $app apt_dependencies $dependencies - fi -} - -# Remove fake package and its dependencies -# -# Dependencies will removed only if no other package need them. -# -# usage: ynh_remove_app_dependencies -ynh_remove_app_dependencies () { - dep_app=${app//_/-} # Replace all '_' by '-' - ynh_package_autoremove ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used. -} - -# Use logrotate to manage the logfile -# -# usage: ynh_use_logrotate [logfile] -# | arg: logfile - absolute path of logfile -# -# If no argument provided, a standard directory will be use. /var/log/${app} -# You can provide a path with the directory only or with the logfile. -# /parentdir/logdir/ -# /parentdir/logdir/logfile.log -# -# It's possible to use this helper several times, each config will added to same logrotate config file. -ynh_use_logrotate () { - if [ "$#" -gt 0 ]; then - if [ "$(echo ${1##*.})" == "log" ]; then # Keep only the extension to check if it's a logfile - logfile=$1 # In this case, focus logrotate on the logfile - else - logfile=$1/.log # Else, uses the directory and all logfile into it. - fi - else - logfile="/var/log/${app}/.log" # Without argument, use a defaut directory in /var/log - fi - cat > ./${app}-logrotate << EOF # Build a config file for logrotate -$logfile { - # Rotate if the logfile exceeds 100Mo - size 100M - # Keep 12 old log maximum - rotate 12 - # Compress the logs with gzip - compress - # Compress the log at the next cycle. So keep always 2 non compressed logs - delaycompress - # Copy and truncate the log to allow to continue write on it. Instead of move the log. - copytruncate - # Do not do an error if the log is missing - missingok - # Not rotate if the log is empty - notifempty - # Keep old logs in the same dir - noolddir -} -EOF - sudo mkdir -p $(dirname "$logfile") # Create the log directory, if not exist - cat ${app}-logrotate | sudo tee -a /etc/logrotate.d/$app > /dev/null # Append this config to the others for this app. If a config file already exist -} - -# Remove the app's logrotate config. -# -# usage: ynh_remove_logrotate -ynh_remove_logrotate () { - if [ -e "/etc/logrotate.d/$app" ]; then - sudo rm "/etc/logrotate.d/$app" - fi -} - -# Find a free port and return it -# -# example: port=$(ynh_find_port 8080) -# -# usage: ynh_find_port begin_port -# | arg: begin_port - port to start to search -ynh_find_port () { - port=$1 - test -n "$port" || ynh_die "The argument of ynh_find_port must be a valid port." - while netcat -z 127.0.0.1 $port # Check if the port is free - do - port=$((port+1)) # Else, pass to next port - done - echo $port -} - -# Create a system user -# -# usage: ynh_system_user_create user_name [home_dir] -# | arg: user_name - Name of the system user that will be create -# | arg: home_dir - Path of the home dir for the user. Usually the final path of the app. If this argument is omitted, the user will be created without home -ynh_system_user_create () { - if ! ynh_system_user_exists "$1" # Check if the user exists on the system - then # If the user doesn't exist - if [ $# -ge 2 ]; then # If a home dir is mentioned - user_home_dir="-d $2" - else - user_home_dir="--no-create-home" - fi - sudo useradd $user_home_dir --system --user-group $1 --shell /usr/sbin/nologin || ynh_die "Unable to create $1 system account" - fi -} - -# Delete a system user -# -# usage: ynh_system_user_delete user_name -# | arg: user_name - Name of the system user that will be create -ynh_system_user_delete () { - if ynh_system_user_exists "$1" # Check if the user exists on the system - then - echo "Remove the user $1" >&2 - sudo userdel $1 - else - echo "The user $1 was not found" >&2 - fi -} - -# Curl abstraction to help with POST requests to local pages (such as installation forms) -# -# $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?)) -# -# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2" -# -# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ... -# | arg: page_uri - Path (relative to $path_url) of the page where POST data will be sent -# | arg: key1=value1 - (Optionnal) POST key and corresponding value -# | arg: key2=value2 - (Optionnal) Another POST key and corresponding value -# | arg: ... - (Optionnal) More POST keys and values -ynh_local_curl () { - # Define url of page to curl - full_page_url=https://localhost$path_url$1 - - # Concatenate all other arguments with '&' to prepare POST data - POST_data="" - for arg in "${@:2}" - do - POST_data="${POST_data}${arg}&" - done - if [ -n "$POST_data" ] - then - # Add --data arg and remove the last character, which is an unecessary '&' - POST_data="--data \"${POST_data::-1}\"" - fi - - # Curl the URL - curl --silent --show-error -kL -H "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url" -} - -# Substitute/replace a string by another in a file -# -# usage: ynh_replace_string match_string replace_string target_file -# | arg: match_string - String to be searched and replaced in the file -# | arg: replace_string - String that will replace matches -# | arg: target_file - File in which the string will be replaced. -ynh_replace_string () { - delimit=@ - match_string=${1//${delimit}/"\\${delimit}"} # Escape the delimiter if it's in the string. - replace_string=${2//${delimit}/"\\${delimit}"} - workfile=$3 - - sudo sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$workfile" -} - -# Remove a file or a directory securely -# -# usage: ynh_secure_remove path_to_remove -# | arg: path_to_remove - File or directory to remove -ynh_secure_remove () { - path_to_remove=$1 - forbidden_path=" \ - /var/www \ - /home/yunohost.app" - - if [[ "$forbidden_path" =~ "$path_to_remove" \ - # Match all paths or subpaths in $forbidden_path - || "$path_to_remove" =~ ^/[[:alnum:]]+$ \ - # Match all first level paths from / (Like /var, /root, etc...) - || "${path_to_remove:${#path_to_remove}-1}" = "/" ]] - # Match if the path finishes by /. Because it seems there is an empty variable - then - echo "Avoid deleting $path_to_remove." >&2 - else - if [ -e "$path_to_remove" ] - then - sudo rm -R "$path_to_remove" - else - echo "$path_to_remove wasn't deleted because it doesn't exist." >&2 - fi - fi -} - -# Download, check integrity, uncompress and patch the source from app.src -# -# The file conf/app.src need to contains: -# -# SOURCE_URL=Address to download the app archive -# SOURCE_SUM=Control sum -# # (Optional) Programm to check the integrity (sha256sum, md5sum$YNH_EXECUTION_DIR/...) -# # default: sha256 -# SOURCE_SUM_PRG=sha256 -# # (Optional) Archive format -# # default: tar.gz -# SOURCE_FORMAT=tar.gz -# # (Optional) Put false if source are directly in the archive root -# # default: true -# SOURCE_IN_SUBDIR=false -# # (Optionnal) Name of the local archive (offline setup support) -# # default: ${src_id}.${src_format} -# SOURCE_FILENAME=example.tar.gz -# -# Details: -# This helper download sources from SOURCE_URL if there is no local source -# archive in /opt/yunohost-apps-src/APP_ID/SOURCE_FILENAME -# -# Next, it check the integrity with "SOURCE_SUM_PRG -c --status" command. -# -# If it's ok, the source archive will be uncompress in $dest_dir. If the -# SOURCE_IN_SUBDIR is true, the first level directory of the archive will be -# removed. -# -# Finally, patches named sources/patches/${src_id}-*.patch and extra files in -# sources/extra_files/$src_id will be applyed to dest_dir -# -# -# usage: ynh_setup_source dest_dir [source_id] -# | arg: dest_dir - Directory where to setup sources -# | arg: source_id - Name of the app, if the package contains more than one app -ynh_setup_source () { - local dest_dir=$1 - local src_id=${2:-app} # If the argument is not given, source_id equal "app" - - # Load value from configuration file (see above for a small doc about this file - # format) - local src_url=$(grep 'SOURCE_URL=' "$YNH_EXECUTION_DIR/../conf/${src_id}.src" | cut -d= -f2-) - local src_sum=$(grep 'SOURCE_SUM=' "$YNH_EXECUTION_DIR/../conf/${src_id}.src" | cut -d= -f2-) - local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$YNH_EXECUTION_DIR/../conf/${src_id}.src" | cut -d= -f2-) - local src_format=$(grep 'SOURCE_FORMAT=' "$YNH_EXECUTION_DIR/../conf/${src_id}.src" | cut -d= -f2-) - local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$YNH_EXECUTION_DIR/../conf/${src_id}.src" | cut -d= -f2-) - local src_filename=$(grep 'SOURCE_FILENAME=' "$YNH_EXECUTION_DIR/../conf/${src_id}.src" | cut -d= -f2-) - - # Default value - src_sumprg=${src_sumprg:-sha256sum} - src_in_subdir=${src_in_subdir:-true} - src_format=${src_format:-tar.gz} - src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]') - if [ "$src_filename" = "" ] ; then - src_filename="${src_id}.${src_format}" - fi - local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}" - - if test -e "$local_src" - then # Use the local source file if it is present - sudo cp $local_src $src_filename - else # If not, download the source - wget -nv -O $src_filename $src_url - fi - - # Check the control sum - echo "${src_sum} ${src_filename}" | ${src_sumprg} -c --status \ - || ynh_die "Corrupt source" - - # Extract source into the app dir - sudo mkdir -p "$dest_dir" - if [ "$src_format" = "zip" ] - then - # Zip format - # Using of a temp directory, because unzip doesn't manage --strip-components - if $src_in_subdir ; then - local tmp_dir=$(mktemp -d) - unzip -quo $src_filename -d "$tmp_dir" - sudo cp -a $tmp_dir/*/. "$dest_dir" - ynh_secure_remove "$tmp_dir" - else - sudo unzip -quo $src_filename -d "$dest_dir" - fi - else - local strip="" - if $src_in_subdir ; then - strip="--strip-components 1" - fi - if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]] ; then - sudo tar -xf $src_filename -C "$dest_dir" $strip - else - ynh_die "Archive format unrecognized." - fi - fi - - # Apply patches - if (( $(find $YNH_EXECUTION_DIR/../sources/patches/ -type f -name "${src_id}-*.patch" 2> /dev/null | wc -l) > "0" )); then - local old_dir=$(pwd) - (cd "$dest_dir" \ - && for p in $YNH_EXECUTION_DIR/../sources/patches/${src_id}-*.patch; do \ - patch -p1 < $p; done) \ - || ynh_die "Unable to apply patches" - cd $old_dir - fi - - # Add supplementary files - if test -e "$YNH_EXECUTION_DIR/../sources/extra_files/${src_id}"; then - cp -a $YNH_EXECUTION_DIR/../sources/extra_files/$src_id/. "$dest_dir" - fi - -} - -# Check availability of a web path -# -# example: ynh_webpath_available some.domain.tld /coffee -# -# usage: ynh_webpath_available domain path -# | arg: domain - the domain/host of the url -# | arg: path - the web path to check the availability of -ynh_webpath_available () { - local domain=$1 - local path=$2 - sudo yunohost domain url-available $domain $path -} - -# Register/book a web path for an app -# -# example: ynh_webpath_register wordpress some.domain.tld /coffee -# -# usage: ynh_webpath_register app domain path -# | arg: app - the app for which the domain should be registered -# | arg: domain - the domain/host of the web path -# | arg: path - the web path to be registered -ynh_webpath_register () { - local app=$1 - local domain=$2 - local path=$3 - sudo yunohost app register-url $app $domain $path -} - -# Calculate and store a file checksum into the app settings -# -# $app should be defined when calling this helper -# -# usage: ynh_store_file_checksum file -# | arg: file - The file on which the checksum will performed, then stored. -ynh_store_file_checksum () { - local checksum_setting_name=checksum_${1//[\/ ]/_} # Replace all '/' and ' ' by '_' - ynh_app_setting_set $app $checksum_setting_name $(sudo md5sum "$1" | cut -d' ' -f1) -} - -# Verify the checksum and backup the file if it's different -# This helper is primarily meant to allow to easily backup personalised/manually -# modified config files. -# -# $app should be defined when calling this helper -# -# usage: ynh_backup_if_checksum_is_different file -# | arg: file - The file on which the checksum test will be perfomed. -# -# | ret: Return the name a the backup file, or nothing -ynh_backup_if_checksum_is_different () { - local file=$1 - local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_' - local checksum_value=$(ynh_app_setting_get $app $checksum_setting_name) - if [ -n "$checksum_value" ] - then # Proceed only if a value was stored into the app settings - if ! echo "$checksum_value $file" | sudo md5sum -c --status - then # If the checksum is now different - backup_file="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')" - sudo mkdir -p "$(dirname "$backup_file")" - sudo cp -a "$file" "$backup_file" # Backup the current file - echo "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file" >&2 - echo "$backup_file" # Return the name of the backup file - fi - fi -} +pkg_dependencies="build-essential cmake libssl-dev libcurl4-openssl-dev libxml2-dev libxslt-dev imagemagick ghostscript curl libmagickwand-dev git libpq-dev redis-server nodejs postgresql bison " +ruby_build_dependencies="bison libffi-dev libgdbm-dev libncurses5-dev libsqlite3-dev libyaml-dev pkg-config sqlite3 zlib1g-dev libgmp-dev libreadline-dev libssl-dev" diff --git a/scripts/backup b/scripts/backup new file mode 100644 index 0000000..56849fa --- /dev/null +++ b/scripts/backup @@ -0,0 +1,61 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +#Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --weight=1 + +app=$YNH_APP_INSTANCE_NAME + +final_path=$(ynh_app_setting_get --app=$app --key=final_path) + +#================================================= +# STANDARD BACKUP STEPS +#================================================= +# clean folder +rm -rf $final_path/backup +mkdir -p $final_path/backup +#================================================= +# BACKUP DIASPORA DATABASE +#================================================= +ynh_script_progression --message="Backup Diaspora DB..." --weight=10 +db_pass=$(ynh_app_setting_get --app=$app --key=psqlpwd) +dump_file="$final_path/backup/$app.dump" +pg_dump -d "dbname=$app user=$app password=$db_pass host=localhost" -Fc -f $dump_file +ynh_backup --src_path="$dump_file" +#================================================= +# BACKUP DIASPORA UPLOADS +#================================================= +ynh_script_progression --message="Backup uploads..." --weight=10 +if [ -x $final_path/diaspora/public/uploads]; then + ynh_backup --src_path="$final_path/diaspora/public/uploads" +else + echo "uploads folder does not exist. Skipping." +fi + +#================================================= +# BACKUP CONF FILES +#================================================= +ynh_script_progression --message="Backup configuration files of Diaspora..." --weight=10 +ynh_backup --src_path="$final_path/diaspora/config/database.yml" +ynh_backup --src_path="$final_path/diaspora/config/diaspora.yml" + +#================================================= +# END OF SCRIPT +#================================================= +ynh_script_progression --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." --last diff --git a/scripts/install b/scripts/install index a21d371..0144c55 100755 --- a/scripts/install +++ b/scripts/install @@ -1,5 +1,14 @@ #!/bin/bash +# TODO +# - which service to register to ynuhosto? diaspora.target only ? All of them ? +# - backup / restore +# - changeurl ? Is that possible ? or even a good idea ? +# - make an admin automatically +# - integration with ssowat? Or not? How exactly? +# - a setting to enable / disable registration +# - say something about the registration to https://the-federation.info/ + #================================================= # GENERIC START #================================================= @@ -22,7 +31,9 @@ ynh_abort_if_errors domain=$YNH_APP_ARG_DOMAIN path_url=$YNH_APP_ARG_PATH -is_public=$YNH_APP_ARG_IS_PUBLIC +admin=$YNH_APP_ARG_ADMIN +admin_password=$YNH_APP_ARG_ADMIN_PASSWORD +admin_email=$(ynh_user_get_info --username=$admin --key=mail) # This is a multi-instance app, meaning it can be installed several times independently @@ -40,130 +51,155 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= +ynh_script_progression --message="Validating installation parameters..." --time --weight=1 # Normalize the url path syntax path_url=$(ynh_normalize_url_path $path_url) # Check web path availability -ynh_webpath_available $domain $path_url -# Register (book) web path -ynh_webpath_register $app $domain $path_url - +ynh_webpath_available --domain=$domain --path_url=$path_url +# check path availability final_path=/var/www/$app test ! -e "$final_path" || ynh_die "This path already contains a folder" +# Register (book) web path +ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url #================================================= # STORE SETTINGS FROM MANIFEST #================================================= - -ynh_app_setting_set $app domain $domain -ynh_app_setting_set $app path $path_url -ynh_app_setting_set $app is_public $is_public +ynh_script_progression --message="Saving app settings..." --time --weight=1 +ynh_app_setting_set --app=$app --key=domain --value=$domain +ynh_app_setting_set --app=$app --key=path --value=$path_url +ynh_app_setting_set --app=$app --key=final_path --value=$final_path #================================================= # STANDARD MODIFICATIONS #================================================= -# FIND AND OPEN A PORT -#================================================= - -# Find a free port -port=$(ynh_find_port 8095) -# Open this port -yunohost firewall allow --no-upnp TCP $port 2>&1 -ynh_app_setting_set $app port $port #================================================= # INSTALL DEPENDENCIES #================================================= - -ynh_install_app_dependencies build-essential libssl-dev libcurl4-openssl-dev libxml2-dev libxslt-dev imagemagick ghostscript curl libmagickwand-dev git libmysqlclient-dev redis-server nodejs +ynh_script_progression --message="Installing dependencies..." --time --weight=27 +ynh_install_app_dependencies $pkg_dependencies $ruby_build_dependencies #================================================= -# CREATE A MYSQL DATABASE +# CREATE A POSTGRESQL DATABASE #================================================= -# If your app uses a MySQL database, you can use these lines to bootstrap -# a database, an associated user and save the password in app settings - +ynh_script_progression --message="Creating database..." --time --weight=1 db_name=$(ynh_sanitize_dbid $app) -ynh_app_setting_set $app db_name $db_name -ynh_mysql_setup_db $db_name $db_name +ynh_app_setting_set --app=$app --key=db_name --value=$db_name +ynh_psql_test_if_first_run +ynh_psql_setup_db $db_name $db_name +db_pass=$(ynh_app_setting_get --app=$app --key=psqlpwd) #================================================= # CREATE DEDICATED USER #================================================= - +ynh_script_progression --message="Creating user..." --time --weight=1 # Create a system user -ynh_system_user_create $app +ynh_system_user_create --username=$app --home_dir=$final_path --use_shell +mkdir -p $final_path +chown $app:$app $final_path +# SWITCH TO NEW USER UNTIL EOF + +#================================================= +# INSTALL RVM AND RUBY FOR CURRENT USER +#================================================= +ynh_script_progression --message="Installing rvm..." --time --weight=10 +sudo -u $app gpg --import ../conf/piotr.kuczynski\@gmail.com.pgp ../conf/mpapis\@gmail.com.pgp +pushd $final_path +sudo -u $app curl -sSL https://get.rvm.io | sudo -u $app bash -s stable +ynh_script_progression --message="Installing ruby 2.4 (this can take a long time)..." --time --weight=230 +sudo -u $app $final_path/.rvm/bin/rvm autolibs read-fail +sudo -u $app $final_path/.rvm/bin/rvm install 2.4 #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= +# Download, check integrity, unucompress and patch the source from app.src +ynh_script_progression --message="Download the sources..." --time --weight=16 +sudo -u $app git clone https://github.com/diaspora/diaspora.git -b v0.7.13.0 +popd -ynh_app_setting_set $app final_path $final_path -# Download, check integrity, uncompress and patch the source from app.src -su -l $app -s /bin/bash -cd ~ -git clone -b master https://github.com/diaspora/diaspora.git -cd diaspora -config/database.yml -cp config/diaspora.yml -curl -L https://s.diaspora.software/1t | bash -echo [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" | tee ~/.bashrc -gem install bundler -RAILS_ENV=production bin/bundle install --jobs $(nproc) --deployment --without test development --with mysql +#================================================= +# EXPORT VARIABLES FOR TEMPLATING +#================================================= +export app +export domain +export path_url +export db_pass +export final_path +export admin + +#================================================= +# CONFIGURE DIASPORA +#================================================= +ynh_script_progression --message="Configure diaspora..." --time --weight=1 +ynh_render_template ../conf/diaspora.yml $final_path/diaspora/config/diaspora.yml +ynh_render_template ../conf/database.yml $final_path/diaspora/config/database.yml + +#================================================= +# Bundle the ruby app +#================================================= +pushd $final_path/diaspora +ynh_script_progression --message="bundle the app..." --time --weight=1000 +# here we *absolutely* need bash (not dash) because dash does not understand what rvm puts in .profile +# (wtf rvm for assuming everybody uses bash as default shell??) +# we also need a login shell to make sure .profile is loaded +sudo -u $app /bin/bash --login << EOF +rvm use --default 2.4 +rvm 2.4 do gem install bundler:1.17.3 +script/configure_bundler +bin/bundle install --full-index --with=postgresql +EOF +ynh_script_progression --message="Create db schema..." --time --weight=22 +sudo -u $app /bin/bash --login << EOF +RAILS_ENV=production bundle exec rake db:migrate +EOF + +#================================================= +# ASSETS PRECOMPILATION +#================================================= +ynh_script_progression --message="Precompile assets..." --time --weight=400 +sudo -u $app /bin/bash --login << EOF +RAILS_ENV=production bin/rake assets:precompile +EOF +popd #================================================= # NGINX CONFIGURATION #================================================= - +# TODO serve public/ ? # Create a dedicated nginx config +ynh_script_progression --message="configure nginx..." --time --weight=1 ynh_add_nginx_config -#================================================= -# SPECIFIC SETUP -#================================================= - #================================================= # SETUP SYSTEMD #================================================= - # Create a dedicated systemd config -ynh_systemd_config - -#================================================= -# SETUP APPLICATION WITH CURL -#================================================= - -# Set right permissions for curl install -chown -R $app: $final_path - -# Set the app as temporarily public for curl call -ynh_app_setting_set $app unprotected_uris "/" -# Reload SSOwat config -yunohost app ssowatconf - -# Reload Nginx -systemctl reload nginx - -# Installation with curl -ynh_local_curl "/INSTALL_PATH" "key1=value1" "key2=value2" "key3=value3" +# TODO add service in yunohost panel ? +ynh_script_progression --message="configure systemd unit..." --time --weight=1 +ynh_render_template ../conf/diaspora_sidekiq.service /etc/systemd/system/${app}_sidekiq.service +ynh_render_template ../conf/diaspora_web.service /etc/systemd/system/${app}_web.service +ynh_render_template ../conf/diaspora.tmpfiles.d /etc/tmpfiles.d/${app}.conf +ynh_render_template ../conf/diaspora.target /etc/systemd/system/${app}.target +systemctl daemon-reload +systemd-tmpfiles --create +systemctl enable ${app}.target ${app}_sidekiq.service ${app}_web.service +systemctl restart ${app}.target #================================================= # STORE THE CHECKSUM OF THE CONFIG FILE #================================================= - # Calculate and store the config file checksum into the app settings -ynh_store_file_checksum "$final_path/CONFIG_FILE" +ynh_store_file_checksum --file="$final_path/diaspora/config/diaspora.yml" +ynh_store_file_checksum --file="$final_path/diaspora/config/database.yml" #================================================= # GENERIC FINALIZATION #================================================= -# SECURE FILES AND DIRECTORIES -#================================================= - -# Set permissions to app files -chown -R root: $final_path #================================================= # SETUP LOGROTATE @@ -175,26 +211,38 @@ ynh_use_logrotate #================================================= # ADVERTISE SERVICE IN ADMIN PANEL #================================================= - -yunohost service add NAME_INIT.D --log "/var/log/FILE.log" +yunohost service add postgresql --log /var/log/postgresql/postgresql-9.4-main.log --description "PostgreSQL RDBMS" +yunohost service add $app.target\ + --log $final_path/diaspora/log/production.log \ + $final_path/diaspora/log/unicorn-stderr.log\ + $final_path/diaspora/log/unicorn-stdout.log\ + $final_path/diaspora/log/sidekiq.log\ + --description "Diaspora service (unicorn web and sidekiq)" #================================================= # SETUP SSOWAT #================================================= - -if [ $is_public -eq 0 ] -then # Remove the public access - ynh_app_setting_delete $app skipped_uris -fi -# Make app public if necessary -if [ $is_public -eq 1 ] -then - # unprotected_uris allows SSO credentials to be passed anyway. - ynh_app_setting_set $app unprotected_uris "/" -fi +# unprotected_uris allows SSO credentials to be passed anyway. +ynh_app_setting_set $app unprotected_uris "/" #================================================= # RELOAD NGINX #================================================= - +ynh_script_progression --message="Reload nginx..." --time --weight=1 systemctl reload nginx + +#================================================= +# CREATE AN ADMIN +#================================================= +ynh_script_progression --message="Create admin..." --time --weight=1 +pushd $final_path/diaspora +sudo -u diaspora /bin/bash --login << EOF +RAILS_ENV=production bundle exec rails console << END +user = User.build({username: '$admin', email: '$admin_email', password: '$admin_password', password_confirmation: '$admin_password' }) +user.seed_aspects +user.save +Role.add_admin user.person +END +EOF +popd + diff --git a/scripts/remove b/scripts/remove index 4367e39..e151849 100644 --- a/scripts/remove +++ b/scripts/remove @@ -16,7 +16,6 @@ source /usr/share/yunohost/helpers app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get $app domain) -port=$(ynh_app_setting_get $app port) db_name=$(ynh_app_setting_get $app db_name) final_path=$(ynh_app_setting_get $app final_path) @@ -26,8 +25,15 @@ final_path=$(ynh_app_setting_get $app final_path) # STOP AND REMOVE SERVICE #================================================= -# Remove the dedicated systemd config -ynh_remove_systemd_config +yunohost service remove $app.target +systemctl stop ${app}.target ${app}_sidekiq.service ${app}_web.service +systemctl disable ${app}.target ${app}_sidekiq.service ${app}_web.service +ynh_secure_remove --file="/etc/systemd/system/${app}_web.service" +ynh_secure_remove --file="/etc/systemd/system/${app}_sidekiq.service" +ynh_secure_remove --file="/etc/tmpfiles.d/${app}.conf" +ynh_secure_remove --file="/etc/systemd/system/${app}.target" +ynh_secure_remove --file="/run/${app}" +systemctl daemon-reload #================================================= # REMOVE SERVICE FROM ADMIN PANEL @@ -39,6 +45,13 @@ then yunohost service remove $app fi +#================================================= +# REMOVE THE POSTGRESQL DATABASE +#================================================= + +# Remove a database if it exists, along with the associated user +ynh_psql_remove_db $db_name $db_name + #================================================= # REMOVE DEPENDENCIES #================================================= @@ -46,20 +59,6 @@ fi # Remove metapackage and its dependencies ynh_remove_app_dependencies -#================================================= -# REMOVE THE MYSQL DATABASE -#================================================= - -# Remove a database if it exists, along with the associated user -ynh_mysql_remove_db $db_name $db_name - -#================================================= -# REMOVE APP MAIN DIR -#================================================= - -# Remove the app directory securely -ynh_secure_remove "$final_path" - #================================================= # REMOVE NGINX CONFIGURATION #================================================= @@ -67,45 +66,14 @@ ynh_secure_remove "$final_path" # Remove the dedicated nginx config ynh_remove_nginx_config -#================================================= -# REMOVE PHP-FPM CONFIGURATION -#================================================= - -# Remove the dedicated php-fpm config -ynh_remove_fpm_config - #================================================= # REMOVE LOGROTATE CONFIGURATION #================================================= # Remove the app-specific logrotate config +# TODO setup logrotate ? ynh_remove_logrotate -#================================================= -# CLOSE A PORT -#================================================= - -if yunohost firewall list | grep -q "\- $port$" -then - echo "Close port $port" - yunohost firewall disallow TCP $port 2>&1 -fi - -#================================================= -# SPECIFIC REMOVE -#================================================= -# REMOVE THE CRON FILE -#================================================= - -# Remove a cron file -ynh_secure_remove "/etc/cron.d/$app" - -# Remove a directory securely -ynh_secure_remove "/etc/$app/" - -# Remove the log files -ynh_secure_remove "/var/log/$app/" - #================================================= # GENERIC FINALIZATION #================================================= @@ -113,4 +81,14 @@ ynh_secure_remove "/var/log/$app/" #================================================= # Delete a system user +# because we use gpg, sometimes rogue processes (gpg an d dirmngr) stays a bit, +# preventing the deletion of the user. Hence we kill all processes belonging to $app +pkill -9 -u `id -u $app` ynh_system_user_delete $app + +#================================================= +# REMOVE APP MAIN DIR +#================================================= +# Remove the app directory securely +ynh_secure_remove "$final_path" + diff --git a/scripts/restore b/scripts/restore new file mode 100644 index 0000000..0564351 --- /dev/null +++ b/scripts/restore @@ -0,0 +1,40 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading settings..." --time --weight=1 + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) +db_user=$db_name + +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= +ynh_script_progression --message="Validating restoration parameters..." --time --weight=1 + +ynh_webpath_available --domain=$domain --path_url=$path_url \ + || ynh_die --message="Path not available: ${domain}${path_url}" +test ! -d $final_path \ + || ynh_die --message="There is already a directory: $final_path " + diff --git a/scripts/upgrade b/scripts/upgrade index 0fd088a..264a496 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,20 +1,31 @@ -#!/bin/sh +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +# IMPORT GENERIC HELPERS +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME # Retrieve arguments -domain=$(sudo yunohost app setting diaspora domain) -admin=$(sudo yunohost app setting diaspora admin) -final_path=$(sudo yunohost app setting diaspora final_path) +domain=$(ynh_app_setting_get --app $app --key domain) +admin=$(ynh_app_setting_get --app $app --key admin) +final_path=$(ynh_app_setting_get --app $app --key final_path) -sudo service diaspora_ynh stop -sleep 3 +ynh_abort_if_errors -sudo cp ../conf/diaspora_ynh /etc/init.d/diaspora_ynh -sudo chmod 754 /etc/init.d/diaspora_ynh - -sudo su - diaspora -c "rvm get stable" -sudo su - diaspora -c "git checkout Gemfile.lock db/schema.rb ; git pull" -sudo su - diaspora -c "bundle" -sudo su - diaspora -c "RAILS_ENV=production bundle exec rake db:migrate" -sudo su - diaspora -c "RAILS_ENV=production bundle exec rake tmp:cache:clear assets:precompile" - -sudo service diaspora_ynh start +upgrade_type=$(ynh_check_app_version_changed) +# nothing to do yet!! +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + # do something! + echo "to be implemented" +fi