From d5061d363371bfa26e648e2e945ad95f59c4f697 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Fri, 21 May 2021 14:13:08 +0200 Subject: [PATCH] First commit --- LICENSE | 674 +++++++++++++++++++++++++++++++++++ README.md | 60 ++++ README_fr.md | 60 ++++ check_process | 26 ++ conf/amd64.src | 6 + conf/arm5.src | 6 + conf/arm6.src | 6 + conf/arm64.src | 6 + conf/arm7.src | 6 + conf/miniflux.conf | 6 + conf/nginx.conf | 18 + conf/systemd.service | 13 + doc/DISCLAIMER.md | 0 doc/screenshots/overview.png | Bin 0 -> 59531 bytes manifest.json | 66 ++++ scripts/_common.sh | 48 +++ scripts/backup | 64 ++++ scripts/change_url | 125 +++++++ scripts/install | 165 +++++++++ scripts/remove | 92 +++++ scripts/restore | 123 +++++++ scripts/upgrade | 149 ++++++++ 22 files changed, 1719 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 README_fr.md create mode 100644 check_process create mode 100644 conf/amd64.src create mode 100644 conf/arm5.src create mode 100644 conf/arm6.src create mode 100644 conf/arm64.src create mode 100644 conf/arm7.src create mode 100644 conf/miniflux.conf create mode 100644 conf/nginx.conf create mode 100644 conf/systemd.service create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/screenshots/overview.png create mode 100644 manifest.json create mode 100644 scripts/_common.sh create mode 100644 scripts/backup create mode 100644 scripts/change_url create mode 100644 scripts/install create mode 100644 scripts/remove create mode 100644 scripts/restore create mode 100644 scripts/upgrade diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bcb6d6a --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# Miniflux for YunoHost + +[![Integration level](https://dash.yunohost.org/integration/miniflux.svg)](https://dash.yunohost.org/appci/app/miniflux) ![](https://ci-apps.yunohost.org/ci/badges/miniflux.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/miniflux.maintain.svg) +[![Install Simple Torrent with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=miniflux/) + +*[Lire ce readme en français.](./README_fr.md)* + +> *This package allows you to install Miniflux quickly and simply on a YunoHost server. +If you don't have YunoHost, please consult [the guide](https://yunohost.org/install) to learn how to install it.* + +## Overview + +Miniflux is a minimalist and opinionated feed reader. + +**Shipped version:** 2.0.30 + +## Screenshots + +![](https://miniflux.app/images/overview.png) + +## Configuration + +Most of the items can be edited in Web-UI on the fly in the config board. + +You can also configure Miniflux by editing this file `/etc/miniflux.conf` using the [documentation](https://miniflux.app/docs/configuration.html). + +## Documentation + + * Official documentation: https://miniflux.app/docs/index.html + +## YunoHost specific features + +#### Multi-user support + +* Is LDAP supported? **No** +* Can the app be used by multiple users? **No** + +#### Supported architectures + +* x86-64 - [![Build Status](https://ci-apps.yunohost.org/ci/logs/miniflux.svg)](https://ci-apps.yunohost.org/ci/apps/miniflux/) +* ARMv8-A - [![Build Status](https://ci-apps-arm.yunohost.org/ci/logs/miniflux.svg)](https://ci-apps-arm.yunohost.org/ci/apps/miniflux/) + +## Links + + * Report a bug: https://github.com/YunoHost-Apps/miniflux_ynh/issues + * Upstream app repository: https://github.com/miniflux/v2 + * YunoHost website: https://yunohost.org/ + +--- + +## Developer info + +Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/miniflux_ynh/tree/testing). + +To try the testing branch, please proceed like that. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/miniflux_ynh/tree/testing --debug +or +sudo yunohost app upgrade miniflux -u https://github.com/YunoHost-Apps/miniflux_ynh/tree/testing --debug +``` diff --git a/README_fr.md b/README_fr.md new file mode 100644 index 0000000..60141df --- /dev/null +++ b/README_fr.md @@ -0,0 +1,60 @@ +# Miniflux pour YunoHost + +[![Niveau d'intégration](https://dash.yunohost.org/integration/miniflux.svg)](https://dash.yunohost.org/appci/app/miniflux) ![](https://ci-apps.yunohost.org/ci/badges/miniflux.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/miniflux.maintain.svg) +[![Installer Miniflux avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=miniflux) + +*[Read this readme in english.](./README.md)* + +> *Ce package vous permet d'installer Miniflux rapidement et simplement sur un serveur YunoHost. +Si vous n'avez pas YunoHost, consultez [le guide](https://yunohost.org/install) pour apprendre comment l'installer.* + +## Vue d'ensemble + +Miniflux est un agrégateur de flux RSS minimaliste. + +**Version incluse :** 2.0.30 + +## Captures d'écran + +![](https://miniflux.app/images/overview.png) + +## Configuration + +La plupart des éléments peuvent être modifiés à la volée dans Web-UI dans la page de configuration. + +Vous pouvez configurer Simple Torrent en modifiant le fichier `/etc/miniflux.conf` en vous aidant de la [documentation](https://miniflux.app/docs/configuration.html). + +## Documentation + + * Documentation officielle : https://miniflux.app/docs/index.html + +## Caractéristiques spécifiques YunoHost + +#### Support multi-utilisateur + +* L'authentification LDAP est-elle prise en charge ? **Non** +* L'application peut-elle être utilisée par plusieurs utilisateurs ? **Non** + +#### Architectures supportées + +* x86-64 - [![Build Status](https://ci-apps.yunohost.org/ci/logs/miniflux.svg)](https://ci-apps.yunohost.org/ci/apps/miniflux/) +* ARMv8-A - [![Build Status](https://ci-apps-arm.yunohost.org/ci/logs/miniflux.svg)](https://ci-apps-arm.yunohost.org/ci/apps/miniflux/) + +## Liens + + * Signaler un bug : https://github.com/YunoHost-Apps/miniflux_ynh/issues + * Dépôt de l'application principale : https://github.com/miniflux/v2 + * Site web YunoHost : https://yunohost.org/ + +--- + +## Informations pour les développeurs + +Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/miniflux_ynh/tree/testing). + +Pour essayer la branche testing, procédez comme suit. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/miniflux_ynh/tree/testing --debug +ou +sudo yunohost app upgrade miniflux -u https://github.com/YunoHost-Apps/miniflux/tree/testing --debug +``` diff --git a/check_process b/check_process new file mode 100644 index 0000000..0e2363c --- /dev/null +++ b/check_process @@ -0,0 +1,26 @@ +;; Test complet + ; Manifest + domain="domain.tld" + path="/path" + is_public=1 + admin="john" + password="password" + ; Checks + pkg_linter=1 + setup_sub_dir=1 + setup_root=1 + setup_nourl=0 + setup_private=1 + setup_public=1 + upgrade=1 + #upgrade=1 from_commit= + backup_restore=1 + multi_instance=0 + change_url=1 +;;; Options +Email= +Notification=none +;;; Upgrade options + ; commit= + name= + manifest_arg=domain=DOMAIN&path=PATH&admin=USER&language=fr&is_public=1&password=pass&port=4533& \ No newline at end of file diff --git a/conf/amd64.src b/conf/amd64.src new file mode 100644 index 0000000..0f5a99e --- /dev/null +++ b/conf/amd64.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/miniflux/v2/releases/download/2.0.30/miniflux-linux-amd64 +SOURCE_SUM=9f099c93b6b1a6f0b97e5954c95116a4cd760aed25250596e863b6cfad633b03 +SOURCE_SUM_PRG=sha256sum +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME=miniflux +SOURCE_EXTRACT=false \ No newline at end of file diff --git a/conf/arm5.src b/conf/arm5.src new file mode 100644 index 0000000..c97be13 --- /dev/null +++ b/conf/arm5.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/miniflux/v2/releases/download/2.0.30/miniflux-linux-armv5 +SOURCE_SUM=ece08f6bf86a4b86de13dba5e1641f12d3b6e4e60d42c343a8953eb22b853c6b +SOURCE_SUM_PRG=sha256sum +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME=miniflux +SOURCE_EXTRACT=false \ No newline at end of file diff --git a/conf/arm6.src b/conf/arm6.src new file mode 100644 index 0000000..8db4709 --- /dev/null +++ b/conf/arm6.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/miniflux/v2/releases/download/2.0.30/miniflux-linux-armv6 +SOURCE_SUM=ffb71c66ad8f3a201c68482a67a9116cbfc5d02b859989063c30881ed56ef1c7 +SOURCE_SUM_PRG=sha256sum +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME=miniflux +SOURCE_EXTRACT=false \ No newline at end of file diff --git a/conf/arm64.src b/conf/arm64.src new file mode 100644 index 0000000..4690d06 --- /dev/null +++ b/conf/arm64.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/miniflux/v2/releases/download/2.0.30/miniflux-linux-arm64 +SOURCE_SUM=33850fa88696eeb7fe0dd14242608c0b71764e0c91130af913bc0adbf9551315 +SOURCE_SUM_PRG=sha256sum +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME=miniflux +SOURCE_EXTRACT=false \ No newline at end of file diff --git a/conf/arm7.src b/conf/arm7.src new file mode 100644 index 0000000..859c88b --- /dev/null +++ b/conf/arm7.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/miniflux/v2/releases/download/2.0.30/miniflux-linux-armv7 +SOURCE_SUM=f30ed0538c36d11fd167d8c430f1c32546c93a8223bc0a85c061e5658d205cda +SOURCE_SUM_PRG=sha256sum +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME=miniflux +SOURCE_EXTRACT=false \ No newline at end of file diff --git a/conf/miniflux.conf b/conf/miniflux.conf new file mode 100644 index 0000000..8102b7c --- /dev/null +++ b/conf/miniflux.conf @@ -0,0 +1,6 @@ +LISTEN_ADDR=127.0.0.1:__PORT__ +DATABASE_URL=postgres://__DB_NAME__:__DB_PWD__@localhost/__DB_NAME__?sslmode=disable +RUN_MIGRATIONS=1 +CREATE_ADMIN=1 +ADMIN_USERNAME=__ADMIN__ +ADMIN_PASSWORD=__PASSWORD__ \ No newline at end of file diff --git a/conf/nginx.conf b/conf/nginx.conf new file mode 100644 index 0000000..f74bf7a --- /dev/null +++ b/conf/nginx.conf @@ -0,0 +1,18 @@ +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; +location __PATH__/ { + + # Force usage of https + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } + + proxy_pass http://127.0.0.1:__PORT__/; + proxy_redirect off; + proxy_set_header Host $host; + 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 $scheme; + + # Include SSOWAT user panel. + include conf.d/yunohost_panel.conf.inc; +} diff --git a/conf/systemd.service b/conf/systemd.service new file mode 100644 index 0000000..5789aed --- /dev/null +++ b/conf/systemd.service @@ -0,0 +1,13 @@ +[Unit] +Description=Miniflux Service +Documentation=https://miniflux.app/docs/#database-connection-parameters + +[Service] +User=__APP__ +#Group=__APP__ +ExecStart=__FINALPATH__/__APP__ -config-file=__FINALPATH__/__APP__.conf +EnvironmentFile=__FINALPATH__/__APP__.conf +NonBlocking=true + +[Install] +WantedBy=multi-user.target diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/overview.png b/doc/screenshots/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..a2df255989e4403b3cf5b8b9281980c7621812a8 GIT binary patch literal 59531 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�sDha>jm9H+{hT|3 zV2XxnMIPjiYfb6A5u&`yDPLy5`H-%U$O{x(p$@zxJ7B`qFX=;->VL9PNfK|4XgU!I zSoTOL2CBp{v?L0cRfZ98N$xtgNGE1FgSN^wq}P5fzlz|G?;?XbnvDUT)!_F;J-t)R zp+7CDCqHn+OD}A{dbIgbfF_Nv7(B{L<^QCXDS6YrJ|&P2yfXy$WKoe)k0xrDmWg1ghra!dM}?lAvzzNGKUL zvaZDxL*yb-Tpvz3$fqovH0%bba6(@(NNJ)R?7yThDiyxUNImSsMG=sn#er9ioxK64 zAiuOSz2mi-z6*XzV1G%PG@a40FPT4AiGLL}@B;OEY|Ddf^ScTqmoM{u4JLDw^8SyT z9=FL53N&h@GVgEQrVWYLNJe?szACe5)8pqh&fxyWCzi$kMXOCP zC0AKSx}UH{`=d%Mr;~OS#g~lHpIvNeO95R&`*7d|wf#tT%yt#*B zr>wRFR}v{nK3C)2RqMv$GAgCc11*l^z)2oL8@`hqDe@e%u9XnN?w7nx{X12iwQbCR zsXQ<&vXZ_|4kv!cMw!FR`am^`BfcsE%DTZp9)9#XY&)r)Gk%!-DgE#J+{Z&8|R6C zj?-@4ZLA&(@9vo_r!afqzhQW%u#aZU?1O*GnxXDJwj_bs)S~^2`ftSbPZvfjPR!eDPLhheK3| zQNZL-L3@N6L0b}yzP?it$;Y%O53LG#&vNW-OHMlJoI-dkB%dN;nHFB^9EFV*&k^oF z)sEc*SfuJSDaf$cL{gG!S>NbRz9hp49Oz80$*$x{+bTmiEQgDCI0E!{;TA9o2Z)x} zs@LaoikfT$*NASdu-tIbivj&$rCkSZibLDQNXY?073%7d2-6!!p32{nW>X7_6!$hB z;nuMWSq1<=4_8JYMOb9b62=^Qw6iK(6>wSHISil3Styhq{H15Ywzb6|{U%?E+@n@xtRQY|aPwjBJx{08_@b7q2HsgDQ>QkuDDt?Pj#U0pO*jPSVa@@V2XYQM zc+||~xu}_K`7^UpEbPgE$!`i1Sf?mrI&{T}jW4y5qSZvy%y`&{#Ij2|X!N2r@s$tK zo*w&|&ThAw6|*oa=0y@bN)Mf^9nU(N^f~Tx*`W;WT}wkI*uafyaX?SY>P2C^>>}rp zBJOltIklNZ-^!EsJ;Wgo_;GCFj2HO7Y z73-AT1XdONw1_+0cN2xVn#6H*BfNCYO@*P`<6vfPODS8hK(eOhkWm~^koCYSQD;IY zeKBQB7I7#<>g^rt*dHJ7PW}R1MA?HfaC0(NRni%X;Yu2N{X-LHthoFehTnwgWLYXypnBOsW*8AA z!+2PVq!}4y!2LAV49&`?mhW+Z_YgDi&joo~Mi(Qm8XRIhI^=n(DS?%aK`@;miEM|y zJ*Aa9qsmK~+|#Qbx0&mM8BlWvwJi{6|HN8J=3grpDmB9+z5QW7W1n){h7f7gMleg0 z-!?A*Ys(%7#;(2n^lOV>tZ*bs5%wW>hY+}J8~#au--Rp3k?-g>>XhO`w?JbyW!Kd* zly{sEosOFqy!VVXKLy%~9)OGb^Wr~8HB-49-NN7R+69xT(ya2c)=t+pCr$Xi>z&%u zrtKP4_-S>+_nKVfnHI<1(GOR!1ohUqy|;Yc3z`RH&?);~7CFy5HRK9Y4?;QaPx^7B z&ijNdXnPnWQnhMXidBez6_gM)FMZyqmsQwEArw~&Grf)g%&iwJxo9O@sJ_N&$p?(| zd!eWD!F#_9ss$~#loBHBF`G(3Af2{X$~5)x{D{9fsqodqJ7g+&#oC%)N)2)CiZ#_9 z1{&>(KdFk+Y}kJp2tZBKB~Xx* zhA_BuoY%ls2ahM=oZY~D21CguLrc)3gW?IYFLSx zx!3yC&ZQ_?nnJ*>@W{et{!m5=hn1R!=P|`dTxa5T|8tvL{$TNTrXJ#dadyS~UqzsB zmrCCF)0D2%{=4K89x?-ox2Z7x{P5oBe@^EOp@09`_2+JQzXF=Sjz7UGoEE}AzyCzN f{#8Umt{n!wtQQ0}(65*Nx= 4.2.4" + }, + "multi_instance": false, + "services": [ + "nginx" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain", + "example": "domain.org" + }, + { + "name": "path", + "type": "path", + "example": "/miniflux", + "default": "/miniflux" + }, + { + "name": "admin", + "type": "user", + "example": "johndoe" + }, + { + "name": "is_public", + "type": "boolean", + "help": { + "en": "If enabled, Miniflux will be accessible by people who do not have an account. This can be changed later via the webadmin.", + "fr": "Si cette case est cochée, Miniflux sera accessible aux personnes n’ayant pas de compte. Vous pourrez changer ceci plus tard via la webadmin." + }, + "default": true + }, + { + "name": "password", + "type": "password", + "help": { + "en": "Must be more than 6 characters.", + "fr": "Doit contenir plus de 6 caractères." + }, + "example": "Choose a password" + } + ] + } +} diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..637d1d0 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +#================================================= +# COMMON VARIABLES +#================================================= + +# dependencies used by the app +pkg_dependencies="postgresql apt-transport-https" + +#================================================= +# PERSONAL HELPERS +#================================================= + +#================================================= +# EXPERIMENTAL HELPERS +#================================================= + +#================================================= +# FUTURE OFFICIAL HELPERS +#================================================= + +# Check the architecture +# +# example: architecture=$(ynh_detect_arch) +# +# usage: ynh_detect_arch +# +# Requires YunoHost version 2.2.4 or higher. + +ynh_detect_arch(){ + local architecture + if [ -n "$(uname -m | grep arm64)" ] || [ -n "$(uname -m | grep aarch64)" ]; then + architecture="arm64" + elif [ -n "$(uname -m | grep 64)" ]; then + architecture="amd64" + elif [ -n "$(uname -m | grep 86)" ]; then + architecture="386" + elif [ -n "$(uname -m | grep armv7)" ]; then + architecture="arm7" + elif [ -n "$(uname -m | grep armv6)" ]; then + architecture="arm6" + elif [ -n "$(uname -m | grep armv5)" ]; then + architecture="arm5" + else + architecture="unknown" + fi + echo $architecture +} diff --git a/scripts/backup b/scripts/backup new file mode 100644 index 0000000..2eaa6b2 --- /dev/null +++ b/scripts/backup @@ -0,0 +1,64 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source ../settings/scripts/_common.sh +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_print_info --message="Loading installation settings..." + +app=$YNH_APP_INSTANCE_NAME + +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +domain=$(ynh_app_setting_get --app=$app --key=domain) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) + +#================================================= +# DECLARE DATA AND CONF FILES TO BACKUP +#================================================= +ynh_print_info --message="Declaring files to be backed up..." + +#================================================= +# BACKUP THE APP MAIN DIR +#================================================= + +ynh_backup --src_path="$final_path" + +#================================================= +# BACKUP THE NGINX CONFIGURATION +#================================================= + +ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# BACKUP SYSTEMD +#================================================= + +ynh_backup --src_path="/etc/systemd/system/$app.service" + +#================================================= +# BACKUP THE POSTGRESQL DATABASE +#================================================= +ynh_print_info --message="Backing up the PostgreSQL database..." + +ynh_psql_dump_db --database="$db_name" > db.sql + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." diff --git a/scripts/change_url b/scripts/change_url new file mode 100644 index 0000000..391f4b0 --- /dev/null +++ b/scripts/change_url @@ -0,0 +1,125 @@ +#!/bin/bash + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +old_domain=$YNH_APP_OLD_DOMAIN +old_path=$YNH_APP_OLD_PATH + +new_domain=$YNH_APP_NEW_DOMAIN +new_path=$YNH_APP_NEW_PATH + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --weight=1 + +# Needed for helper "ynh_add_nginx_config" +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +port=$(ynh_app_setting_get --app=$app --key=port) + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up $app before changing its URL (may take a while)..." --weight=1 + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. + ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" + + # restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# CHECK WHICH PARTS SHOULD BE CHANGED +#================================================= + +change_domain=0 +if [ "$old_domain" != "$new_domain" ] +then + change_domain=1 +fi + +change_path=0 +if [ "$old_path" != "$new_path" ] +then + change_path=1 +fi + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." --weight=1 + +ynh_systemd_action --service_name=$app --action=stop --log_path="/var/log/$app/$app.log" + +#================================================= +# MODIFY URL IN NGINX CONF +#================================================= +ynh_script_progression --message="Updating NGINX web server configuration..." --weight=1 + +nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf + +# Change the path in the NGINX config file +if [ $change_path -eq 1 ] +then + # Make a backup of the original NGINX config file if modified + ynh_backup_if_checksum_is_different --file="$nginx_conf_path" + # Set global variables for NGINX helper + domain="$old_domain" + path_url="$new_path" + # Create a dedicated NGINX config + ynh_add_nginx_config +fi + +# Change the domain for NGINX +if [ $change_domain -eq 1 ] +then + # Delete file checksum for the old conf file location + ynh_delete_file_checksum --file="$nginx_conf_path" + mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf + # Store file checksum for the new config file location + ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +fi + +#================================================= +# GENERIC FINALISATION +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." --weight=1 + +# Start a systemd service +ynh_systemd_action --service_name=$app --action=start --log_path=systemd + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Change of URL completed for $app" --last diff --git a/scripts/install b/scripts/install new file mode 100644 index 0000000..fd48a0a --- /dev/null +++ b/scripts/install @@ -0,0 +1,165 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH +is_public=$YNH_APP_ARG_IS_PUBLIC +architecture=$(ynh_detect_arch) +password=$YNH_APP_ARG_PASSWORD +admin=$YNH_APP_ARG_ADMIN + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= +ynh_script_progression --message="Validating installation parameters..." --weight=1 + +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die --message="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_script_progression --message="Storing installation settings..." --weight=2 + +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=admin --value=$admin + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# FIND AND OPEN A PORT +#================================================= +ynh_script_progression --message="Finding an available port..." --weight=0 + +# Find an available port +port=$(ynh_find_port --port=3000) +ynh_app_setting_set --app=$app --key=port --value=$port + +#================================================= +# INSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Installing dependencies..." --weight=20 + +ynh_exec_warn_less ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --weight=1 + +# Create a system user +ynh_system_user_create --username=$app --home_dir=$final_path + +#================================================= +# CREATE A POSTGRESQL DATABASE +#================================================= +ynh_script_progression --message="Creating a PostgreSQL database..." --weight=2 + +db_name=$(ynh_sanitize_dbid --db_name=$app) +ynh_app_setting_set --app=$app --key=db_name --value=$db_name +ynh_psql_test_if_first_run +ynh_psql_setup_db --db_user=$db_name --db_name=$db_name + +ynh_psql_execute_as_root --sql="CREATE EXTENSION hstore;" --database=$db_name + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= +ynh_script_progression --message="Setting up source files..." --weight=1 + +ynh_app_setting_set --app=$app --key=final_path --value=$final_path +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source --dest_dir="$final_path" --source_id="$architecture" + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chmod +x "$final_path/miniflux" +chown -R $app:www-data "$final_path" + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring NGINX web server..." --weight=3 + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# ADD A CONFIGURATION +#================================================= +ynh_script_progression --message="Adding a configuration file..." --weight=1 + +ynh_add_config --template="../conf/miniflux.conf" --destination="$final_path/miniflux.conf" + +chmod 600 "$final_path/miniflux.conf" + +#================================================= +# SETUP SYSTEMD +#================================================= +ynh_script_progression --message="Configuring a systemd service..." --weight=1 + +ynh_add_systemd_config + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 + +yunohost service add $app --description="Minimalist feed reader" --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." --weight=2 + +# Start a systemd service +ynh_systemd_action --service_name=$app --action=start --log_path=systemd --line_match="Listening on" + +#================================================= +# SETUP SSOWAT +#================================================= +ynh_script_progression --message="Configuring permissions..." --weight=1 + +# Make app public if necessary or protect it +if [ $is_public -eq 1 ] +then + ynh_permission_update --permission="main" --add="visitors" +fi + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --weight=2 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Installation of $app completed" --last diff --git a/scripts/remove b/scripts/remove new file mode 100644 index 0000000..2dd7723 --- /dev/null +++ b/scripts/remove @@ -0,0 +1,92 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --weight=1 + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get --app=$app --key=domain) +port=$(ynh_app_setting_get --app=$app --key=port) +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 + +#================================================= +# STANDARD REMOVE +#================================================= +# REMOVE SERVICE INTEGRATION IN YUNOHOST +#================================================= + +# Remove the service from the list of services known by YunoHost (added from `yunohost service add`) +if ynh_exec_warn_less yunohost service status $app >/dev/null +then + ynh_script_progression --message="Removing $app service..." --weight=1 + yunohost service remove $app +fi + +#================================================= +# STOP AND REMOVE SERVICE +#================================================= +ynh_script_progression --message="Stopping and removing the systemd service..." --weight=1 + +# Remove the dedicated systemd config +ynh_remove_systemd_config + +#================================================= +# REMOVE THE POSTGRESQL DATABASE +#================================================= +ynh_script_progression --message="Removing the PostgreSQL database..." --weight=2 + +# Remove a database if it exists, along with the associated user +ynh_psql_remove_db --db_user=$db_user --db_name=$db_name + +#================================================= +# REMOVE DEPENDENCIES +#================================================= +ynh_script_progression --message="Removing dependencies..." --weight=1 + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# REMOVE APP MAIN DIR +#================================================= +ynh_script_progression --message="Removing $app main directory..." --weight=6 + +# Remove the app directory securely +ynh_secure_remove --file="$final_path" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Removing NGINX web server configuration..." --weight=5 + +# Remove the dedicated NGINX config +ynh_remove_nginx_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= +ynh_script_progression --message="Removing the dedicated system user..." --weight=1 + +# Delete a system user +ynh_system_user_delete --username=$app + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Removal of $app completed" --last diff --git a/scripts/restore b/scripts/restore new file mode 100644 index 0000000..be934f7 --- /dev/null +++ b/scripts/restore @@ -0,0 +1,123 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source ../settings/scripts/_common.sh +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..." --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 +db_pwd=$(ynh_app_setting_get --app=$app --key=psqlpwd) + +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= +ynh_script_progression --message="Validating restoration parameters..." --weight=2 + +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 " + +#================================================= +# STANDARD RESTORATION STEPS +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the NGINX configuration..." --weight=1 + +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# RECREATE THE DEDICATED USER +#================================================= +ynh_script_progression --message="Recreating the dedicated system user..." --weight=1 + +# Create the dedicated user (if not existing) +ynh_system_user_create --username=$app --home_dir="$final_path" + +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= +ynh_script_progression --message="Restoring $app main directory..." --weight=4 + +ynh_restore_file --origin_path="$final_path" + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:www-data "$final_path" + +#================================================= +# REINSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Reinstalling dependencies..." --weight=6 + +# Define and install dependencies +ynh_exec_warn_less ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# RESTORE THE POSTGRESQL DATABASE +#================================================= +ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=6 + +ynh_psql_test_if_first_run +ynh_psql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd +ynh_psql_execute_file_as_root --file="./db.sql" --database=$db_name + +#================================================= +# RESTORE SYSTEMD +#================================================= +ynh_script_progression --message="Restoring the systemd configuration..." --weight=5 + +ynh_restore_file --origin_path="/etc/systemd/system/$app.service" +systemctl enable $app.service --quiet + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." + +yunohost service add $app --description="Minimalist feed reader" --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." --weight=1 + +ynh_systemd_action --service_name=$app --action=start --log_path=systemd --line_match="Listening on" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Restoration completed for $app" --last diff --git a/scripts/upgrade b/scripts/upgrade new file mode 100644 index 0000000..9df7672 --- /dev/null +++ b/scripts/upgrade @@ -0,0 +1,149 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --weight=2 + +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) +port=$(ynh_app_setting_get --app=$app --key=port) +peer_port=$(ynh_app_setting_get --app=$app --key=peer_port) +architecture=$(ynh_detect_arch) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) +db_user=$db_name +db_pwd=$(ynh_app_setting_get --app=$app --key=psqlpwd) + +#================================================= +# CHECK VERSION +#================================================= +ynh_script_progression --message="Checking version..." + +upgrade_type=$(ynh_check_app_version_changed) + +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= +ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 + +# Cleaning legacy permissions +if ynh_legacy_permissions_exists; then + ynh_legacy_permissions_delete_all + + ynh_app_setting_delete --app=$app --key=is_public +fi + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up $app before upgrading (may take a while)..." --weight=4 + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." --weight=1 + +ynh_systemd_action --service_name=$app --action=stop --log_path=systemd + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + ynh_script_progression --message="Upgrading source files..." --weight=5 + + # Download, check integrity, uncompress and patch the source from app.src + ynh_setup_source --dest_dir=$final_path --source_id="$architecture" --keep="$final_path/miniflux.conf" +fi + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=2 + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# UPGRADE DEPENDENCIES +#================================================= +ynh_script_progression --message="Upgrading dependencies..." --weight=10 + +ynh_exec_warn_less ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 + +# Create a dedicated user (if not existing) +ynh_system_user_create --username=$app + +#================================================= +# SETUP SYSTEMD +#================================================= +ynh_script_progression --message="Configuring a systemd service..." --weight=2 + +ynh_add_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= +ynh_script_progression --message="Securing files and directories..." + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:www-data "$final_path" + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." + +yunohost service add $app --description="Minimalist feed reader" --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." --weight=1 + +ynh_systemd_action --service_name=$app --action=start --log_path=systemd --line_match="Listening on" + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Upgrade of $app completed" --last