diff --git a/.gitattributes b/.gitattributes
index aeaab8b9..45c10d7b 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,3 +4,5 @@
docs/speeches export-ignore
docs/video export-ignore
docs/src/man7 export-ignore
+bin/build-helper export-ignore
+README-maintainers export-ignore
diff --git a/.gitignore b/.gitignore
index 320d150d..85a8ccc7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ Session.vim
# Temporary
.netrwhist
*~
+*.tmp
# Auto-generated tag files
tags
# Persistent undo
@@ -23,6 +24,8 @@ docs/src/man1/*.1
docs/src/man7/*.7
docs/src/man7/cdist-type__*.rst
docs/src/cdist-reference.rst
+docs/src/cdist-types.rst
+docs/src/cdist.cfg.skeleton
# Ignore cdist cache for version control
/cache/
@@ -33,7 +36,7 @@ cdist/inventory/
# Python: cache, distutils, distribution in general
__pycache__/
*.pyc
-MANIFEST
+/MANIFEST
dist/
cdist/version.py
cdist.egg-info/
@@ -43,6 +46,7 @@ _build/
docs/dist
# Ignore temp files used for signing
+cdist-*.tar
cdist-*.tar.gz
cdist-*.tar.gz.asc
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..e215652c
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,20 @@
+stages:
+ - test
+
+image: code.ungleich.ch:5050/ungleich-public/cdist/cdist-ci:latest
+
+unit_tests:
+ stage: test
+ script:
+ - ./bin/build-helper version
+ - ./bin/build-helper test
+
+pycodestyle:
+ stage: test
+ script:
+ - ./bin/build-helper pycodestyle
+
+shellcheck:
+ stage: test
+ script:
+ - ./bin/build-helper shellcheck
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..14682ad6
--- /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.
+
+ cdist
+ Copyright (C) 2019 ungleich-public
+
+ 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:
+
+ cdist Copyright (C) 2019 ungleich-public
+ 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/Makefile b/Makefile
index 5f03997a..f89ac1e7 100644
--- a/Makefile
+++ b/Makefile
@@ -18,36 +18,30 @@
#
#
-helper=./bin/build-helper
+.PHONY: help
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo "man build only man user documentation"
+ @echo "html build only html user documentation"
+ @echo "docs build both man and html user documentation"
+ @echo "dotman build man pages for types in your ~/.cdist directory"
+ @echo "speeches build speeches pdf files"
+ @echo "install install in the system site-packages directory"
+ @echo "install-user install in the user site-packages directory"
+ @echo "docs-clean clean documentation"
+ @echo "clean clean"
-DOCS_SRC_DIR=docs/src
-SPEECHDIR=docs/speeches
-TYPEDIR=cdist/conf/type
-
-WEBSRCDIR=docs/web
-
-WEBDIR=$$HOME/vcs/www.nico.schottelius.org
-WEBBLOG=$(WEBDIR)/blog
-WEBBASE=$(WEBDIR)/software/cdist
-WEBPAGE=$(WEBBASE).mdwn
-
-CHANGELOG_VERSION=$(shell $(helper) changelog-version)
-CHANGELOG_FILE=docs/changelog
-
-PYTHON_VERSION=cdist/version.py
+DOCS_SRC_DIR=./docs/src
+SPEECHDIR=./docs/speeches
+TYPEDIR=./cdist/conf/type
SPHINXM=make -C $(DOCS_SRC_DIR) man
SPHINXH=make -C $(DOCS_SRC_DIR) html
SPHINXC=make -C $(DOCS_SRC_DIR) clean
-SHELLCHECKCMD=shellcheck -s sh -f gcc -x
-# Skip SC2154 for variables starting with __ since such variables are cdist
-# environment variables.
-SHELLCHECK_SKIP=grep -v ': __.*is referenced but not assigned.*\[SC2154\]'
################################################################################
# Manpages
#
-MAN1DSTDIR=$(DOCS_SRC_DIR)/man1
MAN7DSTDIR=$(DOCS_SRC_DIR)/man7
# Manpages #1: Types
@@ -69,11 +63,28 @@ DOCSREFSH=$(DOCS_SRC_DIR)/cdist-reference.rst.sh
$(DOCSREF): $(DOCSREFSH)
$(DOCSREFSH)
+# Html types list with references
+DOCSTYPESREF=$(MAN7DSTDIR)/cdist-types.rst
+DOCSTYPESREFSH=$(DOCS_SRC_DIR)/cdist-types.rst.sh
+
+$(DOCSTYPESREF): $(DOCSTYPESREFSH)
+ $(DOCSTYPESREFSH)
+
+DOCSCFGSKEL=./configuration/cdist.cfg.skeleton
+
+configskel: $(DOCSCFGSKEL)
+ cp -f "$(DOCSCFGSKEL)" "$(DOCS_SRC_DIR)/"
+
+version:
+ @[ -f "cdist/version.py" ] || { \
+ printf "Missing 'cdist/version.py', please generate it first.\n" && exit 1; \
+ }
+
# Manpages #3: generic part
-man: $(MANTYPES) $(DOCSREF) $(PYTHON_VERSION)
+man: version $(MANTYPES) $(DOCSREF)
$(SPHINXM)
-html: $(MANTYPES) $(DOCSREF) $(PYTHON_VERSION)
+html: version configskel $(MANTYPES) $(DOCSREF) $(DOCSTYPESREF)
$(SPHINXH)
docs: man html
@@ -81,24 +92,6 @@ docs: man html
docs-clean:
$(SPHINXC)
-# Manpages #5: release part
-MANWEBDIR=$(WEBBASE)/man/$(CHANGELOG_VERSION)
-HTMLBUILDDIR=docs/dist/html
-
-docs-dist: html
- rm -rf "${MANWEBDIR}"
- mkdir -p "${MANWEBDIR}"
- # mkdir -p "${MANWEBDIR}/man1" "${MANWEBDIR}/man7"
- # cp ${MAN1DSTDIR}/*.html ${MAN1DSTDIR}/*.css ${MANWEBDIR}/man1
- # cp ${MAN7DSTDIR}/*.html ${MAN7DSTDIR}/*.css ${MANWEBDIR}/man7
- cp -R ${HTMLBUILDDIR}/* ${MANWEBDIR}
- cd ${MANWEBDIR} && git add . && git commit -m "cdist manpages update: $(CHANGELOG_VERSION)" || true
-
-man-latest-link: web-pub
- # Fix ikiwiki, which does not like symlinks for pseudo security
- ssh staticweb.ungleich.ch \
- "cd /home/services/www/nico/nico.schottelius.org/www/software/cdist/man/ && rm -f latest && ln -sf "$(CHANGELOG_VERSION)" latest"
-
# Manpages: .cdist Types
DOT_CDIST_PATH=${HOME}/.cdist
DOTMAN7DSTDIR=$(MAN7DSTDIR)
@@ -111,8 +104,7 @@ DOTMANTYPES=$(subst /man.rst,.rst,$(DOTMANTYPEPREFIX))
$(DOTMAN7DSTDIR)/cdist-type%.rst: $(DOTTYPEDIR)/%/man.rst
ln -sf "$^" $@
-# Manpages #3: generic part
-dotman: $(DOTMANTYPES)
+dotman: version $(DOTMANTYPES)
$(SPHINXM)
################################################################################
@@ -120,7 +112,6 @@ dotman: $(DOTMANTYPES)
#
SPEECHESOURCES=$(SPEECHDIR)/*.tex
SPEECHES=$(SPEECHESOURCES:.tex=.pdf)
-SPEECHESWEBDIR=$(WEBBASE)/speeches
# Create speeches and ensure Toc is up-to-date
$(SPEECHDIR)/%.pdf: $(SPEECHDIR)/%.tex
@@ -130,160 +121,28 @@ $(SPEECHDIR)/%.pdf: $(SPEECHDIR)/%.tex
speeches: $(SPEECHES)
-speeches-dist: speeches
- rm -rf "${SPEECHESWEBDIR}"
- mkdir -p "${SPEECHESWEBDIR}"
- cp ${SPEECHES} "${SPEECHESWEBDIR}"
- cd ${SPEECHESWEBDIR} && git add . && git commit -m "cdist speeches updated" || true
-
################################################################################
-# Website
+# Misc
#
-
-BLOGFILE=$(WEBBLOG)/cdist-$(CHANGELOG_VERSION)-released.mdwn
-
-$(BLOGFILE): $(CHANGELOG_FILE)
- $(helper) blog $(CHANGELOG_VERSION) $(BLOGFILE)
-
-web-blog: $(BLOGFILE)
-
-web-doc:
- # Go to top level, because of cdist.mdwn
- rsync -av "$(WEBSRCDIR)/" "${WEBBASE}/.."
- cd "${WEBBASE}/.." && git add cdist* && git commit -m "cdist doc update" cdist* || true
-
-web-dist: web-blog web-doc
-
-web-pub: web-dist docs-dist speeches-dist
- cd "${WEBDIR}" && make pub
-
-web-release-all: man-latest-link
-web-release-all-no-latest: web-pub
-
-################################################################################
-# Release: Mailinglist
-#
-ML_FILE=.lock-ml
-
-# Only send mail once - lock until new changelog things happened
-$(ML_FILE): $(CHANGELOG_FILE)
- $(helper) ml-release $(CHANGELOG_VERSION)
- touch $@
-
-ml-release: $(ML_FILE)
-
-
-################################################################################
-# pypi
-#
-PYPI_FILE=.pypi-release
-$(PYPI_FILE): man $(PYTHON_VERSION)
- python3 setup.py sdist upload
- touch $@
-
-pypi-release: $(PYPI_FILE)
-################################################################################
-# archlinux
-#
-ARCHLINUX_FILE=.lock-archlinux
-ARCHLINUXTAR=cdist-$(CHANGELOG_VERSION)-1.src.tar.gz
-
-$(ARCHLINUXTAR): PKGBUILD
- umask 022; mkaurball
-
-PKGBUILD: PKGBUILD.in $(PYTHON_VERSION)
- ./PKGBUILD.in $(CHANGELOG_VERSION)
-
-$(ARCHLINUX_FILE): $(ARCHLINUXTAR) $(PYTHON_VERSION)
- burp -c system $(ARCHLINUXTAR)
- touch $@
-
-archlinux-release: $(ARCHLINUX_FILE)
-
-################################################################################
-# Release
-#
-
-$(PYTHON_VERSION) version: .git/refs/heads/master
- $(helper) version
-
-# Code that is better handled in a shell script
-check-%:
- $(helper) $@
-
-release:
- $(helper) $@
-
-################################################################################
-# Cleanup
-#
-
-clean:
+clean: docs-clean
rm -f $(DOCS_SRC_DIR)/cdist-reference.rst
+ rm -f $(DOCS_SRC_DIR)/cdist-types.rst
+ rm -f $(DOCS_SRC_DIR)/cdist.cfg.skeleton
find "$(DOCS_SRC_DIR)" -mindepth 2 -type l \
| xargs rm -f
- make -C $(DOCS_SRC_DIR) clean
-
find * -name __pycache__ | xargs rm -rf
- # Archlinux
- rm -f cdist-*.pkg.tar.xz cdist-*.tar.gz
- rm -rf pkg/ src/
-
- rm -f MANIFEST PKGBUILD
- rm -rf dist/
-
- # Signed release
- rm -f cdist-*.tar.gz
- rm -f cdist-*.tar.gz.asc
-
-distclean: clean
- rm -f cdist/version.py
+ # distutils
+ rm -rf ./build
################################################################################
-# Misc
+# install
#
-# The pub is Nico's "push to all git remotes" way ("make pub")
-pub:
- git push --mirror
+install:
+ python3 setup.py install
-test:
- $(helper) $@
-
-test-remote:
- $(helper) $@
-
-pycodestyle pep8:
- $(helper) $@
-
-shellcheck-global-explorers:
- @find cdist/conf/explorer -type f -exec $(SHELLCHECKCMD) {} + | $(SHELLCHECK_SKIP) || exit 0
-
-shellcheck-type-explorers:
- @find cdist/conf/type -type f -path "*/explorer/*" -exec $(SHELLCHECKCMD) {} + | $(SHELLCHECK_SKIP) || exit 0
-
-shellcheck-manifests:
- @find cdist/conf/type -type f -name manifest -exec $(SHELLCHECKCMD) {} + | $(SHELLCHECK_SKIP) || exit 0
-
-shellcheck-local-gencodes:
- @find cdist/conf/type -type f -name gencode-local -exec $(SHELLCHECKCMD) {} + | $(SHELLCHECK_SKIP) || exit 0
-
-shellcheck-remote-gencodes:
- @find cdist/conf/type -type f -name gencode-remote -exec $(SHELLCHECKCMD) {} + | $(SHELLCHECK_SKIP) || exit 0
-
-shellcheck-scripts:
- @$(SHELLCHECKCMD) scripts/cdist-dump || exit 0
-
-shellcheck-gencodes: shellcheck-local-gencodes shellcheck-remote-gencodes
-
-shellcheck-types: shellcheck-type-explorers shellcheck-manifests shellcheck-gencodes
-
-shellcheck: shellcheck-global-explorers shellcheck-types shellcheck-scripts
-
-shellcheck-type-files:
- @find cdist/conf/type -type f -path "*/files/*" -exec $(SHELLCHECKCMD) {} + | $(SHELLCHECK_SKIP) || exit 0
-
-shellcheck-with-files: shellcheck shellcheck-type-files
+install-user:
+ python3 setup.py install --user
diff --git a/PKGBUILD.in b/PKGBUILD.in
index c967249d..c0188e68 100755
--- a/PKGBUILD.in
+++ b/PKGBUILD.in
@@ -9,7 +9,7 @@ pkgver=$version
pkgrel=1
pkgdesc='A Usable Configuration Management System"'
arch=('any')
-url='http://www.nico.schottelius.org/software/cdist/'
+url='https://www.cdi.st/'
license=('GPL3')
depends=('python>=3.2.0')
source=("http://pypi.python.org/packages/source/c/cdist/cdist-\${pkgver}.tar.gz")
diff --git a/README b/README
index a67e25e3..caf2dac8 100644
--- a/README
+++ b/README
@@ -3,4 +3,5 @@ cdist
cdist is a usable configuration management system.
-For the web documentation have a look at docs/web/.
+For the web documentation have a look at https://www.cdi.st/
+or at docs/src for reStructuredText manual.
diff --git a/README-maintainers b/README-maintainers
new file mode 100644
index 00000000..af57f475
--- /dev/null
+++ b/README-maintainers
@@ -0,0 +1,4 @@
+Maintainers should use ./bin/build-helper script.
+
+Makefile is intended for end users. It can be used for non-maintaining
+targets that can be run from pure source (without git repository).
diff --git a/bin/build-helper b/bin/build-helper
index de4ced71..ed41e438 100755
--- a/bin/build-helper
+++ b/bin/build-helper
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
+# 2016-2019 Darko Poljak (darko.poljak at gmail.com)
#
# This file is part of cdist.
#
@@ -18,17 +19,67 @@
# along with cdist. If not, see .
#
#
-# This file contains the heavy lifting found usually in the Makefile
+# This file contains the heavy lifting found usually in the Makefile.
#
-basedir=${0%/*}/../
-# Change to checkout directory
-cd "$basedir"
+usage() {
+ printf "usage: %s TARGET [TARGET-ARGS...]
+ Available targets:
+ changelog-changes
+ changelog-version
+ check-date
+ check-unittest
+ ml-release
+ archlinux-release
+ pypi-release
+ release-git-tag
+ sign-git-release
+ release
+ test
+ test-remote
+ pycodestyle
+ pep8
+ check-pycodestyle
+ shellcheck-global-explorers
+ shellcheck-type-explorers
+ shellcheck-manifests
+ shellcheck-local-gencodes
+ shellcheck-remote-gencodes
+ shellcheck-scripts
+ shellcheck-gencodes
+ shellcheck-types
+ shellcheck
+ shellcheck-type-files
+ shellcheck-with-files
+ shellcheck-build-helper
+ check-shellcheck
+ version-branch
+ version
+ target-version
+ clean
+ distclean\n" "$1"
+}
-version=$(git describe)
+basename="${0##*/}"
+
+if [ $# -lt 1 ]
+then
+ usage "${basename}"
+ exit 1
+fi
option=$1; shift
+SHELLCHECKCMD="shellcheck -s sh -f gcc -x"
+# Skip SC2154 for variables starting with __ since such variables are cdist
+# environment variables.
+SHELLCHECK_SKIP=': __.*is referenced but not assigned.*\[SC2154\]'
+SHELLCHECKTMP=".shellcheck.tmp"
+
+# Change to checkout directory
+basedir="${0%/*}/../"
+cd "$basedir"
+
case "$option" in
changelog-changes)
if [ "$#" -eq 1 ]; then
@@ -66,8 +117,8 @@ case "$option" in
date_changelog=$(grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/.*: //')
if [ "$date_today" != "$date_changelog" ]; then
- echo "Date in changelog is not today"
- echo "Changelog: $date_changelog"
+ printf "Date in changelog is not today\n"
+ printf "Changelog date: %s\n" "${date_changelog}"
exit 1
fi
;;
@@ -76,54 +127,17 @@ case "$option" in
"$0" test
;;
- blog)
- version=$1; shift
- blogfile=$1; shift
- dir=${blogfile%/*}
- file=${blogfile##*/}
-
-
- cat << eof > "$blogfile"
-[[!meta title="Cdist $version released"]]
-
-Here's a short overview about the changes found in version ${version}:
-
-eof
-
- $0 changelog-changes "$version" >> "$blogfile"
-
- cat << eof >> "$blogfile"
-For more information visit the [[cdist homepage|software/cdist]].
-
-[[!tag cdist config unix]]
-eof
- cd "$dir"
- git add "$file"
- # Allow git commit to fail if there are no changes
- git commit -m "cdist blog update: $version" "$blogfile" || true
- ;;
-
ml-release)
if [ $# -ne 1 ]; then
- echo "$0 ml-release version" >&2
+ printf "%s ml-release version\n" "$0" >&2
exit 1
fi
version=$1; shift
- to_a=cdist
- to_d=l.schottelius.org
- to=${to_a}@${to_d}
-
- from_a=nico-cdist
- from_d=schottelius.org
- from=${from_a}@${from_d}
-
(
cat << eof
-From: Nico -telmich- Schottelius <$from>
-To: cdist mailing list <$to>
-Subject: cdist $version released
+Subject: cdist $version has been released
Hello .*,
@@ -134,25 +148,41 @@ eof
"$0" changelog-changes "$version"
cat << eof
-Cheers,
-
-Nico
-
---
-Automatisation at its best level. With cdist.
eof
- ) | /usr/sbin/sendmail -f "$from" "$to"
+ ) > mailinglist.tmp
;;
+ archlinux-release)
+ if [ $# -ne 1 ]; then
+ printf "%s archlinux-release version\n" "$0" >&2
+ exit 1
+ fi
+ version=$1; shift
+
+ ARCHLINUXTAR="cdist-${version}-1.src.tar.gz"
+ ./PKGBUILD.in "${version}"
+ umask 022
+ mkaurball
+ burp -c system "${ARCHLINUXTAR}"
+ ;;
+
+ pypi-release)
+ # Ensure that pypi release has the right version
+ "$0" version
+
+ make docs-clean
+ make docs
+ python3 setup.py sdist upload
+ ;;
release-git-tag)
target_version=$($0 changelog-version)
- if git rev-parse --verify refs/tags/$target_version 2>/dev/null; then
- echo "Tag for $target_version exists, aborting"
+ if git rev-parse --verify "refs/tags/${target_version}" 2>/dev/null; then
+ printf "Tag for %s exists, aborting\n" "${target_version}"
exit 1
fi
- printf "Enter tag description for ${target_version}: "
- read tagmessage
+ printf "Enter tag description for %s: " "${target_version}"
+ read -r tagmessage
# setup for signed tags:
# gpg --fulL-gen-key
@@ -170,7 +200,8 @@ eof
# gpg --verify
# gpg --no-default-keyring --keyring --verify
# Ensure gpg-agent is running.
- export GPG_TTY=$(tty)
+ GPG_TTY=$(tty)
+ export GPG_TTY
gpg-agent
git tag -s "$target_version" -m "$tagmessage"
@@ -180,14 +211,14 @@ eof
sign-git-release)
if [ $# -lt 2 ]
then
- printf "usage: $0 sign-git-release TAG TOKEN [ARCHIVE]\n"
+ printf "usage: %s sign-git-release TAG TOKEN [ARCHIVE]\n" "$0"
printf " if ARCHIVE is not specified then it is created\n"
exit 1
fi
tag="$1"
if ! git rev-parse -q --verify "${tag}" >/dev/null 2>&1
then
- printf "Tag \"${tag}\" not found.\n"
+ printf "Tag \"%s\" not found.\n" "${tag}"
exit 1
fi
token="$2"
@@ -200,40 +231,44 @@ eof
|| exit 1
# make sure target version is generated
"$0" target-version
- tar -r -f "${archivename}" cdist/version.py || exit 1
+ tar -x -f "${archivename}" || exit 1
+ cp cdist/version.py "cdist-${tag}/cdist/version.py" || exit 1
+ tar -c -f "${archivename}" "cdist-${tag}/" || exit 1
+ rm -r -f "cdist-${tag}/"
gzip "${archivename}" || exit 1
archivename="${archivename}.gz"
fi
gpg --armor --detach-sign "${archivename}" || exit 1
- # make github release
- curl -H "Authorization: token ${token}" \
- --request POST \
- --data "{ \"tag_name\":\"${tag}\", \
- \"target_commitish\":\"master\", \
- \"name\": \"${tag}\", \
- \"body\":\"${tag}\", \
- \"draft\":false, \
- \"prerelease\": false}" \
- "https://api.github.com/repos/ungleich/cdist/releases" || exit 1
+ project="ungleich-public%2Fcdist"
+ sed_cmd='s/^.*"markdown":"\([^"]*\)".*$/\1/'
- # get release ID
- repoid=$(curl "https://api.github.com/repos/ungleich/cdist/releases/tags/${tag}" \
- | python3 -c 'import json; import sys; print(json.loads(sys.stdin.read())["id"])') \
- || exit 1
+ # upload archive
+ response_archive=$(curl -f -X POST \
+ --http1.1 \
+ -H "PRIVATE-TOKEN: ${token}" \
+ -F "file=@${archivename}" \
+ "https://code.ungleich.ch/api/v4/projects/${project}/uploads" \
+ | sed "${sed_cmd}") || exit 1
- # upload archive and then signature
- curl -H "Authorization: token ${token}" \
- -H "Accept: application/vnd.github.manifold-preview" \
- -H "Content-Type: application/x-gtar" \
- --data-binary @${archivename} \
- "https://uploads.github.com/repos/ungleich/cdist/releases/${repoid}/assets?name=${archivename}" \
- || exit 1
- curl -H "Authorization: token ${token}" \
- -H "Accept: application/vnd.github.manifold-preview" \
- -H "Content-Type: application/pgp-signature" \
- --data-binary @${archivename}.asc \
- "https://uploads.github.com/repos/ungleich/cdist/releases/${repoid}/assets?name=${archivename}.asc" \
+ # upload archive signature
+ response_archive_sig=$(curl -f -X POST \
+ --http1.1 \
+ -H "PRIVATE-TOKEN: ${token}" \
+ -F "file=@${archivename}.asc" \
+ "https://code.ungleich.ch/api/v4/projects/${project}/uploads" \
+ | sed "${sed_cmd}") || exit 1
+
+ # make release
+ changelog=$("$0" changelog-changes "$1" | sed 's/^[[:space:]]*//')
+ release_notes=$(
+ printf "%s\n\n%s\n\n**Changelog**\n\n%s\n" \
+ "${response_archive}" "${response_archive_sig}" "${changelog}"
+ )
+ curl -f -X POST \
+ -H "PRIVATE-TOKEN: ${token}" \
+ -F "description=${release_notes}" \
+ "https://code.ungleich.ch/api/v4/projects/${project}/repository/tags/${tag}/release" \
|| exit 1
# remove generated files (archive and asc)
@@ -249,30 +284,30 @@ eof
target_version=$($0 changelog-version)
target_branch=$($0 version-branch)
- echo "Beginning release process for $target_version"
+ printf "Beginning release process for %s\n" "${target_version}"
# First check everything is sane
"$0" check-date
"$0" check-unittest
"$0" check-pycodestyle
- "$0" shellcheck
+ "$0" check-shellcheck
# Generate version file to be included in packaging
"$0" target-version
# Ensure the git status is clean, else abort
if ! git diff-index --name-only --exit-code HEAD ; then
- echo "Unclean tree, see files above, aborting"
+ printf "Unclean tree, see files above, aborting.\n"
exit 1
fi
# Ensure we are on the master branch
masterbranch=yes
if [ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]; then
- echo "Releases are happening from the master branch, aborting"
+ printf "Releases are happening from the master branch, aborting.\n"
- echo "Enter the magic word to release anyway"
- read magicword
+ printf "Enter the magic word to release anyway:"
+ read -r magicword
if [ "$magicword" = "iknowwhatido" ]; then
masterbranch=no
@@ -283,7 +318,7 @@ eof
if [ "$masterbranch" = yes ]; then
# Ensure version branch exists
- if ! git rev-parse --verify refs/heads/$target_branch 2>/dev/null; then
+ if ! git rev-parse --verify "refs/heads/${target_branch}" 2>/dev/null; then
git branch "$target_branch"
fi
@@ -301,20 +336,12 @@ eof
make docs-clean
make docs
- # Generate speeches (indirect check if they build)
- make speeches
-
#############################################################
# Everything green, let's do the release
# Tag the current commit
"$0" release-git-tag
- # sign git tag
- printf "Enter github authentication token: "
- read token
- "$0" sign-git-release "${target_version}" "${token}"
-
# Also merge back the version branch
if [ "$masterbranch" = yes ]; then
git checkout master
@@ -322,41 +349,41 @@ eof
fi
# Publish git changes
- make pub
-
- # publish man, speeches, website
- if [ "$masterbranch" = yes ]; then
- make web-release-all
- else
- make web-release-all-no-latest
- fi
-
- # Ensure that pypi release has the right version
- "$0" version
+ # if you want to have mirror locally then uncomment this and comment below
+ # git push --mirror
+ git push
+ # push also new branch and set up tracking
+ git push -u origin "${target_branch}"
+ # fi
# Create and publish package for pypi
- make pypi-release
+ "$0" pypi-release
- # Archlinux release is based on pypi
- make archlinux-release
+ # sign git tag
+ printf "Enter upstream repository authentication token: "
+ read -r token
+ "$0" sign-git-release "${target_version}" "${token}"
# Announce change on ML
- make ml-release
+ "$0" ml-release "${target_version}"
cat << eof
Manual steps post release:
-
- - linkedin
- - hackernews
- - reddit
+ - cdist-web
+ - send generated mailinglist.tmp mail
- twitter
-
eof
-
;;
test)
- export PYTHONPATH="$(pwd -P)"
+ if [ ! -f "cdist/version.py" ]
+ then
+ printf "cdist/version.py is missing, generate it first.\n"
+ exit 1
+ fi
+
+ PYTHONPATH="$(pwd -P)"
+ export PYTHONPATH
if [ $# -lt 1 ]; then
python3 -m cdist.test
@@ -366,12 +393,20 @@ eof
;;
test-remote)
- export PYTHONPATH="$(pwd -P)"
+ if [ ! -f "cdist/version.py" ]
+ then
+ printf "cdist/version.py is missing, generate it first.\n"
+ exit 1
+ fi
+
+ PYTHONPATH="$(pwd -P)"
+ export PYTHONPATH
+
python3 -m cdist.test.exec.remote
;;
pycodestyle|pep8)
- pycodestyle "${basedir}" "${basedir}/scripts/cdist" | less
+ pycodestyle "${basedir}" "${basedir}/scripts/cdist"
;;
check-pycodestyle)
@@ -379,9 +414,9 @@ eof
printf "\\nPlease review pycodestyle report.\\n"
while true
do
- echo "Continue (yes/no)?"
+ printf "Continue (yes/no)?\n"
any=
- read any
+ read -r any
case "$any" in
yes)
break
@@ -390,20 +425,88 @@ eof
exit 1
;;
*)
- echo "Please answer with 'yes' or 'no' explicitly."
+ printf "Please answer with 'yes' or 'no' explicitly.\n"
;;
esac
done
;;
+ shellcheck-global-explorers)
+ # shellcheck disable=SC2086
+ find cdist/conf/explorer -type f -exec ${SHELLCHECKCMD} {} + | grep -v "${SHELLCHECK_SKIP}" > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-type-explorers)
+ # shellcheck disable=SC2086
+ find cdist/conf/type -type f -path "*/explorer/*" -exec ${SHELLCHECKCMD} {} + | grep -v "${SHELLCHECK_SKIP}" > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-manifests)
+ # shellcheck disable=SC2086
+ find cdist/conf/type -type f -name manifest -exec ${SHELLCHECKCMD} {} + | grep -v "${SHELLCHECK_SKIP}" > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-local-gencodes)
+ # shellcheck disable=SC2086
+ find cdist/conf/type -type f -name gencode-local -exec ${SHELLCHECKCMD} {} + | grep -v "${SHELLCHECK_SKIP}" > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-remote-gencodes)
+ # shellcheck disable=SC2086
+ find cdist/conf/type -type f -name gencode-remote -exec ${SHELLCHECKCMD} {} + | grep -v "${SHELLCHECK_SKIP}" > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-scripts)
+ # shellcheck disable=SC2086
+ ${SHELLCHECKCMD} scripts/cdist-dump scripts/cdist-new-type > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-gencodes)
+ "$0" shellcheck-local-gencodes || exit 1
+ "$0" shellcheck-remote-gencodes || exit 1
+ ;;
+
+ shellcheck-types)
+ "$0" shellcheck-type-explorers || exit 1
+ "$0" shellcheck-manifests || exit 1
+ "$0" shellcheck-gencodes || exit 1
+ ;;
+
shellcheck)
- make helper=${helper} WEBDIR=${WEBDIR} shellcheck
+ "$0" shellcheck-global-explorers || exit 1
+ "$0" shellcheck-types || exit 1
+ "$0" shellcheck-scripts || exit 1
+ ;;
+
+ shellcheck-type-files)
+ # shellcheck disable=SC2086
+ find cdist/conf/type -type f -path "*/files/*" -exec ${SHELLCHECKCMD} {} + | grep -v "${SHELLCHECK_SKIP}" > "${SHELLCHECKTMP}"
+ test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
+ ;;
+
+ shellcheck-with-files)
+ "$0" shellcheck || exit 1
+ "$0" shellcheck-type-files || exit 1
+ ;;
+
+ shellcheck-build-helper)
+ ${SHELLCHECKCMD} ./bin/build-helper
+ ;;
+
+ check-shellcheck)
+ "$0" shellcheck
printf "\\nPlease review shellcheck report.\\n"
while true
do
- echo "Continue (yes/no)?"
+ printf "Continue (yes/no)?\n"
any=
- read any
+ read -r any
case "$any" in
yes)
break
@@ -412,7 +515,7 @@ eof
exit 1
;;
*)
- echo "Please answer with 'yes' or 'no' explicitly."
+ printf "Please answer with 'yes' or 'no' explicitly.\n"
;;
esac
done
@@ -423,16 +526,40 @@ eof
;;
version)
- echo "VERSION = \"$(git describe)\"" > cdist/version.py
+ printf "VERSION = \"%s\"\n" "$(git describe)" > cdist/version.py
;;
target-version)
target_version=$($0 changelog-version)
- echo "VERSION = \"${target_version}\"" > cdist/version.py
+ printf "VERSION = \"%s\"\n" "${target_version}" > cdist/version.py
;;
+ clean)
+ make clean
+
+ # Archlinux
+ rm -f cdist-*.pkg.tar.xz cdist-*.tar.gz
+ rm -rf pkg/ src/
+
+ rm -f MANIFEST PKGBUILD
+ rm -rf dist/
+
+ # Signed release
+ rm -f cdist-*.tar.gz
+ rm -f cdist-*.tar.gz.asc
+
+ # Temp files
+ rm -f ./*.tmp
+ rm -f ./.*.tmp
+ ;;
+
+ distclean)
+ "$0" clean
+ rm -f cdist/version.py
+ ;;
*)
- echo "Unknown helper target $@ - aborting"
+ printf "Unknown target: '%s'.\n" "${option}" >&2
+ usage "${basename}"
exit 1
;;
diff --git a/bin/build-helper.freebsd b/bin/build-helper.freebsd
deleted file mode 100755
index 2c5a54a7..00000000
--- a/bin/build-helper.freebsd
+++ /dev/null
@@ -1,501 +0,0 @@
-#!/bin/sh
-#
-# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
-# 2016 Darko Poljak (darko.poljak at gmail.com)
-#
-# This file is part of cdist.
-#
-# cdist 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.
-#
-# cdist 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 cdist. If not, see .
-#
-#
-# This file contains the heavy lifting found usually in the Makefile
-#
-
-# vars for make
-helper=$0
-
-basedir=${0%/*}/../
-# run_as is used to check how the script is called (by $0 value)
-# currently supported sufixes for $0 are:
-# .freebsd - run as freebsd
-basename=${0##*/}
-run_as=${basename#*.}
-case "$run_as" in
- freebsd)
- to_a=cdist-configuration-management
- to_d=googlegroups.com
- from_a=darko.poljak
- from_d=gmail.com
- ml_name="Darko Poljak"
- ml_sig_name="Darko"
-
- # vars for make
- WEBDIR=../vcs/www.nico.schottelius.org
- ;;
- *)
- to_a=cdist
- to_d=l.schottelius.org
- from_a=nico-cdist
- from_d=schottelius.org
- ml_name="Nico -telmich- Schottelius"
- ml_sig_name="Nico"
-
- # vars for make
- WEBDIR=$$HOME/vcs/www.nico.schottelius.org
- ;;
-esac
-
-# Change to checkout directory
-cd "$basedir"
-
-version=$(git describe)
-
-option=$1; shift
-
-case "$option" in
- print-make-vars)
- printf "helper: ${helper}\n"
- printf "WEBDIR: ${WEBDIR}\n"
- ;;
- print-runas)
- printf "run_as: $run_as\n"
- ;;
- changelog-changes)
- if [ "$#" -eq 1 ]; then
- start=$1
- else
- start="[[:digit:]]"
- fi
-
- end="[[:digit:]]"
-
- awk -F: "BEGIN { start=0 }
- {
- if(start == 0) {
- if (\$0 ~ /^$start/) {
- start = 1
- }
- } else {
- if (\$0 ~ /^$end/) {
- exit
- } else {
- print \$0
- }
- }
- }" "$basedir/docs/changelog"
- ;;
-
- changelog-version)
- # get version from changelog
- grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/:.*//'
- ;;
-
- check-date)
- # verify date in changelog is today
- date_today="$(date +%Y-%m-%d)"
- date_changelog=$(grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/.*: //')
-
- if [ "$date_today" != "$date_changelog" ]; then
- echo "Date in changelog is not today"
- echo "Changelog: $date_changelog"
- exit 1
- fi
- ;;
-
- check-unittest)
- "$0" test
- ;;
-
- blog)
- version=$1; shift
- blogfile=$1; shift
- dir=${blogfile%/*}
- file=${blogfile##*/}
-
-
- cat << eof > "$blogfile"
-[[!meta title="Cdist $version released"]]
-
-Here's a short overview about the changes found in version ${version}:
-
-eof
-
- $0 changelog-changes "$version" >> "$blogfile"
-
- cat << eof >> "$blogfile"
-For more information visit the [[cdist homepage|software/cdist]].
-
-[[!tag cdist config unix]]
-eof
- cd "$dir"
- git add "$file"
- # Allow git commit to fail if there are no changes
- git commit -m "cdist blog update: $version" "$blogfile" || true
- ;;
-
- ml-release)
- if [ $# -ne 1 ]; then
- echo "$0 ml-release version" >&2
- exit 1
- fi
-
- version=$1; shift
-
- to=${to_a}@${to_d}
- from=${from_a}@${from_d}
-
- (
- cat << eof
-From: ${ml_name} <$from>
-To: cdist mailing list <$to>
-Subject: cdist $version released
-
-Hello .*,
-
-cdist $version has been released with the following changes:
-
-eof
-
- "$0" changelog-changes "$version"
- cat << eof
-
-Cheers,
-
-${ml_sig_name}
-
---
-Automatisation at its best level. With cdist.
-eof
- ) | /usr/sbin/sendmail -f "$from" "$to"
- ;;
-
- release-git-tag)
- target_version=$($0 changelog-version)
- if git rev-parse --verify refs/tags/$target_version 2>/dev/null; then
- echo "Tag for $target_version exists, aborting"
- exit 1
- fi
- printf "Enter tag description for ${target_version}: "
- read tagmessage
-
- # setup for signed tags:
- # gpg --fulL-gen-key
- # gpg --list-secret-keys --keyid-format LONG
- # git config --local user.signingkey
- # for exporting pub key:
- # gpg --armor --export > pubkey.asc
- # gpg --output pubkey.gpg --export
- # show tag with signature
- # git show
- # verify tag signature
- # git tag -v
- #
- # gpg verify signature
- # gpg --verify
- # gpg --no-default-keyring --keyring --verify
- # Ensure gpg-agent is running.
- export GPG_TTY=$(tty)
- gpg-agent
-
- git tag -s "$target_version" -m "$tagmessage"
- git push --tags
- ;;
-
- sign-git-release)
- if [ $# -lt 2 ]
- then
- printf "usage: $0 sign-git-release TAG TOKEN [ARCHIVE]\n"
- printf " if ARCHIVE is not specified then it is created\n"
- exit 1
- fi
- tag="$1"
- if ! git rev-parse -q --verify "${tag}" >/dev/null 2>&1
- then
- printf "Tag \"${tag}\" not found.\n"
- exit 1
- fi
- token="$2"
- if [ $# -gt 2 ]
- then
- archivename="$3"
- else
- archivename="cdist-${tag}.tar"
- git archive --prefix="cdist-${tag}/" -o "${archivename}" "${tag}" \
- || exit 1
- # make sure target version is generated
- "$0" target-version
- tar -r -f "${archivename}" cdist/version.py || exit 1
- gzip "${archivename}" || exit 1
- archivename="${archivename}.gz"
- fi
- gpg --armor --detach-sign "${archivename}" || exit 1
-
- # make github release
- curl -H "Authorization: token ${token}" \
- --request POST \
- --data "{ \"tag_name\":\"${tag}\", \
- \"target_commitish\":\"master\", \
- \"name\": \"${tag}\", \
- \"body\":\"${tag}\", \
- \"draft\":false, \
- \"prerelease\": false}" \
- "https://api.github.com/repos/ungleich/cdist/releases" || exit 1
-
- # get release ID
- repoid=$(curl "https://api.github.com/repos/ungleich/cdist/releases/tags/${tag}" \
- | python3 -c 'import json; import sys; print(json.loads(sys.stdin.read())["id"])') \
- || exit 1
-
- # upload archive and then signature
- curl -H "Authorization: token ${token}" \
- -H "Accept: application/vnd.github.manifold-preview" \
- -H "Content-Type: application/x-gtar" \
- --data-binary @${archivename} \
- "https://uploads.github.com/repos/ungleich/cdist/releases/${repoid}/assets?name=${archivename}" \
- || exit 1
- curl -H "Authorization: token ${token}" \
- -H "Accept: application/vnd.github.manifold-preview" \
- -H "Content-Type: application/pgp-signature" \
- --data-binary @${archivename}.asc \
- "https://uploads.github.com/repos/ungleich/cdist/releases/${repoid}/assets?name=${archivename}.asc" \
- || exit 1
-
- # remove generated files (archive and asc)
- if [ $# -eq 2 ]
- then
- rm -f "${archivename}"
- fi
- rm -f "${archivename}.asc"
- ;;
-
- release)
- set -e
- target_version=$($0 changelog-version)
- target_branch=$($0 version-branch)
-
- echo "Beginning release process for $target_version"
-
- # First check everything is sane
- "$0" check-date
- "$0" check-unittest
- "$0" check-pycodestyle
- "$0" shellcheck
-
- # Generate version file to be included in packaging
- "$0" target-version
-
- # Ensure the git status is clean, else abort
- if ! git diff-index --name-only --exit-code HEAD ; then
- echo "Unclean tree, see files above, aborting"
- exit 1
- fi
-
- # Ensure we are on the master branch
- masterbranch=yes
- if [ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]; then
- echo "Releases are happening from the master branch, aborting"
-
- echo "Enter the magic word to release anyway"
- read magicword
-
- if [ "$magicword" = "iknowwhatido" ]; then
- masterbranch=no
- else
- exit 1
- fi
- fi
-
- if [ "$masterbranch" = yes ]; then
- # Ensure version branch exists
- if ! git rev-parse --verify refs/heads/$target_branch 2>/dev/null; then
- git branch "$target_branch"
- fi
-
- # Merge master branch into version branch
- git checkout "$target_branch"
- git merge master
- fi
-
- # Verify that after the merge everything works
- "$0" check-date
- "$0" check-unittest
-
- # Generate documentation (man and html)
- # First, clean old generated docs
- make helper=${helper} WEBDIR=${WEBDIR} docs-clean
- make helper=${helper} WEBDIR=${WEBDIR} docs
-
- # Generate speeches (indirect check if they build)
- make helper=${helper} WEBDIR=${WEBDIR} speeches
-
- #############################################################
- # Everything green, let's do the release
-
- # Tag the current commit
- "$0" release-git-tag
-
- # sign git tag
- printf "Enter github authentication token: "
- read token
- "$0" sign-git-release "${target_version}" "${token}"
-
- # Also merge back the version branch
- if [ "$masterbranch" = yes ]; then
- git checkout master
- git merge "$target_branch"
- fi
-
- # Publish git changes
- case "$run_as" in
- freebsd)
- # if we are not Nico :) then just push, no mirror
- git push
- # push also new branch and set up tracking
- git push -u origin "${target_branch}"
- ;;
- *)
- make helper=${helper} WEBDIR=${WEBDIR} pub
- ;;
- esac
-
- # publish man, speeches, website
- if [ "$masterbranch" = yes ]; then
- make helper=${helper} WEBDIR=${WEBDIR} web-release-all
- else
- make helper=${helper} WEBDIR=${WEBDIR} web-release-all-no-latest
- fi
-
- # Ensure that pypi release has the right version
- "$0" version
-
- # Create and publish package for pypi
- make helper=${helper} WEBDIR=${WEBDIR} pypi-release
-
- case "$run_as" in
- freebsd)
- ;;
- *)
- # Archlinux release is based on pypi
- make archlinux-release
- ;;
- esac
-
- # Announce change on ML
- make helper=${helper} WEBDIR=${WEBDIR} ml-release
-
- cat << eof
-Manual steps post release:
-
- - linkedin
- - hackernews
- - reddit
- - twitter
-
-eof
-
- case "$run_as" in
- freebsd)
- cat < cdist/version.py
- ;;
-
- target-version)
- target_version=$($0 changelog-version)
- echo "VERSION = \"${target_version}\"" > cdist/version.py
- ;;
-
- *)
- echo "Unknown helper target $@ - aborting"
- exit 1
- ;;
-
-esac
diff --git a/cdist/__init__.py b/cdist/__init__.py
index 000a571c..c673b3ba 100644
--- a/cdist/__init__.py
+++ b/cdist/__init__.py
@@ -181,17 +181,40 @@ class CdistObjectError(CdistEntityError):
params, stdout_paths, stderr_paths, subject)
+class CdistObjectExplorerError(CdistEntityError):
+ """
+ Something went wrong while working on a specific
+ cdist object explorer
+ """
+ def __init__(self, cdist_object, explorer_name, explorer_path,
+ stderr_path, subject=''):
+ params = [
+ ('object name', cdist_object.name, ),
+ ('object path', cdist_object.absolute_path, ),
+ ('object source', " ".join(cdist_object.source), ),
+ ('object type', os.path.realpath(
+ cdist_object.cdist_type.absolute_path), ),
+ ('explorer name', explorer_name, ),
+ ('explorer path', explorer_path, ),
+ ]
+ stdout_paths = []
+ stderr_paths = [
+ ('remote', stderr_path, ),
+ ]
+ super().__init__("explorer '{}' of object '{}'".format(
+ explorer_name, cdist_object.name), params, stdout_paths,
+ stderr_paths, subject)
+
+
class InitialManifestError(CdistEntityError):
"""Something went wrong while executing initial manifest"""
def __init__(self, initial_manifest, stdout_path, stderr_path, subject=''):
params = [
('path', initial_manifest, ),
]
- stdout_paths = []
stdout_paths = [
('init', stdout_path, ),
]
- stderr_paths = []
stderr_paths = [
('init', stderr_path, ),
]
@@ -199,6 +222,20 @@ class InitialManifestError(CdistEntityError):
stderr_paths, subject)
+class GlobalExplorerError(CdistEntityError):
+ """Something went wrong while executing global explorer"""
+ def __init__(self, name, path, stderr_path, subject=''):
+ params = [
+ ('name', name, ),
+ ('path', path, ),
+ ]
+ stderr_paths = [
+ ('remote', stderr_path, ),
+ ]
+ super().__init__("global explorer '{}'".format(name),
+ params, [], stderr_paths, subject)
+
+
def file_to_list(filename):
"""Return list from \n seperated file"""
if os.path.isfile(filename):
diff --git a/cdist/argparse.py b/cdist/argparse.py
index 72fc0d0f..611c484a 100644
--- a/cdist/argparse.py
+++ b/cdist/argparse.py
@@ -5,21 +5,24 @@ import logging
import collections
import functools
import cdist.configuration
+import cdist.preos
+import cdist.info
# set of beta sub-commands
BETA_COMMANDS = set(('install', 'inventory', ))
# set of beta arguments for sub-commands
BETA_ARGS = {
- 'config': set(('jobs', 'tag', 'all_tagged_hosts', 'use_archiving', )),
+ 'config': set(('tag', 'all_tagged_hosts', 'use_archiving', )),
}
-EPILOG = "Get cdist at http://www.nico.schottelius.org/software/cdist/"
+EPILOG = "Get cdist at https://code.ungleich.ch/ungleich-public/cdist"
# Parser others can reuse
parser = None
_verbosity_level_off = -2
_verbosity_level = {
+ None: logging.WARNING,
_verbosity_level_off: logging.OFF,
-1: logging.ERROR,
0: logging.WARNING,
@@ -101,7 +104,7 @@ def get_parsers():
name="log level"),
help=('Set the specified verbosity level. '
'The levels, in order from the lowest to the highest, are: '
- 'ERROR (-1), WARNING (0), INFO (1), VERBOSE (2), DEBUG (3) '
+ 'ERROR (-1), WARNING (0), INFO (1), VERBOSE (2), DEBUG (3), '
'TRACE (4 or higher). If used along with -v then -v '
'increases last set value and -l overwrites last set '
'value.'),
@@ -191,8 +194,7 @@ def get_parsers():
name="positive int"),
help=('Operate in parallel in specified maximum number of jobs. '
'Global explorers, object prepare and object run are '
- 'supported. Without argument CPU count is used by default. '
- 'Currently in beta.'),
+ 'supported. Without argument CPU count is used by default. '),
action='store', dest='jobs',
const=multiprocessing.cpu_count())
parser['config_main'].add_argument(
@@ -423,6 +425,9 @@ def get_parsers():
parser['inventory'].set_defaults(
func=cdist.inventory.Inventory.commandline)
+ # PreOS
+ parser['preos'] = parser['sub'].add_parser('preos', add_help=False)
+
# Shell
parser['shell'] = parser['sub'].add_parser(
'shell', parents=[parser['loglevel']])
@@ -432,6 +437,37 @@ def get_parsers():
' should be POSIX compatible shell.'))
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
+ # Info
+ parser['info'] = parser['sub'].add_parser('info')
+ parser['info'].add_argument(
+ '-a', '--all', help='Display all info. This is the default.',
+ action='store_true', default=False)
+ parser['info'].add_argument(
+ '-c', '--conf-dir',
+ help='Add configuration directory (can be repeated).',
+ action='append')
+ parser['info'].add_argument(
+ '-e', '--global-explorers',
+ help='Display info for global explorers.', action='store_true',
+ default=False)
+ parser['info'].add_argument(
+ '-F', '--fixed-string',
+ help='Interpret pattern as a fixed string.', action='store_true',
+ default=False)
+ parser['info'].add_argument(
+ '-f', '--full', help='Display full details.',
+ action='store_true', default=False)
+ parser['info'].add_argument(
+ '-g', '--config-file',
+ help='Use specified custom configuration file.',
+ dest="config_file", required=False)
+ parser['info'].add_argument(
+ '-t', '--types', help='Display info for types.',
+ action='store_true', default=False)
+ parser['info'].add_argument(
+ 'pattern', nargs='?', help='Glob pattern.')
+ parser['info'].set_defaults(func=cdist.info.Info.commandline)
+
for p in parser:
parser[p].epilog = EPILOG
diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks
index 405a273a..24540601 100755
--- a/cdist/conf/explorer/disks
+++ b/cdist/conf/explorer/disks
@@ -1,30 +1,67 @@
#!/bin/sh -e
+#
+# based on previous work by other people, modified by:
+# 2020 Dennis Camera
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+# Finds disks of the system (excl. ram disks, floppy, cdrom)
-os="$( "$__explorer/os" )"
+uname_s="$(uname -s)"
-case "$os" in
- freebsd)
+case $uname_s in
+ FreeBSD)
sysctl -n kern.disks
;;
- openbsd)
- sysctl -n hw.disknames | grep -Eo '[sw]d[0-9]+' | xargs
+ OpenBSD)
+ sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]+'
;;
- netbsd)
- sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]' | xargs
+ NetBSD)
+ PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
+ sysctl -n hw.disknames \
+ | awk 'BEGIN { RS = " " } /^[lsw]d[0-9]+/'
;;
- *)
- # hopefully everything else is linux
- if command -v lsblk > /dev/null
+ Linux)
+ # list of major device numbers toexclude:
+ # ram disks, floppies, cdroms
+ # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
+ ign_majors='1 2 11'
+
+ if command -v lsblk >/dev/null 2>&1
then
- # exclude ram disks, floppies and cdroms
- # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
- lsblk -e 1,2,11 -dno name | xargs
+ lsblk -e "$(echo "$ign_majors" | tr ' ' ',')" -dno name
+ elif test -d /sys/block/
+ then
+ # shellcheck disable=SC2012
+ ls -1 /sys/block/ \
+ | awk -v ign_majors="$(echo "$ign_majors" | tr ' ' '|')" '
+ {
+ devfile = "/sys/block/" $0 "/dev"
+ getline devno < devfile
+ close(devfile)
+ if (devno !~ "^(" ign_majors "):") print
+ }'
else
- # fallback
- find /dev \
- -type b \
- -regex '/dev/\(hd\|sd\|vd\)[a-z]+' \
- -printf '%f '
+ echo "Don't know how to list disks on Linux without lsblk and sysfs." >&2
+ echo 'If you can, please submit a patch.'>&2
fi
;;
-esac
+ *)
+ printf "Don't know how to list disks for %s operating system.\n" "${uname_s}" >&2
+ printf 'If you can please submit a patch\n' >&2
+ ;;
+esac \
+| xargs
diff --git a/cdist/conf/explorer/hostname b/cdist/conf/explorer/hostname
index 7715c6b0..dca004d1 100755
--- a/cdist/conf/explorer/hostname
+++ b/cdist/conf/explorer/hostname
@@ -1,7 +1,6 @@
#!/bin/sh
#
-# 2010-2014 Nico Schottelius (nico-cdist at schottelius.org)
-# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -19,7 +18,12 @@
# along with cdist. If not, see .
#
#
+# Retrieve the running hostname
+#
-if command -v uname >/dev/null; then
- uname -n
+if command -v hostname >/dev/null
+then
+ hostname
+else
+ uname -n
fi
diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init
index 43a66a50..f27c77ef 100755
--- a/cdist/conf/explorer/init
+++ b/cdist/conf/explorer/init
@@ -1,7 +1,8 @@
-#!/bin/sh
+#!/bin/sh -e
#
# 2016 Daniel Heule (hda at sfs.biz)
# Copyright 2017, Philippe Gregoire
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -19,21 +20,423 @@
# along with cdist. If not, see .
#
#
-# Returns the process name of pid 1 ( normaly the init system )
-# for example at linux this value is "init" or "systemd" in most cases
+# Returns the name of the init system (PID 1)
+
+# Expected values:
+# Linux:
+# Adélie Linux:
+# sysvinit+openrc
+# Alpine Linux:
+# busybox-init+openrc
+# ArchLinux:
+# systemd, sysvinit
+# CRUX:
+# sysvinit
+# Debian:
+# systemd, upstart, sysvinit, openrc, ???
+# Devuan:
+# sysvinit, sysvinit+openrc
+# Gentoo:
+# sysvinit+openrc, openrc-init, systemd
+# OpenBMC:
+# systemd
+# OpenWrt:
+# procd, init???
+# RedHat (RHEL, CentOS, Fedora, RedHat Linux, ...):
+# systemd, upstart, upstart-legacy, sysvinit
+# Slackware:
+# sysvinit
+# SuSE:
+# systemd, sysvinit
+# Ubuntu:
+# systemd, upstart, upstart-legacy, sysvinit
+# VoidLinux:
+# runit
#
+# GNU:
+# Debian:
+# sysvinit, hurd-init
+#
+# BSD:
+# {Free,Open,Net}BSD:
+# init
+#
+# Mac OS X:
+# launchd, init+SystemStarter
+#
+# Solaris/Illumos:
+# smf, init???
-uname_s="$(uname -s)"
+# NOTE: init systems can be stacked. This is popular to run OpenRC on top of
+# sysvinit (Gentoo) or busybox-init (Alpine), but can also be used to run runit
+# as a systemd service. This makes init system detection very complicated
+# (which result is expected?) This script tries to untangle some combinations,
+# OpenRC on top of sysv or busybox (X+openrc), but will ignore others (runit as
+# a systemd service)
-case "$uname_s" in
- Linux)
- (pgrep -P0 -l | awk '/^1[ \t]/ {print $2;}') || true
- ;;
- FreeBSD)
- ps -o comm= -p 1 || true
- ;;
- *)
- # return a empty string as unknown value
- echo ""
- ;;
-esac
+# NOTE: When we have no idea, nothing will be printed!
+
+# NOTE:
+# When trying to gather information about the init system make sure to do so
+# without calling the binary! On some systems this triggers a reinitialisation
+# of the system which we don't want (e.g. embedded systems).
+
+
+set -e
+
+KERNEL_NAME=$(uname -s)
+
+KNOWN_INIT_SYSTEMS=$(cat </dev/null 2>&1 || return 1
+ launchctl getenv PATH >/dev/null || return 1
+ echo launchd
+}
+
+check_openrc() {
+ test -f /run/openrc/softlevel || return 1
+ echo openrc
+}
+
+check_procd() (
+ procd_path=${1:-/sbin/procd}
+ test -x "${procd_path}" || return 1
+ grep -q 'procd' "${procd_path}" || return 1
+ echo procd
+)
+
+check_runit() {
+ test -d /run/runit || return 1
+ echo runit
+}
+
+check_smf() {
+ # XXX: Is this the correct way??
+ test -f /etc/svc/volatile/svc_nonpersist.db || return 1
+ echo smf
+}
+
+check_systemd() {
+ # NOTE: sd_booted(3)
+ test -d /run/systemd/system/ || return 1
+ # systemctl --version | sed -e '/^systemd/!d;s/^systemd //'
+ echo systemd
+}
+
+check_systemstarter() {
+ test -d /System/Library/StartupItems/ || return 1
+ test -f /System/Library/StartupItems/LoginWindow/StartupParameters.plist || return 1
+ echo init+SystemStarter
+}
+
+check_sysvinit() (
+ init_path=${1:-/sbin/init}
+ test -x "${init_path}" || return 1
+ grep -q 'INIT_VERSION=sysvinit-[0-9.]*' "${init_path}" || return 1
+
+ # It is quite common to use SysVinit to stack other init systemd
+ # (like OpenRC) on top of it. So we check for that, too.
+ if stacked=$(check_openrc)
+ then
+ echo "sysvinit+${stacked}"
+ else
+ echo sysvinit
+ fi
+ unset stacked
+)
+
+check_upstart() {
+ test -x "$(command -v initctl)" || return 1
+ case $(initctl version)
+ in
+ *'(upstart '*')')
+ if test -d /etc/init
+ then
+ # modern (DBus-based?) upstart >= 0.5
+ echo upstart
+ elif test -d /etc/event.d
+ then
+ # ancient upstart
+ echo upstart-legacy
+ else
+ # whatever...
+ echo upstart
+ fi
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}
+
+find_init_procfs() (
+ # First, check if the required file in procfs exists...
+ test -h /proc/1/exe || return 1
+
+ # Find init executable
+ init_exe=$(ls -l /proc/1/exe 2>/dev/null) || return 1
+ init_exe=${init_exe#* -> }
+
+ if ! test -x "$init_exe"
+ then
+ # On some rare occasions it can happen that the
+ # running init's binary has been replaced. In this
+ # case Linux adjusts the symlink to "X (deleted)"
+
+ # [root@fedora-12 ~]# readlink /proc/1/exe
+ # /sbin/init (deleted)
+ # [root@fedora-12 ~]# ls -l /proc/1/exe
+ # lrwxrwxrwx. 1 root root 0 2020-01-30 23:00 /proc/1/exe -> /sbin/init (deleted)
+
+ init_exe=${init_exe% (deleted)}
+ test -x "$init_exe" || return 1
+ fi
+
+ echo "${init_exe}"
+)
+
+guess_by_path() {
+ case $1
+ in
+ /bin/busybox)
+ check_busybox_init "$1" && return
+ ;;
+ /lib/systemd/systemd)
+ check_systemd "$1" && return
+ ;;
+ /hurd/init)
+ check_hurd_init "$1" && return
+ ;;
+ /sbin/launchd)
+ check_launchd "$1" && return
+ ;;
+ /usr/bin/runit|/sbin/runit)
+ check_runit "$1" && return
+ ;;
+ /sbin/openrc-init)
+ if check_openrc "$1" >/dev/null
+ then
+ echo openrc-init
+ return
+ fi
+ ;;
+ /sbin/procd)
+ check_procd "$1" && return
+ ;;
+ /sbin/init|*/init)
+ # init: it could be anything -> (explicit) no match
+ return 1
+ ;;
+ esac
+
+ # No match
+ return 1
+}
+
+guess_by_comm_name() {
+ case $1
+ in
+ busybox)
+ check_busybox_init && return
+ ;;
+ openrc-init)
+ if check_openrc >/dev/null
+ then
+ echo openrc-init
+ return 0
+ fi
+ ;;
+ init)
+ # init could be anything -> no match
+ return 1
+ ;;
+ *)
+ # Run check function by comm name if available.
+ # Fall back to comm name if either it does not exist or
+ # returns non-zero.
+ if type "check_$1" >/dev/null
+ then
+ "check_$1" && return
+ else
+ echo "$1" ; return 0
+ fi
+ esac
+
+ return 1
+}
+
+check_list() (
+ # List must be a multi-line input on stdin (one name per line)
+ while read -r init
+ do
+ "check_${init}" || continue
+ return 0
+ done
+ return 1
+)
+
+
+# BusyBox's versions of ps and pgrep do not support some options
+# depending on which compile-time options have been used.
+
+find_init_pgrep() {
+ pgrep -P0 -fl 2>/dev/null | awk -F '[[:blank:]]' '$1 == 1 { print $2 }'
+}
+
+find_init_ps() {
+ case $KERNEL_NAME
+ in
+ Darwin)
+ ps -o command -p 1 2>/dev/null | tail -n +2
+ ;;
+ FreeBSD)
+ ps -o args= -p 1 2>/dev/null | cut -d ' ' -f 1
+ ;;
+ Linux)
+ ps -o comm= -p 1 2>/dev/null
+ ;;
+ NetBSD)
+ ps -o comm= -p 1 2>/dev/null
+ ;;
+ OpenBSD)
+ ps -o args -p 1 2>/dev/null | tail -n +2 | cut -d ' ' -f 1
+ ;;
+ *)
+ ps -o args= -p 1 2>/dev/null
+ ;;
+ esac | trim # trim trailing whitespace (some ps like Darwin add it)
+}
+
+find_init() {
+ case $KERNEL_NAME
+ in
+ Linux|GNU|NetBSD)
+ find_init_procfs || find_init_pgrep || find_init_ps
+ ;;
+ FreeBSD)
+ find_init_procfs || find_init_ps
+ ;;
+ OpenBSD)
+ find_init_pgrep || find_init_ps
+ ;;
+ Darwin|SunOS)
+ find_init_ps
+ ;;
+ *)
+ echo "Don't know how to determine init." >&2
+ echo 'Please send a patch.' >&2
+ exit 1
+ esac
+}
+
+# -----
+
+init=$(find_init)
+
+# If we got a path, guess by the path first (fall back to file name if no match)
+# else guess by file name directly.
+# shellcheck disable=SC2015
+{
+ test -x "${init}" \
+ && guess_by_path "${init}" \
+ || guess_by_comm_name "$(basename "${init}")"
+} && exit 0 || true
+
+
+# Guessing based on the file path and name didn’t lead to a definitive result.
+#
+# We go through all of the checks until we find a match. To speed up the
+# process, common cases will be checked first based on the underlying kernel.
+
+{ common_candidates_by_kernel; echo "${KNOWN_INIT_SYSTEMS}"; } \
+ | unique | check_list
diff --git a/cdist/conf/explorer/interfaces b/cdist/conf/explorer/interfaces
index c1f2a57a..aeb55ed0 100755
--- a/cdist/conf/explorer/interfaces
+++ b/cdist/conf/explorer/interfaces
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/sh -e
#
-# 2012 Sébastien Gross
+# 2019 Ander Punnar (ander-at-kvlt-dot-ee)
#
# This file is part of cdist.
#
@@ -17,35 +17,12 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see .
#
-#
-# List all network interfaces in explorer/ifaces. One interface per line.
-#
-# If your OS is not supported please provide a ifconfig output
-#
-# Use ip, if available
-if command -v ip >/dev/null; then
- ip -o link show | sed -n 's/^[0-9]\+: \(.\+\): <.*/\1/p'
- exit 0
-fi
-
-if ! command -v ifconfig >/dev/null; then
- # no ifconfig, nothing we could do
- exit 0
-fi
-
-uname_s="$(uname -s)"
-REGEXP='s/^(.*)(:[[:space:]]*flags=|Link encap).*/\1/p'
-
-case "$uname_s" in
- Darwin)
- ifconfig -a | sed -n -E "$REGEXP"
- ;;
- Linux|*BSD)
- ifconfig -a | sed -n -r "$REGEXP"
- ;;
- *)
- echo "Unsupported ifconfig output for $uname_s" >&2
- exit 1
- ;;
-esac
+if command -v ip >/dev/null
+then
+ ip -o link show | sed -n 's/^[0-9]\+: \(.\+\): <.*/\1/p'
+elif command -v ifconfig >/dev/null
+then
+ ifconfig -a | sed -n -E 's/^(.*)(:[[:space:]]*flags=|Link encap).*/\1/p'
+fi \
+ | sort -u
diff --git a/cdist/conf/explorer/os b/cdist/conf/explorer/os
index d522300c..563fa4cf 100755
--- a/cdist/conf/explorer/os
+++ b/cdist/conf/explorer/os
@@ -145,7 +145,7 @@ esac
if [ -f /etc/os-release ]; then
# already lowercase, according to:
# https://www.freedesktop.org/software/systemd/man/os-release.html
- awk -F= '/^ID=/ {print $2;}' /etc/os-release
+ awk -F= '/^ID=/ { if ($2 ~ /^'"'"'(.*)'"'"'$/ || $2 ~ /^"(.*)"$/) { print substr($2, 2, length($2) - 2) } else { print $2 } }' /etc/os-release
exit 0
fi
diff --git a/cdist/conf/explorer/os_release b/cdist/conf/explorer/os_release
index cfc01004..6489446b 100644
--- a/cdist/conf/explorer/os_release
+++ b/cdist/conf/explorer/os_release
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2018 Adam Dej (dejko.a at gmail.com)
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -21,6 +22,17 @@
# See os-release(5) and http://0pointer.de/blog/projects/os-release
-set +e
+if test -f /etc/os-release
+then
+ # Linux and FreeBSD (usually a symlink)
+ cat /etc/os-release
+elif test -f /usr/lib/os-release
+then
+ # systemd
+ cat /usr/lib/os-release
+elif test -f /var/run/os-release
+then
+ # FreeBSD (created by os-release service)
+ cat /var/run/os-release
+fi
-cat /etc/os-release || cat /usr/lib/os-release || true
diff --git a/cdist/conf/explorer/os_version b/cdist/conf/explorer/os_version
index 4c41695b..1d54ea60 100755
--- a/cdist/conf/explorer/os_version
+++ b/cdist/conf/explorer/os_version
@@ -70,4 +70,7 @@ case "$("$__explorer/os")" in
ubuntu)
lsb_release -sr
;;
-esac
+ alpine)
+ cat /etc/alpine-release
+ ;;
+esac
\ No newline at end of file
diff --git a/cdist/conf/type/__acl/explorer/acl_is b/cdist/conf/type/__acl/explorer/acl_is
index 4dc98c51..a693c023 100755
--- a/cdist/conf/type/__acl/explorer/acl_is
+++ b/cdist/conf/type/__acl/explorer/acl_is
@@ -18,6 +18,14 @@
# along with cdist. If not, see .
#
-if [ -e "/$__object_id" ]
-then getfacl "/$__object_id" | grep -E '^((default:|)(user|group)):[a-z]' || true
+[ ! -e "/$__object_id" ] && exit 0
+
+if ! command -v getfacl > /dev/null
+then
+ echo 'getfacl not available' >&2
+ exit 1
fi
+
+getfacl "/$__object_id" 2>/dev/null \
+ | grep -Eo '^(default:)?(user|group|(mask|other):):[^:][[:graph:]]+' \
+ || true
diff --git a/cdist/conf/type/__acl/explorer/checks b/cdist/conf/type/__acl/explorer/checks
new file mode 100755
index 00000000..70bb0412
--- /dev/null
+++ b/cdist/conf/type/__acl/explorer/checks
@@ -0,0 +1,39 @@
+#!/bin/sh -e
+#
+# 2019 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+# TODO check if filesystem has ACL turned on etc
+
+if [ -f "$__object/parameter/acl" ]
+then
+ grep -E '^(default:)?(user|group):' "$__object/parameter/acl" \
+ | while read -r acl
+ do
+ param="$( echo "$acl" | awk -F: '{print $(NF-2)}' )"
+ check="$( echo "$acl" | awk -F: '{print $(NF-1)}' )"
+
+ [ "$param" = 'user' ] && db=passwd || db="$param"
+
+ if ! getent "$db" "$check" > /dev/null
+ then
+ echo "missing $param '$check'" >&2
+ exit 1
+ fi
+ done
+fi
diff --git a/cdist/conf/type/__hostname/explorer/hostname_file b/cdist/conf/type/__acl/explorer/file_is
similarity index 72%
rename from cdist/conf/type/__hostname/explorer/hostname_file
rename to cdist/conf/type/__acl/explorer/file_is
index 6a00aa9f..096cffd1 100755
--- a/cdist/conf/type/__hostname/explorer/hostname_file
+++ b/cdist/conf/type/__acl/explorer/file_is
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/sh -e
#
-# 2014 Nico Schottelius (nico-cdist at schottelius.org)
+# 2018 Ander Punnar (ander-at-kvlt-dot-ee)
#
# This file is part of cdist.
#
@@ -17,14 +17,15 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see .
#
-#
-# Retrieve the contents of /etc/hostname
-#
-# Almost any distribution
-if [ -f /etc/hostname ]; then
- cat /etc/hostname
-# SuSE
-elif [ -f /etc/HOSTNAME ]; then
- cat /etc/HOSTNAME
+if [ -e "/$__object_id" ]
+then
+ if [ -d "/$__object_id" ]
+ then echo directory
+ elif [ -f "/$__object_id" ]
+ then echo regular
+ else echo other
+ fi
+else
+ echo missing
fi
diff --git a/cdist/conf/type/__acl/gencode-remote b/cdist/conf/type/__acl/gencode-remote
index a59d49e0..e5404a9d 100755
--- a/cdist/conf/type/__acl/gencode-remote
+++ b/cdist/conf/type/__acl/gencode-remote
@@ -18,32 +18,86 @@
# along with cdist. If not, see .
#
+file_is="$( cat "$__object/explorer/file_is" )"
+
+if [ "$file_is" = 'missing' ] \
+ && [ -z "$__cdist_dry_run" ] \
+ && \( [ ! -f "$__object/parameter/file" ] \
+ || [ ! -f "$__object/parameter/directory" ] \)
+then
+ exit 0
+fi
+
os="$( cat "$__global/explorer/os" )"
acl_path="/$__object_id"
acl_is="$( cat "$__object/explorer/acl_is" )"
-acl_should="$( for parameter in user group
-do
- if [ ! -f "$__object/parameter/$parameter" ]
- then continue
- fi
- while read -r l
- do
- echo "$parameter:$l"
+if [ -f "$__object/parameter/source" ]
+then
+ acl_source="$( cat "$__object/parameter/source" )"
- if [ -f "$__object/parameter/default" ]
- then echo "default:$parameter:$l"
- fi
- done < "$__object/parameter/$parameter"
-done )"
+ if [ "$acl_source" = '-' ]
+ then
+ acl_should="$( cat "$__object/stdin" )"
+ else
+ acl_should="$( grep -Ev '^#|^$' "$acl_source" )"
+ fi
+elif [ -f "$__object/parameter/entry" ]
+then
+ acl_should="$( cat "$__object/parameter/entry" )"
+elif [ -f "$__object/parameter/acl" ]
+then
+ acl_should="$( cat "$__object/parameter/acl" )"
+elif
+ [ -f "$__object/parameter/user" ] \
+ || [ -f "$__object/parameter/group" ] \
+ || [ -f "$__object/parameter/mask" ] \
+ || [ -f "$__object/parameter/other" ]
+then
+ acl_should="$( for param in user group mask other
+ do
+ [ ! -f "$__object/parameter/$param" ] && continue
+
+ echo "$param" | grep -Eq 'mask|other' && sep=:: || sep=:
+
+ echo "$param$sep$( cat "$__object/parameter/$param" )"
+ done )"
+else
+ echo 'no parameters set' >&2
+ exit 1
+fi
+
+if [ -f "$__object/parameter/default" ]
+then
+ acl_should="$( echo "$acl_should" \
+ | sed 's/^default://' \
+ | sort -u \
+ | sed 's/\(.*\)/default:\1\n\1/' )"
+fi
+
+if [ "$file_is" = 'regular' ] \
+ && echo "$acl_should" | grep -Eq '^default:'
+then
+ # only directories can have default ACLs,
+ # but instead of error,
+ # let's just remove default entries
+ acl_should="$( echo "$acl_should" | grep -Ev '^default:' )"
+fi
+
+if echo "$acl_should" | awk -F: '{ print $NF }' | grep -Fq 'X'
+then
+ [ "$file_is" = 'directory' ] && rep=x || rep=-
+
+ acl_should="$( echo "$acl_should" | sed "s/\\(.*\\)X/\\1$rep/" )"
+fi
setfacl_exec='setfacl'
if [ -f "$__object/parameter/recursive" ]
then
- if echo "$os" | grep -E 'macosx|netbsd|freebsd|openbsd'
+ if echo "$os" | grep -Fq 'freebsd'
then
echo "$os setfacl do not support recursive operations" >&2
else
@@ -53,29 +107,39 @@ fi
if [ -f "$__object/parameter/remove" ]
then
- if echo "$os" | grep 'solaris'
- then
- # Solaris setfacl behaves differently.
- # We will not support Solaris for now, because no way to test it.
- # But adding support should be easy (use -s instead of -m on modify).
- echo "$os setfacl do not support -x flag for ACL remove" >&2
- else
- echo "$acl_is" | while read -r acl
- do
- if echo "$acl_should" | grep -Fq "$acl"
- then continue
- fi
+ echo "$acl_is" | while read -r acl
+ do
+ # skip wanted ACL entries which already exist
+ # and skip mask and other entries, because we
+ # can't actually remove them, but only change.
+ if echo "$acl_should" | grep -Eq "^$acl" \
+ || echo "$acl" | grep -Eq '^(default:)?(mask|other)'
+ then continue
+ fi
- no_bits="$( echo "$acl" | sed -r 's/:[rwx-]+$//' )"
+ if echo "$os" | grep -Fq 'freebsd'
+ then
+ remove="$acl"
+ else
+ remove="$( echo "$acl" | sed 's/:...$//' )"
+ fi
- echo "$setfacl_exec -x \"$no_bits\" \"$acl_path\""
- done
- fi
+ echo "$setfacl_exec -x \"$remove\" \"$acl_path\""
+ echo "removed '$remove'" >> "$__messages_out"
+ done
fi
for acl in $acl_should
do
if ! echo "$acl_is" | grep -Eq "^$acl"
- then echo "$setfacl_exec -m \"$acl\" \"$acl_path\""
+ then
+ if echo "$os" | grep -Fq 'freebsd' \
+ && echo "$acl" | grep -Eq '^default:'
+ then
+ echo "setting default ACL in $os is currently not supported" >&2
+ else
+ echo "$setfacl_exec -m \"$acl\" \"$acl_path\""
+ echo "added '$acl'" >> "$__messages_out"
+ fi
fi
done
diff --git a/cdist/conf/type/__acl/man.rst b/cdist/conf/type/__acl/man.rst
index 39db4d75..28412871 100644
--- a/cdist/conf/type/__acl/man.rst
+++ b/cdist/conf/type/__acl/man.rst
@@ -3,35 +3,55 @@ cdist-type__acl(7)
NAME
----
-cdist-type__acl - Basic wrapper around `setfacl`
+cdist-type__acl - Set ACL entries
DESCRIPTION
-----------
-ACL must be defined as 3-symbol combination, using `r`, `w`, `x` and `-`.
+Fully supported and tested on Linux (ext4 filesystem), partial support for FreeBSD.
-See setfacl(1) and acl(5) for more details.
+See ``setfacl`` and ``acl`` manpages for more details.
-OPTIONAL MULTIPLE PARAMETERS
+REQUIRED MULTIPLE PARAMETERS
----------------------------
-user
- Add user ACL entry.
+entry
+ Set ACL entry following ``getfacl`` output syntax.
-group
- Add group ACL entry.
+
+OPTIONAL PARAMETERS
+-------------------
+source
+ Read ACL entries from stdin or file.
+ Ordering of entries is not important.
+ When reading from file, comments and empty lines are ignored.
+
+file
+ Create/change file with ``__file`` using ``user:group:mode`` pattern.
+
+directory
+ Create/change directory with ``__directory`` using ``user:group:mode`` pattern.
BOOLEAN PARAMETERS
------------------
-recursive
- Operate recursively (Linux only).
-
default
- Add default ACL entries.
+ Set all ACL entries as default too.
+ Only directories can have default ACLs.
+ Setting default ACL in FreeBSD is currently not supported.
+
+recursive
+ Make ``setfacl`` recursive (Linux only), but not ``getfacl`` in explorer.
remove
- Remove undefined ACL entries (Solaris not supported).
+ Remove undefined ACL entries.
+ ``mask`` and ``other`` entries can't be removed, but only changed.
+
+
+DEPRECATED PARAMETERS
+---------------------
+Parameters ``acl``, ``user``, ``group``, ``mask`` and ``other`` are deprecated and they
+will be removed in future versions. Please use ``entry`` parameter instead.
EXAMPLES
@@ -40,13 +60,41 @@ EXAMPLES
.. code-block:: sh
__acl /srv/project \
+ --default \
--recursive \
+ --remove \
+ --entry user:alice:rwx \
+ --entry user:bob:r-x \
+ --entry group:project-group:rwx \
+ --entry group:some-other-group:r-x \
+ --entry mask::r-x \
+ --entry other::r-x
+
+ # give Alice read-only access to subdir,
+ # but don't allow her to see parent content.
+
+ __acl /srv/project2 \
+ --remove \
+ --entry default:group:secret-project:rwx \
+ --entry group:secret-project:rwx \
+ --entry user:alice:--x
+
+ __acl /srv/project2/subdir \
--default \
--remove \
- --user alice:rwx \
- --user bob:r-x \
- --group project-group:rwx \
- --group some-other-group:r-x
+ --entry group:secret-project:rwx \
+ --entry user:alice:r-x
+
+ # read acl from stdin
+ echo 'user:alice:rwx' \
+ | __acl /path/to/directory --source -
+
+ # create/change directory too
+ __acl /path/to/directory \
+ --default \
+ --remove \
+ --directory root:root:770 \
+ --entry user:nobody:rwx
AUTHORS
diff --git a/cdist/conf/type/__acl/manifest b/cdist/conf/type/__acl/manifest
new file mode 100755
index 00000000..5fd23110
--- /dev/null
+++ b/cdist/conf/type/__acl/manifest
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+
+for p in file directory
+do
+ [ ! -f "$__object/parameter/$p" ] && continue
+
+ "__$p" "/$__object_id" \
+ --owner "$( awk -F: '{print $1}' "$__object/parameter/$p" )" \
+ --group "$( awk -F: '{print $2}' "$__object/parameter/$p" )" \
+ --mode "$( awk -F: '{print $3}' "$__object/parameter/$p" )"
+done
diff --git a/cdist/conf/type/__acl/parameter/deprecated/acl b/cdist/conf/type/__acl/parameter/deprecated/acl
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/acl
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/group b/cdist/conf/type/__acl/parameter/deprecated/group
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/group
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/mask b/cdist/conf/type/__acl/parameter/deprecated/mask
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/mask
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/other b/cdist/conf/type/__acl/parameter/deprecated/other
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/other
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/user b/cdist/conf/type/__acl/parameter/deprecated/user
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/user
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/optional b/cdist/conf/type/__acl/parameter/optional
new file mode 100644
index 00000000..cdcbc0b8
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/optional
@@ -0,0 +1,5 @@
+mask
+other
+source
+file
+directory
diff --git a/cdist/conf/type/__acl/parameter/optional_multiple b/cdist/conf/type/__acl/parameter/optional_multiple
index 22f5a52c..c615d507 100644
--- a/cdist/conf/type/__acl/parameter/optional_multiple
+++ b/cdist/conf/type/__acl/parameter/optional_multiple
@@ -1,2 +1,4 @@
+entry
+acl
user
group
diff --git a/cdist/conf/type/__apt_key/explorer/state b/cdist/conf/type/__apt_key/explorer/state
index f7940741..38f1bd3c 100755
--- a/cdist/conf/type/__apt_key/explorer/state
+++ b/cdist/conf/type/__apt_key/explorer/state
@@ -27,6 +27,18 @@ else
keyid="$__object_id"
fi
-apt-key export "$keyid" | head -n 1 | grep -Fqe "BEGIN PGP PUBLIC KEY BLOCK" \
- && echo present \
- || echo absent
+keydir="$(cat "$__object/parameter/keydir")"
+keyfile="$keydir/$__object_id.gpg"
+
+if [ -d "$keydir" ]
+then
+ if [ -f "$keyfile" ]
+ then echo present
+ else echo absent
+ fi
+else
+ # fallback to deprecated apt-key
+ apt-key export "$keyid" | head -n 1 | grep -Fqe "BEGIN PGP PUBLIC KEY BLOCK" \
+ && echo present \
+ || echo absent
+fi
diff --git a/cdist/conf/type/__apt_key/gencode-remote b/cdist/conf/type/__apt_key/gencode-remote
index 9c4fa00c..0c96ff67 100755
--- a/cdist/conf/type/__apt_key/gencode-remote
+++ b/cdist/conf/type/__apt_key/gencode-remote
@@ -31,12 +31,82 @@ if [ "$state_should" = "$state_is" ]; then
exit 0
fi
+keydir="$(cat "$__object/parameter/keydir")"
+keyfile="$keydir/$__object_id.gpg"
+
case "$state_should" in
present)
keyserver="$(cat "$__object/parameter/keyserver")"
- echo "apt-key adv --keyserver \"$keyserver\" --recv-keys \"$keyid\""
+
+ if [ -f "$__object/parameter/uri" ]; then
+ uri="$(cat "$__object/parameter/uri")"
+
+ if [ -d "$keydir" ]; then
+ cat << EOF
+
+curl -s -L \\
+ -o "$keyfile" \\
+ "$uri"
+
+key="\$( cat "$keyfile" )"
+
+if echo "\$key" | grep -Fq 'BEGIN PGP PUBLIC KEY BLOCK'
+then
+ echo "\$key" | gpg --dearmor > "$keyfile"
+fi
+
+EOF
+ else
+ # fallback to deprecated apt-key
+ echo "curl -s -L '$uri' | apt-key add -"
+ fi
+ elif [ -d "$keydir" ]; then
+ # we need to kill gpg after 30 seconds, because gpg
+ # can get stuck if keyserver is not responding.
+ # exporting env var and not exit 1,
+ # because we need to clean up and kill dirmngr.
+ cat << EOF
+
+gpgtmphome="\$( mktemp -d )"
+
+if timeout 30s \\
+ gpg --homedir "\$gpgtmphome" \\
+ --keyserver "$keyserver" \\
+ --recv-keys "$keyid"
+then
+ gpg --homedir "\$gpgtmphome" \\
+ --export "$keyid" \\
+ > "$keyfile"
+else
+ export GPG_GOT_STUCK=1
+fi
+
+GNUPGHOME="\$gpgtmphome" gpgconf --kill dirmngr
+
+rm -rf "\$gpgtmphome"
+
+if [ -n "\$GPG_GOT_STUCK" ]
+then
+ echo "GPG GOT STUCK - no response from keyserver after 30 seconds" >&2
+ exit 1
+fi
+
+EOF
+ else
+ # fallback to deprecated apt-key
+ echo "apt-key adv --keyserver \"$keyserver\" --recv-keys \"$keyid\""
+ fi
+
+ echo "added '$keyid'" >> "$__messages_out"
;;
absent)
- echo "apt-key del \"$keyid\""
+ if [ -f "$keyfile" ]; then
+ echo "rm '$keyfile'"
+ else
+ # fallback to deprecated apt-key
+ echo "apt-key del \"$keyid\""
+ fi
+
+ echo "removed '$keyid'" >> "$__messages_out"
;;
esac
diff --git a/cdist/conf/type/__apt_key/man.rst b/cdist/conf/type/__apt_key/man.rst
index 9009877e..234bc715 100644
--- a/cdist/conf/type/__apt_key/man.rst
+++ b/cdist/conf/type/__apt_key/man.rst
@@ -28,6 +28,12 @@ keyserver
the keyserver from which to fetch the key. If omitted the default set
in ./parameter/default/keyserver is used.
+keydir
+ key save location, defaults to ``/etc/apt/trusted.pgp.d``
+
+uri
+ the URI from which to download the key
+
EXAMPLES
--------
@@ -47,15 +53,20 @@ EXAMPLES
# same thing with other keyserver
__apt_key UbuntuArchiveKey --keyid 437D05B5 --keyserver keyserver.ubuntu.com
+ # download key from the internet
+ __apt_key rabbitmq \
+ --uri http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
+
AUTHORS
-------
Steven Armstrong
+Ander Punnar
COPYING
-------
-Copyright \(C) 2011-2014 Steven Armstrong. 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
+Copyright \(C) 2011-2019 Steven Armstrong and Ander Punnar. 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.
diff --git a/cdist/conf/type/__apt_key/manifest b/cdist/conf/type/__apt_key/manifest
new file mode 100755
index 00000000..010357cd
--- /dev/null
+++ b/cdist/conf/type/__apt_key/manifest
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+__package gnupg
+
+if [ -f "$__object/parameter/uri" ]
+then __package curl
+else __package dirmngr
+fi
diff --git a/cdist/conf/type/__apt_key/parameter/default/keydir b/cdist/conf/type/__apt_key/parameter/default/keydir
new file mode 100644
index 00000000..190eb2de
--- /dev/null
+++ b/cdist/conf/type/__apt_key/parameter/default/keydir
@@ -0,0 +1 @@
+/etc/apt/trusted.gpg.d
diff --git a/cdist/conf/type/__apt_key/parameter/optional b/cdist/conf/type/__apt_key/parameter/optional
index 18cf2586..de647375 100644
--- a/cdist/conf/type/__apt_key/parameter/optional
+++ b/cdist/conf/type/__apt_key/parameter/optional
@@ -1,3 +1,5 @@
state
keyid
keyserver
+keydir
+uri
diff --git a/cdist/conf/type/__apt_unattended_upgrades/man.rst b/cdist/conf/type/__apt_unattended_upgrades/man.rst
new file mode 100644
index 00000000..2231b5f9
--- /dev/null
+++ b/cdist/conf/type/__apt_unattended_upgrades/man.rst
@@ -0,0 +1,68 @@
+cdist-type__apt_unattended_upgrades(7)
+======================================
+
+NAME
+----
+cdist-type__apt_unattended_upgrades - automatic installation of updates
+
+
+DESCRIPTION
+-----------
+
+Install and configure unattended-upgrades package.
+
+For more information see https://wiki.debian.org/UnattendedUpgrades.
+
+
+OPTIONAL MULTIPLE PARAMETERS
+----------------------------
+option
+ Set options for unattended-upgrades. See examples.
+
+ Supported options with default values (as of 2020-01-17) are:
+
+ - AutoFixInterruptedDpkg, default is "true"
+ - MinimalSteps, default is "true"
+ - InstallOnShutdown, default is "false"
+ - Mail, default is "" (empty)
+ - MailOnlyOnError, default is "false"
+ - Remove-Unused-Kernel-Packages, default is "true"
+ - Remove-New-Unused-Dependencies, default is "true"
+ - Remove-Unused-Dependencies, default is "false"
+ - Automatic-Reboot, default is "false"
+ - Automatic-Reboot-WithUsers, default is "true"
+ - Automatic-Reboot-Time, default is "02:00"
+ - SyslogEnable, default is "false"
+ - SyslogFacility, default is "daemon"
+ - OnlyOnACPower, default is "true"
+ - Skip-Updates-On-Metered-Connections, default is "true"
+ - Verbose, default is "false"
+ - Debug, default is "false"
+
+blacklist
+ Python regular expressions, matching packages to exclude from upgrading.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ __apt_unattended_upgrades \
+ --option Mail=root \
+ --option MailOnlyOnError=true \
+ --blacklist multipath-tools \
+ --blacklist open-iscsi
+
+
+AUTHORS
+-------
+Ander Punnar
+
+
+COPYING
+-------
+Copyright \(C) 2020 Ander Punnar. 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.
diff --git a/cdist/conf/type/__apt_unattended_upgrades/manifest b/cdist/conf/type/__apt_unattended_upgrades/manifest
new file mode 100755
index 00000000..3c00e2f4
--- /dev/null
+++ b/cdist/conf/type/__apt_unattended_upgrades/manifest
@@ -0,0 +1,80 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+__package unattended-upgrades
+
+export require='__package/unattended-upgrades'
+
+# in normal circumstances 20auto-upgrades is managed
+# by debconf and it can only contain these lines
+
+__file /etc/apt/apt.conf.d/20auto-upgrades \
+ --owner root \
+ --group root \
+ --mode 644 \
+ --source - << EOF
+APT::Periodic::Update-Package-Lists "1";
+APT::Periodic::Unattended-Upgrade "1";
+EOF
+
+# lets not write into upstream 50unattended-upgrades file,
+# but use our own config file to avoid clashes
+
+conf_file='/etc/apt/apt.conf.d/51unattended-upgrades-cdist'
+
+conf='# this file is managed by cdist'
+
+if [ -f "$__object/parameter/option" ]
+then
+ o=''
+
+ while read -r l
+ do
+ o="$( printf '%s\nUnattended-Upgrade::%s "%s";\n' "$o" "${l%%=*}" "${l#*=}" )"
+ done \
+ < "$__object/parameter/option"
+
+ conf="$( printf '%s\n%s\n' "$conf" "$o" )"
+fi
+
+if [ -f "$__object/parameter/blacklist" ]
+then
+ b='Unattended-Upgrade::Package-Blacklist {'
+
+ while read -r l
+ do
+ b="$( printf '%s\n"%s";\n' "$b" "$l" )"
+ done \
+ < "$__object/parameter/blacklist"
+
+ conf="$( printf '%s\n%s\n}\n' "$conf" "$b" )"
+fi
+
+if [ "$( echo "$conf" | wc -l )" -gt 1 ]
+then
+ echo "$conf" \
+ | __file "$conf_file" \
+ --owner root \
+ --group root \
+ --mode 644 \
+ --source -
+else
+ __file "$conf_file" --state absent
+fi
diff --git a/cdist/conf/type/__apt_unattended_upgrades/parameter/optional_multiple b/cdist/conf/type/__apt_unattended_upgrades/parameter/optional_multiple
new file mode 100644
index 00000000..ea4fba2b
--- /dev/null
+++ b/cdist/conf/type/__apt_unattended_upgrades/parameter/optional_multiple
@@ -0,0 +1,2 @@
+option
+blacklist
diff --git a/cdist/conf/type/__apt_unattended_upgrades/singleton b/cdist/conf/type/__apt_unattended_upgrades/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__block/gencode-remote b/cdist/conf/type/__block/gencode-remote
index f269c785..1f5cc033 100755
--- a/cdist/conf/type/__block/gencode-remote
+++ b/cdist/conf/type/__block/gencode-remote
@@ -18,6 +18,11 @@
# along with cdist. If not, see .
#
+# quote function from http://www.etalabs.net/sh_tricks.html
+quote() {
+ printf '%s\n' "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"
+}
+
file="$(cat "$__object/parameter/file" 2>/dev/null || echo "/$__object_id")"
state_should=$(cat "$__object/parameter/state")
prefix=$(cat "$__object/parameter/prefix" 2>/dev/null || echo "#cdist:__block/$__object_id")
@@ -46,7 +51,7 @@ tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX)
if [ -f "$file" ]; then
cp -p "$file" "\$tmpfile"
fi
-awk -v prefix="^$prefix\$" -v suffix="^$suffix\$" '
+awk -v prefix=^$(quote "$prefix")\$ -v suffix=^$(quote "$suffix")\$ '
{
if (match(\$0,prefix)) {
triggered=1
diff --git a/cdist/conf/type/__cdist/man.rst b/cdist/conf/type/__cdist/man.rst
index 9e1c72cb..be082781 100644
--- a/cdist/conf/type/__cdist/man.rst
+++ b/cdist/conf/type/__cdist/man.rst
@@ -30,7 +30,7 @@ username
source
Select the source from which to clone cdist from.
- Defaults to "git://github.com/ungleich/cdist.git".
+ Defaults to "git@code.ungleich.ch:ungleich-public/cdist.git".
branch
@@ -47,7 +47,7 @@ EXAMPLES
__cdist /home/cdist/cdist
# Use alternative source
- __cdist --source "git://github.com/ungleich/cdist" /home/cdist/cdist
+ __cdist --source "git@code.ungleich.ch:ungleich-public/cdist.git" /home/cdist/cdist
AUTHORS
diff --git a/cdist/conf/type/__cdist/manifest b/cdist/conf/type/__cdist/manifest
index a97cf288..0b0f1263 100755
--- a/cdist/conf/type/__cdist/manifest
+++ b/cdist/conf/type/__cdist/manifest
@@ -37,6 +37,7 @@ source="$(cat "$__object/parameter/source")"
# out of it
home=/home/$username
+# shellcheck disable=SC2086
__user "$username" --home "$home" $shell
require="__user/$username" __directory "$home" \
diff --git a/cdist/conf/type/__cdist/parameter/default/source b/cdist/conf/type/__cdist/parameter/default/source
index 3f8e31ad..1ad3a250 100644
--- a/cdist/conf/type/__cdist/parameter/default/source
+++ b/cdist/conf/type/__cdist/parameter/default/source
@@ -1 +1 @@
-git://github.com/ungleich/cdist.git
+git@code.ungleich.ch:ungleich-public/cdist.git
diff --git a/cdist/conf/type/__consul/files/versions/1.5.0/cksum b/cdist/conf/type/__consul/files/versions/1.5.0/cksum
new file mode 100644
index 00000000..efca9caa
--- /dev/null
+++ b/cdist/conf/type/__consul/files/versions/1.5.0/cksum
@@ -0,0 +1 @@
+886614099 103959898 consul
diff --git a/cdist/conf/type/__consul/files/versions/1.5.0/source b/cdist/conf/type/__consul/files/versions/1.5.0/source
new file mode 100644
index 00000000..cafa9248
--- /dev/null
+++ b/cdist/conf/type/__consul/files/versions/1.5.0/source
@@ -0,0 +1 @@
+https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
diff --git a/cdist/conf/type/__consul/gencode-remote b/cdist/conf/type/__consul/gencode-remote
index 1d2244ea..2a21054f 100755
--- a/cdist/conf/type/__consul/gencode-remote
+++ b/cdist/conf/type/__consul/gencode-remote
@@ -42,7 +42,7 @@ source_file_name="${source##*/}"
cksum_should=$(cut -d' ' -f1,2 "$version_dir/cksum")
cat << eof
- tmpdir=\$(mktemp -d --tmpdir="/tmp" "${__type##*/}.XXXXXXXXXX")
+ tmpdir=\$(mktemp -d -p /tmp "${__type##*/}.XXXXXXXXXX")
curl -s -L "$source" > "\$tmpdir/$source_file_name"
unzip -p "\$tmpdir/$source_file_name" > "${destination}.tmp"
rm -rf "\$tmpdir"
diff --git a/cdist/conf/type/__consul/manifest b/cdist/conf/type/__consul/manifest
index 0dd50f53..156eb667 100755
--- a/cdist/conf/type/__consul/manifest
+++ b/cdist/conf/type/__consul/manifest
@@ -24,7 +24,7 @@
os=$(cat "$__global/explorer/os")
case "$os" in
- scientific|centos|redhat|ubuntu|debian|devuan|archlinux|gentoo)
+ alpine|scientific|centos|redhat|ubuntu|debian|devuan|archlinux|gentoo)
# any linux should work
:
;;
@@ -47,6 +47,7 @@ fi
if [ -f "$__object/parameter/direct" ]; then
__package unzip
+ __package curl
else
__staged_file /usr/local/bin/consul \
--source "$(cat "$version_dir/source")" \
diff --git a/cdist/conf/type/__consul_agent/files/consul.sys-openrc b/cdist/conf/type/__consul_agent/files/consul.sys-openrc
new file mode 100644
index 00000000..1dbe9375
--- /dev/null
+++ b/cdist/conf/type/__consul_agent/files/consul.sys-openrc
@@ -0,0 +1,38 @@
+#!/sbin/openrc-run
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
+
+description="consul agent"
+
+pidfile="${CONSUL_PIDFILE:-"/var/run/$RC_SVCNAME/pidfile"}"
+command="${CONSUL_BINARY:-"/usr/local/bin/consul"}"
+
+
+checkconfig() {
+ if [ ! -d /var/run/consul ] ; then
+ mkdir -p /var/run/consul || return 1
+ chown consul:consul /var/run/$NAME || return 1
+ chmod 2770 /var/run/$NAME || return 1
+ fi
+}
+
+start() {
+ need net
+
+ start-stop-daemon --start --quiet --oknodo \
+ --pidfile "$pidfile" --background \
+ --exec $command -- agent -pid-file="$pidfile" -config-dir /etc/consul/conf.d
+}
+start_pre() {
+ checkconfig
+}
+
+stop() {
+ if [ "${RC_CMD}" = "restart" ] ; then
+ checkconfig || return 1
+ fi
+
+ ebegin "Stopping $RC_SVCNAME"
+ start-stop-daemon --stop --exec "$command" \
+ --pidfile "$pidfile" --quiet
+ eend $?
+}
diff --git a/cdist/conf/type/__consul_agent/man.rst b/cdist/conf/type/__consul_agent/man.rst
index 966abc60..62ee70bb 100644
--- a/cdist/conf/type/__consul_agent/man.rst
+++ b/cdist/conf/type/__consul_agent/man.rst
@@ -116,6 +116,9 @@ verify-incoming
verify-outgoing
enforce the use of TLS and verify the peers authenticity on outgoing connections
+use-distribution-package
+ uses distribution package instead of upstream binary
+
EXAMPLES
--------
diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest
index c48bfe85..7b54529c 100755
--- a/cdist/conf/type/__consul_agent/manifest
+++ b/cdist/conf/type/__consul_agent/manifest
@@ -1,7 +1,8 @@
#!/bin/sh -e
#
# 2015 Steven Armstrong (steven-cdist at armstrong.cc)
-# 2015 Nico Schottelius (nico-cdist at schottelius.org)
+# 2015-2020 Nico Schottelius (nico-cdist at schottelius.org)
+# 2019 Timothée Floure (timothee.floure at ungleich.ch)
#
# This file is part of cdist.
#
@@ -19,133 +20,87 @@
# along with cdist. If not, see .
#
-
os=$(cat "$__global/explorer/os")
-case "$os" in
- scientific|centos|debian|devuan|redhat|ubuntu)
- # whitelist safeguard
- :
- ;;
- *)
- echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
- echo "Please contribute an implementation for it if you can." >&2
- exit 1
- ;;
-esac
+###
+# Type parameters.
state="$(cat "$__object/parameter/state")"
user="$(cat "$__object/parameter/user")"
group="$(cat "$__object/parameter/group")"
-data_dir="/var/lib/consul"
-conf_dir="/etc/consul/conf.d"
-conf_file="config.json"
+release=$(cat "$__global/explorer/lsb_release")
+if [ -f "$__object/parameter/use-distribution-package" ]; then
+ use_distribution_package=1
+fi
-# FIXME: there has got to be a better way to handle the dependencies in this case
-case "$state" in
- present)
- __group "$group" --system --state "$state"
- require="__group/$group" \
- __user "$user" --system --gid "$group" \
- --home "$data_dir" --state "$state"
- export require="__user/consul"
- ;;
- absent)
- echo "Sorry, state=absent currently not supported :-(" >&2
- exit 1
- require="$__object_name" \
- __user "$user" --system --gid "$group" --state "$state"
- require="__user/$user" \
- __group "$group" --system --state "$state"
- ;;
+###
+# Those are default that might be overriden by os-specific logic.
+
+data_dir="/var/lib/consul"
+
+
+
+tls_dir="$conf_dir/tls"
+
+case "$os" in
+ alpine)
+ conf_dir="/etc/consul"
+ conf_file="server.json"
+ ;;
+ *)
+ conf_dir="/etc/consul/conf.d"
+ conf_file="config.json"
+ ;;
esac
-__directory /etc/consul \
- --owner root --group "$group" --mode 750 --state "$state"
-require="__directory/etc/consul" \
- __directory "$conf_dir" \
- --owner root --group "$group" --mode 750 --state "$state"
+###
+# Sane deployment, based on distribution package when available.
-if [ -f "$__object/parameter/ca-file-source" ] || [ -f "$__object/parameter/cert-file-source" ] || [ -f "$__object/parameter/key-file-source" ]; then
- # create directory for ssl certs
- require="__directory/etc/consul" \
- __directory /etc/consul/ssl \
- --owner root --group "$group" --mode 750 --state "$state"
-fi
+distribution_setup () {
+ case "$os" in
+ debian)
+ # consul is only available starting Debian 10 (buster).
+ # See https://packages.debian.org/buster/consul
+ if [ "$release" -lt 10 ]; then
+ echo "Consul is not available for your debian release." >&2
+ echo "Please use the 'manual' (i.e. non-package) installation or \
+ upgrade the target system." >&2
+ exit 1
+ fi
-__directory "$data_dir" \
- --owner "$user" --group "$group" --mode 770 --state "$state"
+ # Override previously defined environment to match debian packaging.
+ conf_dir='/etc/consul.d'
+ user='consul'
+ group='consul'
+ ;;
+ alpine)
+ # consul is only available starting Alpine 3.12 (= edge during the 3.11 cycle).
+ # See https://pkgs.alpinelinux.org/packages?name=consul&branch=edge
+ # Override previously defined environment to match alpine packaging.
+ conf_dir='/etc/consul'
+ conf_file='server.json'
+ data_dir='/var/consul'
+ user='consul'
+ group='consul'
+ ;;
+ *)
+ echo "Your operating system ($os) is currently not supported with the \
+ --use-distribution-package flag (${__type##*/})." >&2
+ echo "Please use non-package installation or contribute an \
+ implementation for if you can." >&2
+ exit 1
+ ;;
+ esac
-# Generate json config file
-(
-echo "{"
+ # Install consul package.
+ __package consul --state "$state"
-# parameters we define ourself
-printf ' "data_dir": "%s"\n' "$data_dir"
+ export config_deployment_requires="__package/consul"
+}
-cd "$__object/parameter/"
-for param in *; do
- case "$param" in
- state|user|group|json-config) continue ;;
- ca-file-source|cert-file-source|key-file-source)
- source="$(cat "$__object/parameter/$param")"
- destination="/etc/consul/ssl/${source##*/}"
- require="__directory/etc/consul/ssl" \
- __file "$destination" \
- --owner root --group consul --mode 640 \
- --source "$source" \
- --state "$state"
- key="$(echo "${param%-*}" | tr '-' '_')"
- printf ' ,"%s": "%s"\n' "$key" "$destination"
- ;;
- disable-remote-exec|disable-update-check|leave-on-terminate|rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing)
- # handle boolean parameters
- key="$(echo "$param" | tr '-' '_')"
- printf ' ,"%s": true\n' "$key"
- ;;
- retry-join)
- # join multiple parameters into json array
- retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")"
- # remove trailing ,
- printf ' ,"retry_join": [%s]\n' "${retry_join%*,}"
- ;;
- retry-join-wan)
- # join multiple parameters into json array over wan
- retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")"
- # remove trailing ,
- printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}"
- ;;
- bootstrap-expect)
- # integer key=value parameters
- key="$(echo "$param" | tr '-' '_')"
- printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")"
- ;;
- *)
- # string key=value parameters
- key="$(echo "$param" | tr '-' '_')"
- printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")"
- ;;
- esac
-done
-if [ -f "$__object/parameter/json-config" ]; then
- json_config="$(cat "$__object/parameter/json-config")"
- if [ "$json_config" = "-" ]; then
- json_config="$__object/stdin"
- fi
- # remove leading and trailing whitespace and commas from first and last line
- # indent each line with 3 spaces for consistency
- json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config")
- printf ' ,%s\n' "$json"
-fi
-echo "}"
-) | \
-require="__directory${conf_dir}" \
- __config_file "${conf_dir}/${conf_file}" \
- --owner root --group "$group" --mode 640 \
- --state "$state" \
- --onchange 'service consul status >/dev/null && service consul reload || true' \
- --source -
+###
+# LEGACY manual deployment, kept for compatibility reasons.
init_sysvinit()
{
@@ -179,48 +134,186 @@ init_upstart()
require="__file/etc/init/consul.conf" __start_on_boot consul
}
-# Install init script to start on boot
-case "$os" in
- centos|redhat)
- os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")"
- major_version="${os_version%%.*}"
- case "$major_version" in
- [456])
- init_sysvinit redhat
- ;;
- 7)
- init_systemd
- ;;
- *)
- echo "Unsupported CentOS/Redhat version: $os_version" >&2
- exit 1
- ;;
- esac
- ;;
+manual_setup () {
+ case "$os" in
+ alpine|scientific|centos|debian|devuan|redhat|ubuntu)
+ # whitelist safeguard
+ :
+ ;;
+ *)
+ echo "Your operating system ($os) is currently not supported by this \
+ type (${__type##*/})." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+ esac
- debian)
- os_version=$(cat "$__global/explorer/os_version")
- major_version="${os_version%%.*}"
+ # FIXME: there has got to be a better way to handle the dependencies in this case
+ case "$state" in
+ present)
+ __group "$group" --system --state "$state"
+ require="__group/$group" __user "$user" \
+ --system --gid "$group" --home "$data_dir" --state "$state"
+ ;;
+ *)
+ echo "The $state state is not (yet?) supported by this type." >&2
+ exit 1
+ ;;
+ esac
- case "$major_version" in
- [567])
- init_sysvinit debian
- ;;
- [89])
- init_systemd
- ;;
- *)
- echo "Unsupported Debian version $os_version" >&2
- exit 1
- ;;
- esac
- ;;
+ # Create data directory.
+ require="__user/consul" __directory "$data_dir" \
+ --owner "$user" --group "$group" --mode 770 --state "$state"
- devuan)
- init_sysvinit debian
- ;;
+ # Create config directory.
+ require="__user/consul" __directory "$conf_dir" \
+ --parents --owner root --group "$group" --mode 750 --state "$state"
- ubuntu)
- init_upstart
- ;;
-esac
+ # Install init script to start on boot
+ case "$os" in
+ devuan)
+ init_sysvinit debian
+ ;;
+ centos|redhat)
+ os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")"
+ major_version="${os_version%%.*}"
+ case "$major_version" in
+ [456])
+ init_sysvinit redhat
+ ;;
+ 7)
+ init_systemd
+ ;;
+ *)
+ echo "Unsupported CentOS/Redhat version: $os_version" >&2
+ exit 1
+ ;;
+ esac
+ ;;
+
+ debian)
+ os_version=$(cat "$__global/explorer/os_version")
+ major_version="${os_version%%.*}"
+
+ case "$major_version" in
+ [567])
+ init_sysvinit debian
+ ;;
+ [89]|10)
+ init_systemd
+ ;;
+ *)
+ echo "Unsupported Debian version $os_version" >&2
+ exit 1
+ ;;
+ esac
+ ;;
+
+ ubuntu)
+ init_upstart
+ ;;
+ esac
+
+ config_deployment_requires="__user/consul __directory/$conf_dir"
+}
+
+###
+# Trigger requested installation method.
+if [ $use_distribution_package ]; then
+ distribution_setup
+else
+ manual_setup
+fi
+
+###
+# Install TLS certificates.
+
+if [ -f "$__object/parameter/ca-file-source" ] || \
+ [ -f "$__object/parameter/cert-file-source" ] || \
+ [ -f "$__object/parameter/key-file-source" ]; then
+
+ requires="$config_deployment_requires" __directory "$tls_dir" \
+ --owner root --group "$group" --mode 750 --state "$state"
+
+ # Append to service restart requirements.
+ restart_requires="$restart_requires __directory/$conf_dir/tls"
+fi
+
+###
+# Generate and deploy configuration.
+
+json_configuration=$(
+ echo "{"
+
+ # parameters we define ourself
+ printf ' "data_dir": "%s"\n' "$data_dir"
+
+ cd "$__object/parameter/"
+ for param in *; do
+ case "$param" in
+ state|user|group|json-config|use-distribution-package) continue ;;
+ ca-file-source|cert-file-source|key-file-source)
+ source="$(cat "$__object/parameter/$param")"
+ destination="$tls_dir/${source##*/}"
+ require="__directory/$tls_dir" \
+ __file "$destination" \
+ --owner root --group consul --mode 640 \
+ --source "$source" \
+ --state "$state"
+ key="$(echo "${param%-*}" | tr '-' '_')"
+ printf ' ,"%s": "%s"\n' "$key" "$destination"
+ ;;
+ disable-remote-exec|disable-update-check|leave-on-terminate\
+ |rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing)
+ # handle boolean parameters
+ key="$(echo "$param" | tr '-' '_')"
+ printf ' ,"%s": true\n' "$key"
+ ;;
+ retry-join)
+ # join multiple parameters into json array
+ retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")"
+ # remove trailing ,
+ printf ' ,"retry_join": [%s]\n' "${retry_join%*,}"
+ ;;
+ retry-join-wan)
+ # join multiple parameters into json array over wan
+ retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")"
+ # remove trailing ,
+ printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}"
+ ;;
+ bootstrap-expect)
+ # integer key=value parameters
+ key="$(echo "$param" | tr '-' '_')"
+ printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")"
+ ;;
+ *)
+ # string key=value parameters
+ key="$(echo "$param" | tr '-' '_')"
+ printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")"
+ ;;
+ esac
+ done
+ if [ -f "$__object/parameter/json-config" ]; then
+ json_config="$(cat "$__object/parameter/json-config")"
+ if [ "$json_config" = "-" ]; then
+ json_config="$__object/stdin"
+ fi
+ # remove leading and trailing whitespace and commas from first and last line
+ # indent each line with 3 spaces for consistency
+ json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config")
+ printf ' ,%s\n' "$json"
+ fi
+ echo "}"
+)
+echo "$json_configuration" | require="$config_deployment_requires" \
+ __file "$conf_dir/$conf_file" \
+ --owner root --group "$group" --mode 640 \
+ --state "$state" \
+ --source -
+
+# Set configuration deployment as requirement for service restart.
+restart_requires="__file/$conf_dir/$conf_file"
+
+###
+# Restart consul agent after everything else.
+require="$restart_requires" __service consul --action restart
diff --git a/cdist/conf/type/__consul_agent/parameter/boolean b/cdist/conf/type/__consul_agent/parameter/boolean
index 91f7f17e..c86853c3 100644
--- a/cdist/conf/type/__consul_agent/parameter/boolean
+++ b/cdist/conf/type/__consul_agent/parameter/boolean
@@ -6,3 +6,4 @@ server
enable-syslog
verify-incoming
verify-outgoing
+use-distribution-package
diff --git a/cdist/conf/type/__consul_check/explorer/conf-dir b/cdist/conf/type/__consul_check/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_check/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_check/manifest b/cdist/conf/type/__consul_check/manifest
index c9f7add9..522aa1a9 100755
--- a/cdist/conf/type/__consul_check/manifest
+++ b/cdist/conf/type/__consul_check/manifest
@@ -19,7 +19,7 @@
#
name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="check_${name}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_service/explorer/conf-dir b/cdist/conf/type/__consul_service/explorer/conf-dir
new file mode 100644
index 00000000..0fc9ef84
--- /dev/null
+++ b/cdist/conf/type/__consul_service/explorer/conf-dir
@@ -0,0 +1,15 @@
+# Determine the configuration directory used by consul.
+
+check_dir () {
+ if [ -d "$1" ]; then
+ printf '%s' "$1"
+ exit
+ fi
+}
+
+check_dir '/etc/consul/conf.d'
+check_dir '/etc/consul.d'
+check_dir '/etc/consul'
+
+echo 'Could not determine consul configuration dir. Exiting.' >&2
+exit 1
diff --git a/cdist/conf/type/__consul_service/manifest b/cdist/conf/type/__consul_service/manifest
index 60397db7..d16f18e0 100755
--- a/cdist/conf/type/__consul_service/manifest
+++ b/cdist/conf/type/__consul_service/manifest
@@ -19,7 +19,7 @@
#
name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="service_${name}.json"
state="$(cat "$__object/parameter/state")"
@@ -45,7 +45,7 @@ printf ' "name": "%s"\n' "$name"
cd "$__object/parameter/"
for param in *; do
case "$param" in
- state|name|check-interval) continue ;;
+ state|name|check-interval|conf-dir) continue ;;
check-script)
printf ' ,"check": {\n'
printf ' "script": "%s"\n' "$(cat "$__object/parameter/check-script")"
@@ -86,7 +86,6 @@ echo " }"
# end json file
echo "}"
) | \
-require="__directory${conf_dir}" \
__config_file "${conf_dir}/${conf_file}" \
--owner root --group consul --mode 640 \
--state "$state" \
diff --git a/cdist/conf/type/__consul_watch_checks/explorer/conf-dir b/cdist/conf/type/__consul_watch_checks/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_checks/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_checks/manifest b/cdist/conf/type/__consul_watch_checks/manifest
index 5fdd7a74..4976b25a 100755
--- a/cdist/conf/type/__consul_watch_checks/manifest
+++ b/cdist/conf/type/__consul_watch_checks/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_watch_event/explorer/conf-dir b/cdist/conf/type/__consul_watch_event/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_event/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_event/manifest b/cdist/conf/type/__consul_watch_event/manifest
index 61934656..b17680c1 100755
--- a/cdist/conf/type/__consul_watch_event/manifest
+++ b/cdist/conf/type/__consul_watch_event/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_watch_key/explorer/conf-dir b/cdist/conf/type/__consul_watch_key/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_key/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_key/manifest b/cdist/conf/type/__consul_watch_key/manifest
index 61934656..b17680c1 100755
--- a/cdist/conf/type/__consul_watch_key/manifest
+++ b/cdist/conf/type/__consul_watch_key/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir b/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_keyprefix/manifest b/cdist/conf/type/__consul_watch_keyprefix/manifest
index 61934656..b17680c1 100755
--- a/cdist/conf/type/__consul_watch_keyprefix/manifest
+++ b/cdist/conf/type/__consul_watch_keyprefix/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir b/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_nodes/manifest b/cdist/conf/type/__consul_watch_nodes/manifest
index 61934656..b17680c1 100755
--- a/cdist/conf/type/__consul_watch_nodes/manifest
+++ b/cdist/conf/type/__consul_watch_nodes/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_watch_service/explorer/conf-dir b/cdist/conf/type/__consul_watch_service/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_service/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_service/manifest b/cdist/conf/type/__consul_watch_service/manifest
index db38eb18..e8d18328 100755
--- a/cdist/conf/type/__consul_watch_service/manifest
+++ b/cdist/conf/type/__consul_watch_service/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__consul_watch_services/explorer/conf-dir b/cdist/conf/type/__consul_watch_services/explorer/conf-dir
new file mode 120000
index 00000000..daa712c3
--- /dev/null
+++ b/cdist/conf/type/__consul_watch_services/explorer/conf-dir
@@ -0,0 +1 @@
+../../__consul_service/explorer/conf-dir
\ No newline at end of file
diff --git a/cdist/conf/type/__consul_watch_services/manifest b/cdist/conf/type/__consul_watch_services/manifest
index 61934656..b17680c1 100755
--- a/cdist/conf/type/__consul_watch_services/manifest
+++ b/cdist/conf/type/__consul_watch_services/manifest
@@ -20,7 +20,7 @@
cdist_type="${__type##*/}"
watch_type="${cdist_type##*_}"
-conf_dir="/etc/consul/conf.d"
+conf_dir=$(cat "$__object/explorer/conf-dir")
conf_file="watch_${watch_type}_${__object_id}.json"
state="$(cat "$__object/parameter/state")"
diff --git a/cdist/conf/type/__cron/gencode-remote b/cdist/conf/type/__cron/gencode-remote
index 59398058..9debbc47 100755
--- a/cdist/conf/type/__cron/gencode-remote
+++ b/cdist/conf/type/__cron/gencode-remote
@@ -31,24 +31,28 @@ if [ -f "$__object/parameter/raw" ]; then
elif [ -f "$__object/parameter/raw_command" ]; then
entry="$command"
else
- minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")"
- hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")"
- day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")"
- month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")"
- day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")"
+ minute="$(cat "$__object/parameter/minute")"
+ hour="$(cat "$__object/parameter/hour")"
+ day_of_month="$(cat "$__object/parameter/day_of_month")"
+ month="$(cat "$__object/parameter/month")"
+ day_of_week="$(cat "$__object/parameter/day_of_week")"
entry="$minute $hour $day_of_month $month $day_of_week $command # $name"
fi
mkdir "$__object/files"
echo "$entry" > "$__object/files/entry"
-if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then
- state_is=present
+if [ -s "$__object/explorer/entry" ]; then
+ if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then
+ state_is=present
+ else
+ state_is=modified
+ fi
else
state_is=absent
fi
-state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")"
+state_should="$(cat "$__object/parameter/state")"
[ "$state_is" = "$state_should" ] && exit 0
diff --git a/cdist/conf/type/__cron/manifest b/cdist/conf/type/__cron/manifest
index 53973e07..e7b51863 100755
--- a/cdist/conf/type/__cron/manifest
+++ b/cdist/conf/type/__cron/manifest
@@ -22,3 +22,12 @@ if [ -f "$__object/parameter/raw" ] && [ -f "$__object/parameter/raw_command" ];
echo "ERROR: both raw and raw_command specified" >&2
exit 1
fi
+
+case "$(cat "$__object/parameter/state")" in
+ present) ;;
+ absent) ;;
+
+ *)
+ echo "ERROR: unkown cron state" >&2
+ exit 2
+esac
diff --git a/cdist/conf/type/__cron/nonparallel b/cdist/conf/type/__cron/nonparallel
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__cron/parameter/default/day_of_month b/cdist/conf/type/__cron/parameter/default/day_of_month
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/default/day_of_month
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__cron/parameter/default/day_of_week b/cdist/conf/type/__cron/parameter/default/day_of_week
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/default/day_of_week
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__cron/parameter/default/hour b/cdist/conf/type/__cron/parameter/default/hour
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/default/hour
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__cron/parameter/default/minute b/cdist/conf/type/__cron/parameter/default/minute
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/default/minute
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__cron/parameter/default/month b/cdist/conf/type/__cron/parameter/default/month
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/default/month
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__cron/parameter/default/state b/cdist/conf/type/__cron/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__cron/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__daemontools_service/man.rst b/cdist/conf/type/__daemontools_service/man.rst
index ec1d20ff..9bbbe2f8 100644
--- a/cdist/conf/type/__daemontools_service/man.rst
+++ b/cdist/conf/type/__daemontools_service/man.rst
@@ -40,6 +40,12 @@ run-file
log-run
Command to run for log consumption. Default: `multilog t ./main`
+owner
+ User to chown to.
+
+group
+ User to chgrp to.
+
servicedir
Directory to install into. Default: `/service`
diff --git a/cdist/conf/type/__daemontools_service/manifest b/cdist/conf/type/__daemontools_service/manifest
index 78bae285..8a81b5f5 100755
--- a/cdist/conf/type/__daemontools_service/manifest
+++ b/cdist/conf/type/__daemontools_service/manifest
@@ -9,6 +9,8 @@ servicedir=$(cat "$__object/parameter/servicedir")
run=$(cat "$__object/parameter/run")
runfile=$(cat "$__object/parameter/run-file")
logrun=$(cat "$__object/parameter/log-run")
+owner=$(cat "$__object/parameter/owner")
+group=$(cat "$__object/parameter/group")
svc=$(cat "$__type/explorer/svc")
@@ -25,14 +27,22 @@ badusage() {
[ -z "$run$runfile" ] && badusage
[ -n "$run" ] && [ -n "$runfile" ] && badusage
-__directory "$servicedir/$name/log/main" --parents
+flags=""
+if [ -n "$owner" ]; then
+ flags="$flags --owner $owner"
+fi
+if [ -n "$group" ]; then
+ flags="$flags --group $group"
+fi
+
+__directory "$servicedir/$name/log/main" --parents $flags
echo "$RUN_PREFIX$run" | require="__directory/$servicedir/$name/log/main" __config_file "$servicedir/$name/run" \
--onchange "svc -t '$servicedir/$name' 2>/dev/null" \
- --mode 755 \
+ --mode 755 $flags \
--source "${runfile:--}"
echo "$RUN_PREFIX$logrun" | require="__directory/$servicedir/$name/log/main" __config_file "$servicedir/$name/log/run" \
--onchange "svc -t '$servicedir/$name/log' 2>/dev/null" \
- --mode 755 \
+ --mode 755 $flags \
--source "-"
diff --git a/cdist/conf/type/__daemontools_service/parameter/default/group b/cdist/conf/type/__daemontools_service/parameter/default/group
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__daemontools_service/parameter/default/owner b/cdist/conf/type/__daemontools_service/parameter/default/owner
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__daemontools_service/parameter/optional b/cdist/conf/type/__daemontools_service/parameter/optional
index 7e54985f..7c66b514 100644
--- a/cdist/conf/type/__daemontools_service/parameter/optional
+++ b/cdist/conf/type/__daemontools_service/parameter/optional
@@ -1,4 +1,6 @@
+group
log-run
+owner
run
run-file
servicedir
diff --git a/cdist/conf/type/__directory/explorer/stat b/cdist/conf/type/__directory/explorer/stat
index 3d150a21..105d894f 100755
--- a/cdist/conf/type/__directory/explorer/stat
+++ b/cdist/conf/type/__directory/explorer/stat
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -20,23 +21,80 @@
destination="/$__object_id"
+fallback() {
+ # Patch the output together, manually
+
+ ls_line=$(ls -ldn "$destination")
+
+ uid=$(echo "$ls_line" | awk '{ print $3 }')
+ gid=$(echo "$ls_line" | awk '{ print $4 }')
+
+ owner=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/passwd)
+ group=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group)
+
+ mode_text=$(echo "$ls_line" | awk '{ print $1 }')
+ mode=$(echo "$mode_text" | awk '{ k=0; for (i=0; i<=8; i++) k += ((substr($1, i+2, 1) ~ /[rwx]/) * 2^(8-i)); printf("%0o", k) }')
+
+ printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\n' \
+ "$("$__type_explorer/type")" \
+ "$uid" "$owner" \
+ "$gid" "$group" \
+ "$mode" "$mode_text"
+}
+
# nothing to work with, nothing we could do
[ -e "$destination" ] || exit 0
-os=$("$__explorer/os")
-case "$os" in
+if ! command -v stat >/dev/null
+then
+ fallback
+ exit
+fi
+
+case $("$__explorer/os") in
"freebsd"|"netbsd"|"openbsd"|"macosx")
stat -f "type: %HT
owner: %Du %Su
group: %Dg %Sg
mode: %Lp %Sp
-" "$destination" | awk '/^type/ { print tolower($0); next; } { print; }'
- ;;
+" "$destination" | awk '/^type/ { print tolower($0); next } { print }'
+ ;;
+ solaris)
+ ls1="$( ls -ld "$destination" )"
+ ls2="$( ls -ldn "$destination" )"
+
+ if [ -f "$__object/parameter/mode" ]
+ then mode_should="$( cat "$__object/parameter/mode" )"
+ fi
+
+ # yes, it is ugly hack, but if you know better way...
+ if [ -z "$( find "$destination" -perm "$mode_should" )" ]
+ then octets=888
+ else octets="$( echo "$mode_should" | sed 's/^0//' )"
+ fi
+
+ case "$( echo "$ls1" | cut -c1-1 )" in
+ -) echo 'type: regular file' ;;
+ d) echo 'type: directory' ;;
+ esac
+
+ echo "owner: $( echo "$ls2" \
+ | awk '{print $3}' ) $( echo "$ls1" \
+ | awk '{print $3}' )"
+
+ echo "group: $( echo "$ls2" \
+ | awk '{print $4}' ) $( echo "$ls1" \
+ | awk '{print $4}' )"
+
+ echo "mode: $octets $( echo "$ls1" | awk '{print $1}' )"
+ ;;
*)
- stat --printf="type: %F
+ # NOTE: Do not use --printf here as it is not supported by BusyBox stat.
+ # NOTE: BusyBox's stat might not support the "-c" option, in which case
+ # we fall through to the shell fallback.
+ stat -c "type: %F
owner: %u %U
group: %g %G
-mode: %a %A
-" "$destination"
+mode: %a %A" "$destination" 2>/dev/null || fallback
;;
esac
diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote
index 374db47a..a1a32ea2 100755
--- a/cdist/conf/type/__directory/gencode-remote
+++ b/cdist/conf/type/__directory/gencode-remote
@@ -3,6 +3,7 @@
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
# 2014 Daniel Heule (hda at sfs.biz)
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -21,8 +22,8 @@
#
destination="/$__object_id"
-state_should="$(cat "$__object/parameter/state")"
-type="$(cat "$__object/explorer/type")"
+state_should=$(cat "$__object/parameter/state")
+type=$(cat "$__object/explorer/type")
stat_file="$__object/explorer/stat"
# variable to keep track if we have to set directory attributes
@@ -72,7 +73,7 @@ set_mode() {
}
case "$state_should" in
- present)
+ present|exists)
if [ "$type" != "directory" ]; then
set_attributes=1
if [ "$type" != "none" ]; then
@@ -83,6 +84,10 @@ case "$state_should" in
fi
echo "mkdir $mkdiropt '$destination'"
echo "create" >> "$__messages_out"
+ elif [ "$state_should" = 'exists' ]; then
+ # The type is directory and --state exists. We are done and do not
+ # check or set the attributes.
+ exit 0
fi
# Note: Mode - needs to happen last as a chown/chgrp can alter mode by
@@ -103,6 +108,26 @@ case "$state_should" in
fi
done
;;
+ pre-exists)
+ case $type in
+ directory)
+ # all good
+ exit 0
+ ;;
+ none)
+ printf 'Directory "%s" does not exist\n' "$destination" >&2
+ exit 1
+ ;;
+ file|symlink)
+ printf 'File "%s" exists and is a %s, but should be a directory\n' "$destination" "$type" >&2
+ exit 1
+ ;;
+ *)
+ printf 'File or directory "%s" is in an unknown state\n' "$destination" >&2
+ exit 1
+ ;;
+ esac
+ ;;
absent)
if [ "$type" = "directory" ]; then
echo "rm -rf '$destination'"
diff --git a/cdist/conf/type/__directory/man.rst b/cdist/conf/type/__directory/man.rst
index 74b00afe..7755334c 100644
--- a/cdist/conf/type/__directory/man.rst
+++ b/cdist/conf/type/__directory/man.rst
@@ -19,7 +19,18 @@ None.
OPTIONAL PARAMETERS
-------------------
state
- 'present' or 'absent', defaults to 'present'
+ 'present', 'absent', 'exists' or 'pre-exists', defaults to 'present' where:
+
+ present
+ the directory exists and the given attributes are set.
+ absent
+ the directory does not exist.
+ exists
+ the directory exists, but its attributes are not altered if it already
+ existed.
+ pre-exists
+ check that the directory exists and is indeed a directory, but do not
+ create or modify it.
group
Group to chgrp to.
@@ -36,7 +47,7 @@ BOOLEAN PARAMETERS
parents
Whether to create parents as well (mkdir -p behaviour).
Warning: all intermediate directory permissions default
- to whatever mkdir -p does.
+ to whatever mkdir -p does.
Usually this means root:root, 0700.
diff --git a/cdist/conf/type/__docker/manifest b/cdist/conf/type/__docker/manifest
index 04a9ff27..6a57d85a 100755
--- a/cdist/conf/type/__docker/manifest
+++ b/cdist/conf/type/__docker/manifest
@@ -64,6 +64,43 @@ case "$os" in
require="__apt_source/docker" __package docker-ce --state "${state}"
fi
;;
+ devuan)
+ os_version="$(cat "$__global/explorer/os_version")"
+
+ case "$os_version" in
+ ascii)
+ distribution="stretch"
+ ;;
+ jessie)
+ distribution="jessie"
+ ;;
+ *)
+ echo "Your devuan release ($os_version) is currently not supported by this type (${__type##*/}).">&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+ esac
+
+ if [ "${state}" = "present" ]; then
+ __package apt-transport-https
+ __package ca-certificates
+ __package gnupg2
+ fi
+ __apt_key_uri docker --name "Docker Release (CE deb) " \
+ --uri "https://download.docker.com/linux/${os}/gpg" --state "${state}"
+
+ require="__apt_key_uri/docker" __apt_source docker \
+ --uri "https://download.docker.com/linux/${os}" \
+ --distribution "${distribution}" \
+ --state "${state}" \
+ --component "stable"
+ if [ "$version" != "latest" ]; then
+ require="__apt_source/docker" __package docker-ce --version "${version}" --state "${state}"
+ else
+ require="__apt_source/docker" __package docker-ce --state "${state}"
+ fi
+
+ ;;
*)
echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
diff --git a/cdist/conf/type/__docker_swarm/explorer/swarm-state b/cdist/conf/type/__docker_swarm/explorer/swarm-state
index 9c1bc32d..2c9fd598 100755
--- a/cdist/conf/type/__docker_swarm/explorer/swarm-state
+++ b/cdist/conf/type/__docker_swarm/explorer/swarm-state
@@ -18,4 +18,4 @@
# along with cdist. If not, see .
#
-docker info 2>/dev/null | grep "^Swarm: " | cut -d " " -f 2-
+docker info 2>/dev/null | grep '^ *Swarm: ' | awk '{print $2}'
diff --git a/cdist/conf/type/__file/explorer/stat b/cdist/conf/type/__file/explorer/stat
index fec0d6f3..91c8cc84 100755
--- a/cdist/conf/type/__file/explorer/stat
+++ b/cdist/conf/type/__file/explorer/stat
@@ -1,6 +1,8 @@
#!/bin/sh
#
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -20,27 +22,95 @@
destination="/$__object_id"
+fallback() {
+ # Fallback: Patch the output together, manually.
+
+ ls_line=$(ls -ldn "$destination")
+
+ uid=$(echo "$ls_line" | awk '{ print $3 }')
+ gid=$(echo "$ls_line" | awk '{ print $4 }')
+
+ owner=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/passwd)
+ group=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group)
+
+ mode_text=$(echo "$ls_line" | awk '{ print $1 }')
+ mode=$(echo "$mode_text" | awk '{ k=0; for (i=0; i<=8; i++) k += ((substr($1, i+2, 1) ~ /[rwx]/) * 2^(8-i)); printf("%0o", k) }')
+
+ size=$(echo "$ls_line" | awk '{ print $5 }')
+ links=$(echo "$ls_line" | awk '{ print $2 }')
+
+ printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\nsize: %d\nlinks: %d\n' \
+ "$("$__type_explorer/type")" \
+ "$uid" "$owner" \
+ "$gid" "$group" \
+ "$mode" "$mode_text" \
+ "$size" \
+ "$links"
+}
+
+
# nothing to work with, nothing we could do
[ -e "$destination" ] || exit 0
-os=$("$__explorer/os")
-case "$os" in
- "freebsd"|"netbsd"|"openbsd"|"macosx")
+
+if ! command -v stat >/dev/null
+then
+ fallback
+ exit
+fi
+
+
+case $("$__explorer/os")
+in
+ freebsd|netbsd|openbsd|macosx)
stat -f "type: %HT
owner: %Du %Su
group: %Dg %Sg
mode: %Lp %Sp
size: %Dz
links: %Dl
-" "$destination" | awk '/^type/ { print tolower($0); next; } { print; }'
- ;;
+" "$destination" | awk '/^type/ { print tolower($0); next } { print }'
+ ;;
+ solaris)
+ ls1="$( ls -ld "$destination" )"
+ ls2="$( ls -ldn "$destination" )"
+
+ if [ -f "$__object/parameter/mode" ]
+ then mode_should="$( cat "$__object/parameter/mode" )"
+ fi
+
+ # yes, it is ugly hack, but if you know better way...
+ if [ -z "$( find "$destination" -perm "$mode_should" )" ]
+ then octets=888
+ else octets="$( echo "$mode_should" | sed 's/^0//' )"
+ fi
+
+ case "$( echo "$ls1" | cut -c1-1 )" in
+ -) echo 'type: regular file' ;;
+ d) echo 'type: directory' ;;
+ esac
+
+ echo "owner: $( echo "$ls2" \
+ | awk '{print $3}' ) $( echo "$ls1" \
+ | awk '{print $3}' )"
+
+ echo "group: $( echo "$ls2" \
+ | awk '{print $4}' ) $( echo "$ls1" \
+ | awk '{print $4}' )"
+
+ echo "mode: $octets $( echo "$ls1" | awk '{print $1}' )"
+ echo "size: $( echo "$ls1" | awk '{print $5}' )"
+ echo "links: $( echo "$ls1" | awk '{print $2}' )"
+ ;;
*)
- stat --printf="type: %F
+ # NOTE: Do not use --printf here as it is not supported by BusyBox stat.
+ # NOTE: BusyBox's stat might not support the "-c" option, in which case
+ # we fall through to the shell fallback.
+ stat -c "type: %F
owner: %u %U
group: %g %G
mode: %a %A
size: %s
-links: %h
-" "$destination"
- ;;
+links: %h" "$destination" 2>/dev/null || fallback
+ ;;
esac
diff --git a/cdist/conf/type/__file/gencode-local b/cdist/conf/type/__file/gencode-local
index fb9f9a92..231b6927 100755
--- a/cdist/conf/type/__file/gencode-local
+++ b/cdist/conf/type/__file/gencode-local
@@ -31,12 +31,24 @@ if [ "$state_should" = "pre-exists" ]; then
exit 1
fi
- if [ "$type" = "file" ]; then
- exit 0 # nothing to do
- else
- echo "File \"$destination\" does not exist"
- exit 1
- fi
+ case $type in
+ file)
+ # nothing to do
+ exit 0
+ ;;
+ none)
+ printf 'File "%s" does not exist\n' "$destination" >&2
+ exit 1
+ ;;
+ directory|symlink)
+ printf 'File "%s" exists and is a %s, but should be a regular file\n' "$destination" "$type" >&2
+ exit 1
+ ;;
+ *)
+ printf 'File or directory "%s" is in an unknown state\n' "$destination" >&2
+ exit 1
+ ;;
+ esac
fi
upload_file=
diff --git a/cdist/conf/type/__file/gencode-remote b/cdist/conf/type/__file/gencode-remote
index b04c471e..815593bd 100755
--- a/cdist/conf/type/__file/gencode-remote
+++ b/cdist/conf/type/__file/gencode-remote
@@ -55,37 +55,41 @@ set_owner() {
}
set_mode() {
- echo "chmod '$1' '$destination'"
- echo "chmod '$1'" >> "$__messages_out"
- fire_onchange=1
+ echo "chmod '$1' '$destination'"
+ echo "chmod '$1'" >> "$__messages_out"
+ fire_onchange=1
}
case "$state_should" in
- present|exists|pre-exists)
- # Note: Mode - needs to happen last as a chown/chgrp can alter mode by
- # clearing S_ISUID and S_ISGID bits (see chown(2))
- for attribute in group owner mode; do
- if [ -f "$__object/parameter/$attribute" ]; then
- value_should="$(cat "$__object/parameter/$attribute")"
+ present|exists)
+ # Note: Mode - needs to happen last as a chown/chgrp can alter mode by
+ # clearing S_ISUID and S_ISGID bits (see chown(2))
+ for attribute in group owner mode; do
+ if [ -f "$__object/parameter/$attribute" ]; then
+ value_should="$(cat "$__object/parameter/$attribute")"
- # change 0xxx format to xxx format => same as stat returns
- if [ "$attribute" = mode ]; then
- value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')"
- fi
-
- value_is="$(get_current_value "$attribute" "$value_should")"
- if [ -f "$__object/files/set-attributes" ] || [ "$value_should" != "$value_is" ]; then
- "set_$attribute" "$value_should"
+ # change 0xxx format to xxx format => same as stat returns
+ if [ "$attribute" = mode ]; then
+ value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')"
+ fi
+
+ value_is="$(get_current_value "$attribute" "$value_should")"
+ if [ -f "$__object/files/set-attributes" ] || [ "$value_should" != "$value_is" ]; then
+ "set_$attribute" "$value_should"
+ fi
fi
+ done
+ if [ -f "$__object/files/set-attributes" ]; then
+ # set-attributes is created if file is created or uploaded in gencode-local
+ fire_onchange=1
fi
- done
- if [ -f "$__object/files/set-attributes" ]; then
- # set-attributes is created if file is created or uploaded in gencode-local
- fire_onchange=1
- fi
-
;;
+ pre-exists)
+ # pre-exists should never reach gencode-remote…
+ exit 1
+ ;;
+
absent)
if [ "$type" = "file" ]; then
echo "rm -f '$destination'"
@@ -101,7 +105,7 @@ case "$state_should" in
esac
if [ -f "$__object/parameter/onchange" ]; then
- if [ -n "$fire_onchange" ]; then
- cat "$__object/parameter/onchange"
- fi
+ if [ -n "$fire_onchange" ]; then
+ cat "$__object/parameter/onchange"
+ fi
fi
diff --git a/cdist/conf/type/__git/gencode-remote b/cdist/conf/type/__git/gencode-remote
index 5a9e23fc..ab22655f 100755
--- a/cdist/conf/type/__git/gencode-remote
+++ b/cdist/conf/type/__git/gencode-remote
@@ -19,32 +19,34 @@
#
#
-state_is="$(cat "$__object/explorer/state")"
-owner_is="$(cat "$__object/explorer/owner")"
-group_is="$(cat "$__object/explorer/group")"
+state_is=$(cat "$__object/explorer/state")
+owner_is=$(cat "$__object/explorer/owner")
+group_is=$(cat "$__object/explorer/group")
-state_should="$(cat "$__object/parameter/state")"
+state_should=$(cat "$__object/parameter/state")
-branch="$(cat "$__object/parameter/branch")"
+branch=$(cat "$__object/parameter/branch")
-source="$(cat "$__object/parameter/source")"
+source=$(cat "$__object/parameter/source")
destination="/$__object_id"
-owner="$(cat "$__object/parameter/owner")"
-group="$(cat "$__object/parameter/group")"
-mode="$(cat "$__object/parameter/mode")"
+owner=$(cat "$__object/parameter/owner")
+group=$(cat "$__object/parameter/group")
+mode=$(cat "$__object/parameter/mode")
-[ "$state_should" = "$state_is" ] && \
-[ "$owner" = "$owner_is" ] && \
-[ "$group" = "$group_is" ] && \
-[ -n "$mode" ] && exit 0
+[ -f "$__object/parameter/recursive" ] && recursive='--recurse-submodules' || recursive=''
+[ -f "$__object/parameter/shallow" ] && shallow='--depth 1 --shallow-submodules' || shallow=''
+
+[ "$state_should" = "$state_is" ] \
+ && [ "$owner" = "$owner_is" ] \
+ && [ "$group" = "$group_is" ] \
+ && [ -n "$mode" ] && exit 0
case $state_should in
present)
-
if [ "$state_should" != "$state_is" ]; then
- echo git clone --quiet --branch "$branch" "$source" "$destination"
+ echo git clone --quiet "$recursive" "$shallow" --branch "$branch" "$source" "$destination"
fi
if { [ -n "$owner" ] && [ "$owner_is" != "$owner" ]; } || \
{ [ -n "$group" ] && [ "$group_is" != "$group" ]; }; then
@@ -54,8 +56,9 @@ case $state_should in
echo chmod -R "$mode" "$destination"
fi
;;
- # Handled in manifest
+
absent)
+ # Handled in manifest
;;
*)
diff --git a/cdist/conf/type/__git/man.rst b/cdist/conf/type/__git/man.rst
index 17e9c623..d3e15f25 100644
--- a/cdist/conf/type/__git/man.rst
+++ b/cdist/conf/type/__git/man.rst
@@ -35,6 +35,12 @@ mode
owner
User to chown to.
+recursive
+ Passes the --recurse-submodules flag to git when cloning the repository.
+
+shallow
+ Sets --depth=1 and --shallow-submodules for cloning repositories with big history.
+
EXAMPLES
--------
@@ -44,7 +50,7 @@ EXAMPLES
__git /home/services/dokuwiki --source git://github.com/splitbrain/dokuwiki.git
# Checkout cdist, stay on branch 2.1
- __git /home/nico/cdist --source git://github.com/ungleich/cdist.git --branch 2.1
+ __git /home/nico/cdist --source git@code.ungleich.ch:ungleich-public/cdist.git --branch 2.1
AUTHORS
diff --git a/cdist/conf/type/__git/parameter/boolean b/cdist/conf/type/__git/parameter/boolean
new file mode 100644
index 00000000..d600d4ca
--- /dev/null
+++ b/cdist/conf/type/__git/parameter/boolean
@@ -0,0 +1,2 @@
+recursive
+shallow
diff --git a/cdist/conf/type/__grafana_dashboard/manifest b/cdist/conf/type/__grafana_dashboard/manifest
index 9cd1465d..d145c4c3 100755
--- a/cdist/conf/type/__grafana_dashboard/manifest
+++ b/cdist/conf/type/__grafana_dashboard/manifest
@@ -8,10 +8,16 @@ case $os in
debian|devuan)
case $os_version in
8*|jessie)
- apt_source_distribution=jessie
+ # Differntation not needed anymore
+ apt_source_distribution=stable
;;
9*|ascii/ceres|ascii)
- apt_source_distribution=stretch
+ # Differntation not needed anymore
+ apt_source_distribution=stable
+ ;;
+ 10*)
+ # Differntation not needed anymore
+ apt_source_distribution=stable
;;
*)
echo "Don't know how to install Grafana on $os $os_version. Send us a pull request!" >&2
@@ -21,16 +27,15 @@ case $os in
__apt_key_uri grafana \
--name 'Grafana Release Signing Key' \
- --uri https://packagecloud.io/gpg.key
+ --uri https://packages.grafana.com/gpg.key
require="$require __apt_key_uri/grafana" __apt_source grafana \
- --uri https://packagecloud.io/grafana/stable/debian/ \
+ --uri https://packages.grafana.com/oss/deb \
--distribution $apt_source_distribution \
--component main
-
__package apt-transport-https
-
- require="$require __apt_source/grafana __package/apt-transport-https" __package grafana
+ require="$require __apt_source/grafana" __apt_update_index
+ require="$require __package/apt-transport-https __apt_update_index" __package grafana
require="$require __package/grafana" __start_on_boot grafana-server
require="$require __start_on_boot/grafana-server" __process grafana-server --start "service grafana-server start"
;;
diff --git a/cdist/conf/type/__group/explorer/group b/cdist/conf/type/__group/explorer/group
index 07f73a91..dc673f61 100755
--- a/cdist/conf/type/__group/explorer/group
+++ b/cdist/conf/type/__group/explorer/group
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2011-2015 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -21,7 +22,21 @@
# Get an existing groups group entry.
#
+not_supported() {
+ echo "Your operating system ($("$__explorer/os")) is currently not supported." >&2
+ echo "Cannot extract group information." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+}
+
name=$__object_id
-getent group "$name" || true
-
+if command -v getent >/dev/null
+then
+ getent group "$name" || true
+elif [ -f /etc/group ]
+then
+ grep "^${name}:" /etc/group || true
+else
+ not_supported
+fi
diff --git a/cdist/conf/type/__group/explorer/gshadow b/cdist/conf/type/__group/explorer/gshadow
index ef40b7bc..05841d69 100755
--- a/cdist/conf/type/__group/explorer/gshadow
+++ b/cdist/conf/type/__group/explorer/gshadow
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2011-2015 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -22,13 +23,28 @@
#
name=$__object_id
-os="$("$__explorer/os")"
+os=$("$__explorer/os")
-case "$os" in
- "freebsd"|"netbsd")
- echo "$os does not have getent gshadow"
- exit 0
- ;;
+not_supported() {
+ echo "Your operating system ($os) is currently not supported." >&2
+ echo "Cannot extract group information." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+}
+
+case $os in
+ "freebsd"|"netbsd")
+ echo "$os does not have getent gshadow" >&2
+ exit 0
+ ;;
esac
-getent gshadow "$name" || true
+if command -v getent >/dev/null
+then
+ getent gshadow "$name" || true
+elif [ -f /etc/gshadow ]
+then
+ grep "^${name}:" /etc/gshadow || true
+else
+ not_supported
+fi
diff --git a/cdist/conf/type/__hostname/explorer/has_hostnamectl b/cdist/conf/type/__hostname/explorer/has_hostnamectl
index 9040023d..2f531f30 100755
--- a/cdist/conf/type/__hostname/explorer/has_hostnamectl
+++ b/cdist/conf/type/__hostname/explorer/has_hostnamectl
@@ -21,4 +21,4 @@
# Check whether system has hostnamectl
#
-command -v hostnamectl || true
+command -v hostnamectl 2>/dev/null || true
diff --git a/cdist/conf/type/__hostname/explorer/max_len b/cdist/conf/type/__hostname/explorer/max_len
new file mode 100644
index 00000000..fb863949
--- /dev/null
+++ b/cdist/conf/type/__hostname/explorer/max_len
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+command -v getconf >/dev/null || exit 0
+
+val=$(getconf HOST_NAME_MAX 2>/dev/null) || exit 0
+
+if test -n "${val}" -a "${val}" != 'undefined'
+then
+ echo "${val}"
+fi
diff --git a/cdist/conf/type/__hostname/gencode-remote b/cdist/conf/type/__hostname/gencode-remote
index 33947f7f..ae224611 100755
--- a/cdist/conf/type/__hostname/gencode-remote
+++ b/cdist/conf/type/__hostname/gencode-remote
@@ -2,6 +2,7 @@
#
# 2014-2017 Steven Armstrong (steven-cdist at armstrong.cc)
# 2014 Nico Schottelius (nico-cdist at schottelius.org)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -19,60 +20,81 @@
# along with cdist. If not, see .
#
-if [ -f "$__object/parameter/name" ]; then
- name_should="$(cat "$__object/parameter/name")"
-else
- name_should="${__target_host%%.*}"
-fi
-
os=$(cat "$__global/explorer/os")
name_running=$(cat "$__global/explorer/hostname")
-name_config=$(cat "$__object/explorer/hostname_file")
-name_sysconfig=$(cat "$__object/explorer/hostname_sysconfig")
has_hostnamectl=$(cat "$__object/explorer/has_hostnamectl")
+
+if test -s "$__object/parameter/name"
+then
+ name_should=$(cat "$__object/parameter/name")
+else
+ case $os
+ in
+ # RedHat-derivatives and BSDs
+ centos|fedora|redhat|scientific|freebsd|macosx|netbsd|openbsd)
+ # Hostname is FQDN
+ name_should="${__target_host}"
+ ;;
+ *)
+ # Hostname is only first component of FQDN
+ name_should="${__target_host%%.*}"
+ ;;
+ esac
+fi
+
+
################################################################################
-# If everything is ok -> exit
+# Check if the (running) hostname is already correct
#
-case "$os" in
- archlinux|debian|suse|ubuntu|devuan|coreos)
- if [ "$name_config" = "$name_should" ] && [ "$name_running" = "$name_should" ]; then
- exit 0
- fi
- ;;
- scientific|centos|freebsd|openbsd)
- if [ "$name_sysconfig" = "$name_should" ] && [ "$name_running" = "$name_should" ]; then
- exit 0
- fi
- ;;
- *)
- echo "Unsupported os: $os" >&2
- exit 1
- ;;
-esac
+test "$name_running" != "$name_should" || exit 0
+
################################################################################
# Setup hostname
#
-echo changed >> "$__messages_out"
+echo 'changed' >>"$__messages_out"
-# Use the good old way to set the hostname even on machines running systemd.
-case "$os" in
- archlinux|debian|ubuntu|devuan|centos|coreos)
- printf "printf '%%s\\\\n' '$name_should' > /etc/hostname\\n"
- echo "hostname -F /etc/hostname"
+# Use the good old way to set the hostname.
+case $os
+in
+ alpine|debian|devuan|ubuntu)
+ echo 'hostname -F /etc/hostname'
;;
- freebsd|openbsd)
+ archlinux)
+ echo 'command -v hostnamectl >/dev/null 2>&1' \
+ "&& hostnamectl set-hostname '$name_should'" \
+ "|| hostname '$name_should'"
+ ;;
+ centos|fedora|redhat|scientific|freebsd|netbsd|openbsd|gentoo|void)
echo "hostname '$name_should'"
;;
- suse)
+ macosx)
+ echo "scutil --set HostName '$name_should'"
+ ;;
+ solaris)
+ echo "uname -S '$name_should'"
+ ;;
+ slackware|suse|opensuse-leap)
+ # We do not read from /etc/HOSTNAME, because the running
+ # hostname is the first component only while the file contains
+ # the FQDN.
echo "hostname '$name_should'"
- printf "printf '%%s\\\\n' '$name_should' > /etc/HOSTNAME\\n"
+ ;;
+ *)
+ # Fall back to set the hostname using hostnamectl, if available.
+ if test -n "$has_hostnamectl"
+ then
+ # Don't use hostnamectl as the primary means to set the hostname for
+ # systemd systems, because it cannot be trusted to work reliably and
+ # exit with non-zero when it fails (e.g. hostname too long,
+ # D-Bus failure, etc.).
+
+ echo "hostnamectl set-hostname \"\$(cat /etc/hostname)\""
+ echo "test \"\$(hostname)\" = \"\$(cat /etc/hostname)\"" \
+ " || hostname -F /etc/hostname"
+ else
+ printf "echo 'Unsupported OS: %s' >&2\nexit 1\n" "$os"
+ fi
;;
esac
-
-if [ "$has_hostnamectl" ]; then
- # Allow hostnamectl set-hostname to fail silently.
- # Who the fuck invented a tool that needs dbus to set the hostname anyway ...
- echo "hostnamectl set-hostname '$name_should' || true"
-fi
diff --git a/cdist/conf/type/__hostname/man.rst b/cdist/conf/type/__hostname/man.rst
index d23a3b8a..72aefbab 100644
--- a/cdist/conf/type/__hostname/man.rst
+++ b/cdist/conf/type/__hostname/man.rst
@@ -8,7 +8,10 @@ cdist-type__hostname - Set the hostname
DESCRIPTION
-----------
-Set's the hostname on various operating systems.
+Sets the hostname on various operating systems.
+
+**Tip:** For advice on choosing a hostname, see
+`RFC 1178 `_.
REQUIRED PARAMETERS
@@ -18,7 +21,7 @@ None.
OPTIONAL PARAMETERS
-------------------
name
- The hostname to set. Defaults to the first segment of __target_host
+ The hostname to set. Defaults to the first segment of __target_host
(${__target_host%%.*})
diff --git a/cdist/conf/type/__hostname/manifest b/cdist/conf/type/__hostname/manifest
index c03b2eac..e1e356a0 100755
--- a/cdist/conf/type/__hostname/manifest
+++ b/cdist/conf/type/__hostname/manifest
@@ -2,6 +2,7 @@
#
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
# 2014 Nico Schottelius (nico-cdist at schottelius.org)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -19,50 +20,170 @@
# along with cdist. If not, see .
#
+not_supported() {
+ echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+}
+
+set_hostname_systemd() {
+ echo "$1" | __file /etc/hostname --source -
+}
+
os=$(cat "$__global/explorer/os")
-if [ -f "$__object/parameter/name" ]; then
- name_should="$(cat "$__object/parameter/name")"
+os_version=$(cat "$__global/explorer/os_version")
+os_major=$(echo "$os_version" | grep -o '^[0-9][0-9]*' || true)
+
+max_len=$(cat "$__object/explorer/max_len")
+has_hostnamectl=$(cat "$__object/explorer/has_hostnamectl")
+
+if test -s "$__object/parameter/name"
+then
+ name_should=$(cat "$__object/parameter/name")
else
- case "$os" in
- openbsd)
- name_should="${__target_host}"
- ;;
- *)
- name_should="${__target_host%%.*}"
- ;;
+ case $os
+ in
+ # RedHat-derivatives and BSDs
+ centos|fedora|redhat|scientific|freebsd|netbsd|openbsd|slackware)
+ # Hostname is FQDN
+ name_should="${__target_host}"
+ ;;
+ suse|opensuse-leap)
+ # Classic SuSE stores the FQDN in /etc/HOSTNAME, while
+ # systemd does not. The running hostname is the first
+ # component in both cases.
+ # In versions before 15.x, the FQDN is stored in /etc/hostname.
+ if test -n "$has_hostnamectl" && test "$os_major" -ge 15 \
+ && test "$os_major" -ne 42
+ then
+ name_should="${__target_host%%.*}"
+ else
+ name_should="${__target_host}"
+ fi
+ ;;
+ *)
+ # Hostname is only first component of FQDN on all other systems.
+ name_should="${__target_host%%.*}"
+ ;;
esac
fi
+if test -n "$max_len" && test "$(printf '%s' "$name_should" | wc -c)" -gt "$max_len"
+then
+ printf "Host name too long. Up to %u characters allowed.\n" "${max_len}" >&2
+ exit 1
+fi
-not_supported() {
- echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
- echo "Please contribute an implementation for it if you can." >&2
- exit 1
-}
+case $os
+in
+ alpine|debian|devuan|ubuntu|void)
+ echo "$name_should" | __file /etc/hostname --source -
+ ;;
+ archlinux)
+ if test -n "$has_hostnamectl"
+ then
+ set_hostname_systemd "$name_should"
+ else
+ echo 'Ancient ArchLinux variants without hostnamectl are not supported.' >&2
+ exit 1
+ # Only for ancient ArchLinux, write to /etc/rc.conf on pre-systemd
+ # versions. There are some versions which use /etc/hostname but not
+ # systemd. It is unclear which ones these are.
-case "$os" in
- archlinux|debian|suse|ubuntu|devuan|coreos)
+ # __key_value '/etc/rc.conf:HOSTNAME' \
+ # --file /etc/rc.conf \
+ # --delimiter '=' --exact_delimiter \
+ # --key 'HOSTNAME' \
+ # --value "\"$name_should\""
+ fi
+ ;;
+ centos|fedora|redhat|scientific)
+ if test -z "$has_hostnamectl"
+ then
+ # Only write to /etc/sysconfig/network on non-systemd versions.
+ # On systemd-based versions this entry is ignored.
+ __key_value '/etc/sysconfig/network:HOSTNAME' \
+ --file /etc/sysconfig/network \
+ --delimiter '=' --exact_delimiter \
+ --key HOSTNAME \
+ --value "\"$name_should\""
+ else
+ set_hostname_systemd "$name_should"
+ fi
+ ;;
+ gentoo)
+ # Only write to /etc/conf.d/hostname on OpenRC-based installations.
+ # On systemd use hostnamectl(1) in gencode-remote.
+ if test -z "$has_hostnamectl"
+ then
+ __key_value '/etc/conf.d/hostname:hostname' \
+ --file /etc/conf.d/hostname \
+ --delimiter '=' --exact_delimiter \
+ --key 'hostname' \
+ --value "\"$name_should\""
+ else
+ set_hostname_systemd "$name_should"
+ fi
+ ;;
+ freebsd)
+ __key_value '/etc/rc.conf:hostname' \
+ --file /etc/rc.conf \
+ --delimiter '=' --exact_delimiter \
+ --key 'hostname' \
+ --value "\"$name_should\""
+ ;;
+ macosx)
# handled in gencode-remote
:
;;
- scientific|centos)
- __key_value sysconfig-hostname \
- --file /etc/sysconfig/network \
- --delimiter '=' \
- --key HOSTNAME \
- --value "$name_should" --exact_delimiter
- ;;
- freebsd)
- __key_value rcconf-hostname \
+ netbsd)
+ __key_value '/etc/rc.conf:hostname' \
--file /etc/rc.conf \
- --delimiter '=' \
+ --delimiter '=' --exact_delimiter \
--key 'hostname' \
- --value "$name_should"
+ --value "\"$name_should\""
+
+ # To avoid confusion, ensure that the hostname is only stored once.
+ __file /etc/myname --state absent
;;
openbsd)
echo "$name_should" | __file /etc/myname --source -
;;
+ slackware)
+ # We write the FQDN into /etc/HOSTNAME. But /etc/rc.d/rc.M will only
+ # read the first component from this file and set it as the running
+ # hostname on boot.
+ echo "$name_should" | __file /etc/HOSTNAME --source -
+ ;;
+ solaris)
+ echo "$name_should" | __file /etc/nodename --source -
+ ;;
+ suse|opensuse-leap)
+ # Modern SuSE provides /etc/HOSTNAME as a symlink for
+ # backwards-compatibility. Unfortunately it cannot be used
+ # here as __file does not follow the symlink.
+ # Therefore, we use the presence of the hostnamectl binary as
+ # an indication of which file to use. This unfortunately does
+ # not work correctly on openSUSE 12.x which provides
+ # hostnamectl but not /etc/hostname.
+
+ if test -n "$has_hostnamectl" -a "$os_major" -gt 12
+ then
+ hostname_file='/etc/hostname'
+ else
+ hostname_file='/etc/HOSTNAME'
+ fi
+
+ echo "$name_should" | __file "$hostname_file" --source -
+ ;;
*)
- not_supported
+ # On other operating systems we fall back to systemd's
+ # hostnamectl if available…
+ if test -n "$has_hostnamectl"
+ then
+ set_hostname_systemd "$name_should"
+ else
+ not_supported
+ fi
;;
esac
diff --git a/cdist/conf/type/__install_chroot_umount/manifest b/cdist/conf/type/__install_chroot_umount/manifest
new file mode 120000
index 00000000..f17af67a
--- /dev/null
+++ b/cdist/conf/type/__install_chroot_umount/manifest
@@ -0,0 +1 @@
+../__chroot_umount/manifest
\ No newline at end of file
diff --git a/cdist/conf/type/__install_directory/man.rst b/cdist/conf/type/__install_directory/man.rst
deleted file mode 120000
index 1ad7fa84..00000000
--- a/cdist/conf/type/__install_directory/man.rst
+++ /dev/null
@@ -1 +0,0 @@
-../__directory/man.rst
\ No newline at end of file
diff --git a/cdist/conf/type/__install_directory/man.rst b/cdist/conf/type/__install_directory/man.rst
new file mode 100644
index 00000000..c402cbad
--- /dev/null
+++ b/cdist/conf/type/__install_directory/man.rst
@@ -0,0 +1,101 @@
+cdist-type__install_directory(7)
+================================
+
+NAME
+----
+cdist-type__install_directory - Manage a directory with install command
+
+
+DESCRIPTION
+-----------
+This cdist type allows you to create or remove directories on the target.
+
+
+REQUIRED PARAMETERS
+-------------------
+None.
+
+
+OPTIONAL PARAMETERS
+-------------------
+state
+ 'present' or 'absent', defaults to 'present'
+
+group
+ Group to chgrp to.
+
+mode
+ Unix permissions, suitable for chmod.
+
+owner
+ User to chown to.
+
+
+BOOLEAN PARAMETERS
+------------------
+parents
+ Whether to create parents as well (mkdir -p behaviour).
+ Warning: all intermediate directory permissions default
+ to whatever mkdir -p does.
+
+ Usually this means root:root, 0700.
+
+recursive
+ If supplied the chgrp and chown call will run recursively.
+ This does *not* influence the behaviour of chmod.
+
+MESSAGES
+--------
+chgrp
+ Changed group membership
+chown
+ Changed owner
+chmod
+ Changed mode
+create
+ Empty directory was created
+remove
+ Directory exists, but state is absent, directory will be removed by generated code.
+remove non directory
+ Something other than a directory with the same name exists and was removed prior to create.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # A silly example
+ __install_directory /tmp/foobar
+
+ # Remove a directory
+ __install_directory /tmp/foobar --state absent
+
+ # Ensure /etc exists correctly
+ __install_directory /etc --owner root --group root --mode 0755
+
+ # Create nfs service directory, including parents
+ __install_directory /home/services/nfs --parents
+
+ # Change permissions recursively
+ __install_directory /home/services --recursive --owner root --group root
+
+ # Setup a temp directory
+ __install_directory /local --mode 1777
+
+ # Take it all
+ __install_directory /home/services/kvm --recursive --parents \
+ --owner root --group root --mode 0755 --state present
+
+
+AUTHORS
+-------
+Nico Schottelius
+
+
+COPYING
+-------
+Copyright \(C) 2011 Nico Schottelius. 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.
diff --git a/cdist/conf/type/__install_file/man.rst b/cdist/conf/type/__install_file/man.rst
index c5409167..977ed77c 100644
--- a/cdist/conf/type/__install_file/man.rst
+++ b/cdist/conf/type/__install_file/man.rst
@@ -23,6 +23,10 @@ symlink
directory
replace it with the source file
+One exception is that when state is pre-exists, an error is raised if
+the file would have been created otherwise (e.g. it is not present or
+not a regular file).
+
In any case, make sure that the file attributes are as specified.
@@ -33,7 +37,7 @@ None.
OPTIONAL PARAMETERS
-------------------
state
- 'present', 'absent' or 'exists', defaults to 'present' where:
+ 'present', 'absent', 'exists' or 'pre-exists', defaults to 'present' where:
present
the file is exactly the one from source
@@ -41,6 +45,9 @@ state
the file does not exist
exists
the file from source but only if it doesn't already exist
+ pre-exists
+ check that the file exists and is a regular file, but do not
+ create or modify it
group
Group to chgrp to.
@@ -56,6 +63,9 @@ source
If not supplied, an empty file or directory will be created.
If source is '-' (dash), take what was written to stdin as the file content.
+onchange
+ The code to run if file is modified.
+
MESSAGES
--------
chgrp
@@ -93,6 +103,8 @@ EXAMPLES
__install_file /home/frodo/.bashrc --source "/etc/skel/.bashrc" \
--state exists \
--owner frodo --mode 0600
+ # Check that the file is present, show an error when it is not
+ __install_file /etc/somefile --state pre-exists
# Take file content from stdin
__install_file /tmp/whatever --owner root --group root --mode 644 --source - << DONE
Here goes the content for /tmp/whatever
diff --git a/cdist/conf/type/__iocage_clone/gencode-remote b/cdist/conf/type/__iocage_clone/gencode-remote
new file mode 100755
index 00000000..30d77099
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/gencode-remote
@@ -0,0 +1,152 @@
+#!/bin/sh
+
+state="$(cat $__object/parameter/state)"
+template="$(cat $__object/parameter/template)"
+ip4_addr="$(cat $__object/parameter/bridge)|$(cat $__object/parameter/ip)"
+interfaces="none:none"
+defaultrouter="none"
+vnet="off"
+jail_zfs_dataset="$(cat $__object/parameter/jail_zfs_dataset)"
+devfs_ruleset="$(cat $__object/parameter/devfs_ruleset)"
+allow_socket_af="$(cat $__object/parameter/allow_socket_af)"
+mount_procfs="$(cat $__object/parameter/mount_procfs)"
+mount_linprocfs="$(cat $__object/parameter/mount_linprocfs)"
+
+if [ "X$state" = "Xabsent" ]; then
+ cat <&2
+ create_new=1
+ fi
+fi
+
+if [ \$create_new -eq 0 ]; then
+ if [ "off" == "\$(get_property_iocage jail_zfs "$__object_id")" ]; then
+ current_jail_zfs_dataset=""
+ else
+ current_jail_zfs_dataset="\$(get_property_iocage jail_zfs_dataset "$__object_id")"
+ fi
+fi
+
+configure=0
+if [ \$create_new -eq 1 ]; then
+ configure=1
+elif [ "X$vnet" != "X\$(get_property_iocage vnet "$__object_id")" ]; then
+ configure=1
+elif [ "X$ip4_addr" != "X\$(get_property_iocage ip4_addr "$__object_id")" ]; then
+ configure=1
+elif [ "X$interfaces" != "X\$(get_property_iocage interfaces "$__object_id")" ]; then
+ configure=1
+elif [ "X$defaultrouter" != "X\$(get_property_iocage defaultrouter "$__object_id")" ]; then
+ configure=1
+elif [ "X$mount_procfs" != "X\$(get_property_iocage mount_procfs "$__object_id")" ]; then
+ configure=1
+elif [ "X$devfs_ruleset" != "X\$(get_property_iocage devfs_ruleset "$__object_id")" ]; then
+ configure=1
+elif [ "X$allow_socket_af" != "X\$(get_property_iocage allow_socket_af "$__object_id")" ]; then
+ configure=1
+elif [ "X$jail_zfs_dataset" != "X\$current_jail_zfs_dataset" ]; then
+ configure=1
+fi
+
+if [ \$create_new -eq 1 ]; then
+ echo "Creating jail $__object_id" >&2
+
+ iocage stop $__object_id || true
+ iocage destroy -f $__object_id || true
+ # Without VNETs, we should not need this.
+ # TODO(riso): Use nicer path
+ # /root/cdist/ioc deconfigure $__object_id
+
+ rm -f /iocage/jails/$__object_id
+
+ iocage clone $template tag=$__object_id
+ iocage set boot=on $__object_id
+ UUID=\$(iocage list | grep " $__object_id " | awk "{ print \\\$2; }")
+ rm -f /iocage/jails/$__object_id
+ ln -s /iocage/jails/\$UUID /iocage/jails/$__object_id
+else
+ UUID=\$(iocage list | grep " $__object_id " | awk "{ print \\\$2; }")
+ echo "Jail $__object_id already exists, UUID=\$UUID" >&2
+fi
+
+ROOT="/iocage/jails/\$UUID/root"
+FSTAB="/iocage/jails/\$UUID/fstab"
+rm -f \$FSTAB.new
+touch \$FSTAB.new
+cat $__object/parameter/mount 2>/dev/null | \\
+while read mount; do
+ src=\$(echo \$mount | awk -F: "{ print \\\$1; }")
+ dst_rel=\$(echo \$mount | awk -F: "{ print \\\$2; }")
+ dst="/iocage/jails/\$UUID/root/\$dst_rel"
+ mkdir -p "\$dst"
+ echo "\$src \$dst nullfs rw 0 0" >>\$FSTAB.new
+done
+if [ $mount_linprocfs -eq 1 ]; then
+ echo "linproc /iocage/jails/\$UUID/root/compat/linux/proc linprocfs rw 0 0" >>\$FSTAB.new
+fi
+
+fstab_changed=0
+if diff -q \$FSTAB \$FSTAB.new >/dev/null; then
+ # pass
+else
+ configure=1
+ fstab_changed=1
+fi
+
+if [ \$configure -eq 1 ]; then
+ echo "Configuring jail $__object_id." >&2
+ iocage stop $__object_id || true
+
+ iocage set vnet="$vnet" $__object_id
+ iocage set interfaces="$interfaces" $__object_id
+ iocage set hostname="$__object_id" $__object_id
+ iocage set ip4_addr="$ip4_addr" $__object_id
+ iocage set defaultrouter="$defaultrouter" $__object_id
+ iocage set mount_procfs="$mount_procfs" $__object_id
+ iocage set devfs_ruleset="$devfs_ruleset" $__object_id
+ iocage set allow_socket_af="$allow_socket_af" $__object_id
+ if [ -n "$jail_zfs_dataset" ]; then
+ iocage set jail_zfs=on $__object_id
+ iocage set jail_zfs_dataset="$jail_zfs_dataset" $__object_id
+ else
+ iocage set jail_zfs=off $__object_id
+ fi
+
+ if [ \$fstab_changed -eq 1 ]; then
+ umount -afF \$FSTAB || true
+ mv \$FSTAB.new \$FSTAB
+ fi
+
+ iocage start $__object_id || true
+
+ # Iocage creates new mac address, but arp can have an old mac cached.
+ # TODO(riso): Is this true without VNETs?
+ arp -d -a
+else
+ echo "Jail $__object_id is already configured." >&2
+fi
+rm -f \$FSTAB.new
+EOF
+fi
diff --git a/cdist/conf/type/__iocage_clone/manifest b/cdist/conf/type/__iocage_clone/manifest
new file mode 100644
index 00000000..0684fce8
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/manifest
@@ -0,0 +1 @@
+__package iocage
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/allow_socket_af b/cdist/conf/type/__iocage_clone/parameter/default/allow_socket_af
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/allow_socket_af
@@ -0,0 +1 @@
+0
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/bridge b/cdist/conf/type/__iocage_clone/parameter/default/bridge
new file mode 100644
index 00000000..092f51c8
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/bridge
@@ -0,0 +1 @@
+bridge0
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/devfs_ruleset b/cdist/conf/type/__iocage_clone/parameter/default/devfs_ruleset
new file mode 100644
index 00000000..b8626c4c
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/devfs_ruleset
@@ -0,0 +1 @@
+4
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/jail_zfs_dataset b/cdist/conf/type/__iocage_clone/parameter/default/jail_zfs_dataset
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/mount_linprocfs b/cdist/conf/type/__iocage_clone/parameter/default/mount_linprocfs
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/mount_linprocfs
@@ -0,0 +1 @@
+0
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/mount_procfs b/cdist/conf/type/__iocage_clone/parameter/default/mount_procfs
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/mount_procfs
@@ -0,0 +1 @@
+0
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/net b/cdist/conf/type/__iocage_clone/parameter/default/net
new file mode 100644
index 00000000..a45fd52c
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/net
@@ -0,0 +1 @@
+24
diff --git a/cdist/conf/type/__iocage_clone/parameter/default/state b/cdist/conf/type/__iocage_clone/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__iocage_clone/parameter/optional b/cdist/conf/type/__iocage_clone/parameter/optional
new file mode 100644
index 00000000..8ca73ed9
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/optional
@@ -0,0 +1,7 @@
+state
+bridge
+jail_zfs_dataset
+mount_procfs
+mount_linprocfs
+devfs_ruleset
+allow_socket_af
diff --git a/cdist/conf/type/__iocage_clone/parameter/optional_multiple b/cdist/conf/type/__iocage_clone/parameter/optional_multiple
new file mode 100644
index 00000000..fde64773
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/optional_multiple
@@ -0,0 +1 @@
+mount
diff --git a/cdist/conf/type/__iocage_clone/parameter/required b/cdist/conf/type/__iocage_clone/parameter/required
new file mode 100644
index 00000000..209d1544
--- /dev/null
+++ b/cdist/conf/type/__iocage_clone/parameter/required
@@ -0,0 +1,2 @@
+ip
+template
diff --git a/cdist/conf/type/__letsencrypt_acmetiny/gencode-remote b/cdist/conf/type/__letsencrypt_acmetiny/gencode-remote
new file mode 100644
index 00000000..9243acc9
--- /dev/null
+++ b/cdist/conf/type/__letsencrypt_acmetiny/gencode-remote
@@ -0,0 +1,112 @@
+#!/bin/sh -e
+
+ACME_TINY_CERT_REQUEST_DIR="/var/acme-tiny/cert-requests"
+ACME_TINY_ACCOUNT_KEY="/var/acme-tiny/account.key"
+ACME_CHALLENGE_DIR="/srv/www/sites/acme/public/.well-known/acme-challenge"
+
+REALM="${__object_id}"
+EXTRA_DOMAINS=""
+if [ -f "${__object}/parameter/extra-domain" ]; then
+ EXTRA_DOMAINS="$(cat "${__object}/parameter/extra-domain")"
+fi
+
+#TODO: support linux too
+REALMS_DIR="/usr/local/etc/pki/realms"
+REALM_DIR="${REALMS_DIR}/${REALM}"
+REALM_CERT="${REALM_DIR}/default.crt"
+REALM_KEY="${REALM_DIR}/default.key"
+REALM_CERT_REQUEST="${ACME_TINY_CERT_REQUEST_DIR}/${REALM}.csr"
+REALM_CERT_REQUEST_CNF="${ACME_TINY_CERT_REQUEST_DIR}/${REALM}.cnf"
+
+CSR_ALT_NAMES=""
+REALM_CERT_REQUEST_CNF_LINE=""
+if [ -n "${EXTRA_DOMAINS}" ]; then
+ CSR_ALT_NAMES="DNS:${REALM}"
+ for domain in ${EXTRA_DOMAINS}; do
+ CSR_ALT_NAMES="${CSR_ALT_NAMES},DNS:${domain}"
+ done
+ # CSR requests are executed always against .new, only after succeeding .new replaces the .cnf
+ REALM_CERT_REQUEST_CNF_LINE="-reqexts SAN -config '${REALM_CERT_REQUEST_CNF}.new'"
+fi
+
+cat << EOF
+if [ ! -d '${REALM_DIR}' ]; then
+ mkdir -p '${REALM_DIR}'
+fi
+if [ ! -f '${REALM_KEY}' ]; then
+ openssl genrsa 4096 > '${REALM_KEY}'
+fi
+
+if [ ! -d '${ACME_TINY_CERT_REQUEST_DIR}' ]; then
+ mkdir '${ACME_TINY_CERT_REQUEST_DIR}'
+fi
+
+FORCE_CSR_REGEN=""
+if [ -n '${CSR_ALT_NAMES}' ]; then
+ # Generate new config
+ cat /etc/ssl/openssl.cnf > '${REALM_CERT_REQUEST_CNF}.new'
+ printf '[SAN]\nsubjectAltName=${CSR_ALT_NAMES}' >> '${REALM_CERT_REQUEST_CNF}.new'
+ # Compare to previous config if necessary
+ if [ -f '${REALM_CERT_REQUEST_CNF}' ]; then
+ CNF_DIFF=\$(diff -q '${REALM_CERT_REQUEST_CNF}' '${REALM_CERT_REQUEST_CNF}.new' || true)
+ if [ -n "\${CNF_DIFF}" ]; then
+ # Options have changed
+ FORCE_CSR_REGEN="YES"
+ else
+ # Since they match, we won't be using this, clean it
+ rm '${REALM_CERT_REQUEST_CNF}.new'
+ fi
+ else
+ # We never used SAN here, CSR regen needed.
+ FORCE_CSR_REGEN="YES"
+ fi
+else
+ # We used SAN at some point, not any more
+ if [ -f '${REALM_CERT_REQUEST_CNF}' ]; then
+ rm '${REALM_CERT_REQUEST_CNF}'
+ FORCE_CSR_REGEN="YES"
+ fi
+fi
+
+# Create or re-create when params have changed
+if [ ! -f '${REALM_CERT_REQUEST}' -o -n "\${FORCE_CSR_REGEN}" ]; then
+ openssl req -new -sha256 -key '${REALM_KEY}' -subj '/CN=${REALM}' -out '${REALM_CERT_REQUEST}' ${REALM_CERT_REQUEST_CNF_LINE}
+fi
+
+# Check if cert exists, and if so whether or not it's older than a month
+if [ -f '${REALM_CERT}' ]; then
+ MODIFIED_IN_30d="\$(find '${REALM_CERT}' -mtime -30d)"
+ if [ -z "\${MODIFIED_IN_30d}" ]; then
+ # Cert is over a month old, it's fine to regenerate
+ FORCE_CRT_REGEN="YES"
+ fi
+else
+ # This cert doesn't exist
+ FORCE_CRT_REGEN="YES"
+fi
+
+
+# Only request certificate when needed
+# TODO: support linux too
+if [ -n "\${FORCE_CSR_REGEN}" -o -n "\${FORCE_CRT_REGEN}" ]; then
+ doas -u acme-tiny -- acme_tiny \
+ --account '${ACME_TINY_ACCOUNT_KEY}' \
+ --csr '${REALM_CERT_REQUEST}' \
+ --acme-dir '${ACME_CHALLENGE_DIR}' > '${REALM_CERT}.new'
+
+ if [ -s '${REALM_CERT}.new' ]; then
+ mv '${REALM_CERT}.new' '${REALM_CERT}'
+ else
+ echo "Failed to generate cert for realm '${REALM}'."
+ exit 1
+ fi
+fi
+
+cat "${REALM_CERT}" "${REALMS_DIR}/chain.pem" > ${REALM_DIR}/fullchain.pem
+
+if [ -n '${REALM_CERT_REQUEST_CNF_LINE}' -a -f '${REALM_CERT_REQUEST_CNF}.new' ]; then
+ # CSR and cert generation succeded with a new config, put new config in-place.
+ # This is the last thing we do, so we try again next time if sth fails.
+ mv '${REALM_CERT_REQUEST_CNF}.new' '${REALM_CERT_REQUEST_CNF}'
+fi
+EOF
diff --git a/cdist/conf/type/__letsencrypt_acmetiny/manifest b/cdist/conf/type/__letsencrypt_acmetiny/manifest
new file mode 100644
index 00000000..48438abb
--- /dev/null
+++ b/cdist/conf/type/__letsencrypt_acmetiny/manifest
@@ -0,0 +1 @@
+#__letsencrypt_acmetiny_base
diff --git a/cdist/conf/type/__letsencrypt_acmetiny/nonparallel b/cdist/conf/type/__letsencrypt_acmetiny/nonparallel
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__letsencrypt_acmetiny/parameter/optional_multiple b/cdist/conf/type/__letsencrypt_acmetiny/parameter/optional_multiple
new file mode 100644
index 00000000..7bfb11da
--- /dev/null
+++ b/cdist/conf/type/__letsencrypt_acmetiny/parameter/optional_multiple
@@ -0,0 +1 @@
+extra-domain
diff --git a/cdist/conf/type/__letsencrypt_acmetiny_base/gencode-remote b/cdist/conf/type/__letsencrypt_acmetiny_base/gencode-remote
new file mode 100644
index 00000000..1e4174a4
--- /dev/null
+++ b/cdist/conf/type/__letsencrypt_acmetiny_base/gencode-remote
@@ -0,0 +1,12 @@
+#!/bin/sh -e
+
+ACME_HOME="/var/acme-tiny"
+ACME_ACCOUNT_KEY="${ACME_HOME}/account.key"
+
+cat << EOF
+if [ ! -f '${ACME_ACCOUNT_KEY}' ]; then
+ openssl genrsa 4096 > '${ACME_ACCOUNT_KEY}'
+ chown acme-tiny:acme-tiny '${ACME_ACCOUNT_KEY}'
+ chmod 640 '${ACME_ACCOUNT_KEY}'
+fi
+EOF
diff --git a/cdist/conf/type/__letsencrypt_acmetiny_base/manifest b/cdist/conf/type/__letsencrypt_acmetiny_base/manifest
new file mode 100644
index 00000000..cbedcdff
--- /dev/null
+++ b/cdist/conf/type/__letsencrypt_acmetiny_base/manifest
@@ -0,0 +1,227 @@
+# Arguments
+ACME_DOMAIN="$(cat "${__object}/parameter/acme_domain" || true)"
+
+if [ -z "${ACME_DOMAIN}" ]; then
+ ACME_DOMAIN="${__target_host}"
+fi
+
+
+# Install needed stuffz
+
+## TODO: consider not depending on nginx? It is... practical though.
+## TODO: Maybe just move this out to a sepecial type?
+__package "nginx"
+
+NGINX_ETC="/usr/local/etc/nginx"
+
+# Setup the acme-challenge snippet
+require="__package/nginx" __directory "${NGINX_ETC}/snippets" --state present
+require="__directory${NGINX_ETC}/snippets" __file "${NGINX_ETC}/snippets/acme-challenge.conf" \
+ --mode 644 \
+ --source - << EOF
+# This file is managed remotely, all changes will be lost
+
+# This was heavily inspired by debops.org.
+
+# Automatic Certificate Management Environment (ACME) support.
+# https://tools.ietf.org/html/draft-ietf-acme-acme-01
+# https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment
+
+
+# Return the ACME challenge present in the server public root.
+# If not found, switch to global web server root.
+location ^~ /.well-known/acme-challenge/ {
+ default_type "text/plain";
+ try_files \$uri @well-known-acme-challenge;
+}
+
+# Return the ACME challenge present in the global server public root.
+# If not present, redirect request to a specified domain.
+location @well-known-acme-challenge {
+ root /srv/www/sites/acme/public;
+ default_type "text/plain";
+ try_files \$uri @redirect-acme-challenge;
+}
+
+# Redirect the ACME challenge to a different host. If a redirect loop is
+# detected, return 404.
+location @redirect-acme-challenge {
+ if (\$arg_redirect) {
+ return 404;
+ }
+ return 307 \$scheme://${ACME_DOMAIN}\$request_uri?redirect=yes;
+}
+
+# Return 404 if ACME challenge well known path is accessed directly.
+location = /.well-known/acme-challenge/ {
+ return 404;
+}
+EOF
+
+require="__package/nginx" __directory "${NGINX_ETC}/sites-enabled" --state present
+require="__directory${NGINX_ETC}/sites-enabled" __file "${NGINX_ETC}/nginx.conf" \
+ --mode 644 \
+ --source - << EOF
+# This file is managed remotely, all changes will be lost
+
+worker_processes 1;
+
+# This default error log path is compiled-in to make sure configuration parsing
+# errors are logged somewhere, especially during unattended boot when stderr
+# isn't normally logged anywhere. This path will be touched on every nginx
+# start regardless of error log location configured here. See
+# https://trac.nginx.org/nginx/ticket/147 for more info.
+#
+#error_log /var/log/nginx/error.log;
+#
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+
+ include mime.types;
+ default_type application/octet-stream;
+
+ server_tokens off;
+
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 5m;
+ sendfile on;
+ tcp_nopush on;
+ tcp_nodelay on;
+ types_hash_max_size 2048;
+ gzip on;
+ gzip_disable "msie6";
+ gzip_comp_level 5;
+ gzip_min_length 256;
+ gzip_proxied any;
+ gzip_vary on;
+ gzip_types
+ application/atom+xml
+ application/javascript
+ application/json
+ application/ld+json
+ application/manifest+json
+ application/rss+xml
+ application/vnd.geo+json
+ application/vnd.ms-fontobject
+ application/x-font-ttf
+ application/x-web-app-manifest+json
+ application/xhtml+xml
+ application/xml
+ font/opentype
+ image/bmp
+ image/svg+xml
+ image/x-icon
+ text/cache-manifest
+ text/css
+ text/plain
+ text/vcard
+ text/vnd.rim.location.xloc
+ text/vtt
+ text/x-component
+ text/x-cross-domain-policy;
+
+ # Logging
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log;
+
+ #add_header X-Clacks-Overhead "GNU Terry Pratchett";
+
+ # Virtual Hosts Configs
+ include ${NGINX_ETC}/sites-enabled/*.conf;
+}
+EOF
+
+require="__directory${NGINX_ETC}/sites-enabled" __file "${NGINX_ETC}/sites-enabled/welcome.conf" \
+ --mode 644 \
+ --source - << EOF
+# This file is managed remotely, all changes will be lost
+
+# nginx server configuration for:
+# - https://welcome/
+
+server {
+
+ listen [::]:80;
+
+ server_name welcome;
+
+ root /srv/www/sites/welcome/public;
+
+ include snippets/acme-challenge.conf;
+
+ location / {
+ return 301 https://\$host\$request_uri;
+ }
+}
+EOF
+
+## TODO: this is kinda bad, don't restart every time.
+## Otherwise this isn't idempotent.
+require="__package/nginx" __service nginx --action onerestart
+require="__package/nginx" __start_on_boot nginx
+
+
+__package "acme-tiny"
+
+# Create acme-tiny user and secure home dir
+ACME_TINY_HOME="/var/acme-tiny"
+require="__package/acme-tiny" __user acme-tiny --system --home ${ACME_TINY_HOME} --comment "acme-tiny client"
+require="__user/acme-tiny" __directory "${ACME_TINY_HOME}" --state present --mode 0750 --owner acme-tiny --group acme-tiny
+
+# Create ACME challenge dirs to be served by nginx
+ACME_PUBLIC_DIR="/srv/www/sites/acme/public"
+ACME_WELLKNOWN_DIR="${ACME_PUBLIC_DIR}/.well-known"
+ACME_CHALLENGE_DIR="${ACME_WELLKNOWN_DIR}/acme-challenge"
+__directory "${ACME_PUBLIC_DIR}" \
+ --parents \
+ --state present \
+ --owner acme-tiny --group www \
+ --mode 2750 # TODO: check whether this does require gid?
+require="__directory${ACME_PUBLIC_DIR}" __directory "${ACME_WELLKNOWN_DIR}" \
+ --state present \
+ --owner acme-tiny --group www \
+ --mode 0750
+require="__directory${ACME_WELLKNOWN_DIR}" __directory "${ACME_CHALLENGE_DIR}" \
+ --state present \
+ --owner acme-tiny --group www \
+ --mode 0750
+
+__package doas
+DOAS_CONF="/usr/local/etc/doas.conf"
+require="__package/doas" __file "${DOAS_CONF}" --mode 0640
+require="__file${DOAS_CONF}" __line "${DOAS_CONF}" \
+ --regex 'root as acme-tiny' \
+ --line 'permit nopass root as acme-tiny'
+
+# Setup CA
+REALMS_DIR="/usr/local/etc/pki/realms"
+__directory "${REALMS_DIR}" \
+ --parents \
+ --state present \
+ --mode 0755
+
+require="__directory${REALMS_DIR}" __file ${REALMS_DIR}/intermediate.pem \
+ --mode 0644 \
+ --source - << EOF
+$(curl -s https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt)
+EOF
+require="__directory${REALMS_DIR}" __file ${REALMS_DIR}/root.pem \
+ --mode 0644 \
+ --source - << EOF
+$(curl -s https://letsencrypt.org/certs/trustid-x3-root.pem.txt)
+EOF
+require="__directory${REALMS_DIR}" __file ${REALMS_DIR}/chain.pem \
+ --mode 0644 \
+ --source - << EOF
+$(curl -s https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt)
+$(curl -s https://letsencrypt.org/certs/trustid-x3-root.pem.txt)
+EOF
+
diff --git a/cdist/conf/type/__letsencrypt_acmetiny_base/parameter/optional b/cdist/conf/type/__letsencrypt_acmetiny_base/parameter/optional
new file mode 100644
index 00000000..fb20814d
--- /dev/null
+++ b/cdist/conf/type/__letsencrypt_acmetiny_base/parameter/optional
@@ -0,0 +1 @@
+acme_domain
diff --git a/cdist/conf/type/__letsencrypt_acmetiny_base/singleton b/cdist/conf/type/__letsencrypt_acmetiny_base/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__letsencrypt_cert/man.rst b/cdist/conf/type/__letsencrypt_cert/man.rst
index c4ffc6bc..85eb88ea 100644
--- a/cdist/conf/type/__letsencrypt_cert/man.rst
+++ b/cdist/conf/type/__letsencrypt_cert/man.rst
@@ -59,13 +59,13 @@ MESSAGES
--------
change
- Certificte was changed.
+ Certificate was changed.
create
- Certificte was created.
+ Certificate was created.
remove
- Certificte was removed.
+ Certificate was removed.
EXAMPLES
--------
diff --git a/cdist/conf/type/__letsencrypt_cert/manifest b/cdist/conf/type/__letsencrypt_cert/manifest
index d6892c9b..68ecf9d4 100755
--- a/cdist/conf/type/__letsencrypt_cert/manifest
+++ b/cdist/conf/type/__letsencrypt_cert/manifest
@@ -7,6 +7,12 @@ if [ -z "${certbot_fullpath}" ]; then
os_version="$(cat "${__global}/explorer/os_version")"
case "$os" in
+ archlinux)
+ __package certbot
+ ;;
+ alpine)
+ __package certbot
+ ;;
debian)
case "$os_version" in
8*)
@@ -33,6 +39,10 @@ if [ -z "${certbot_fullpath}" ]; then
require="__apt_source/stretch-backports" __package_apt certbot \
--target-release stretch-backports
;;
+ 10*)
+ __package_apt certbot
+ ;;
+
*)
echo "Unsupported OS version: $os_version" >&2
exit 1
@@ -62,11 +72,12 @@ if [ -z "${certbot_fullpath}" ]; then
--distribution ascii-backports \
--component main
- require="__apt_source/ascii-backports" __package_apt python-certbot \
- --target-release ascii-backports
require="__apt_source/ascii-backports" __package_apt certbot \
--target-release ascii-backports
;;
+ beowulf*)
+ __package_apt certbot
+ ;;
*)
echo "Unsupported OS version: $os_version" >&2
exit 1
diff --git a/cdist/conf/type/__line/explorer/state b/cdist/conf/type/__line/explorer/state
index 2ef252c8..e8fc3630 100755
--- a/cdist/conf/type/__line/explorer/state
+++ b/cdist/conf/type/__line/explorer/state
@@ -1,6 +1,7 @@
#!/bin/sh -e
#
# 2018 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -18,6 +19,14 @@
# along with cdist. If not, see .
#
+if [ -f "$__object/parameter/file" ]; then
+ file=$(cat "$__object/parameter/file")
+else
+ file="/$__object_id"
+fi
+
+[ -f "$file" ] || exit 0
+
if [ -f "$__object/parameter/before" ]; then
position="before"
elif [ -f "$__object/parameter/after" ]; then
@@ -33,63 +42,56 @@ else
needle="line"
fi
-if [ -f "$__object/parameter/file" ]; then
- file="$(cat "$__object/parameter/file")"
-else
- file="/$__object_id"
-fi
-
-if [ ! -f "$file" ]; then
- echo "file_missing"
- exit 0
-fi
-
awk -v position="$position" -v needle="$needle" '
function _find(_text, _pattern) {
if (needle == "regex") {
return match(_text, _pattern)
} else {
- return index(_text, _pattern)
+ return index(_text, _pattern) == 1
}
}
BEGIN {
getline anchor < (ENVIRON["__object"] "/parameter/" position)
getline pattern < (ENVIRON["__object"] "/parameter/" needle)
- state = "absent"
+
+ found_line = 0
+ correct_pos = (position != "after" && position != "before")
}
{
if (position == "after") {
if (match($0, anchor)) {
getline
if (_find($0, pattern)) {
- state = "present"
+ found_line++
+ correct_pos = 1
+ exit 0
}
- else {
- state = "wrongposition"
- }
- exit 0
+ } else if (_find($0, pattern)) {
+ found_line++
}
- }
- else if (position == "before") {
+ } else if (position == "before") {
if (_find($0, pattern)) {
+ found_line++
getline
if (match($0, anchor)) {
- state = "present"
+ correct_pos = 1
+ exit 0
}
- else {
- state = "wrongposition"
- }
- exit 0
}
- }
- else {
+ } else {
if (_find($0, pattern)) {
- state = "present"
+ found_line++
exit 0
}
}
}
END {
- print state
+ if (found_line && correct_pos) {
+ print "present"
+ } else if (found_line) {
+ print "wrongposition"
+ } else {
+ print "absent"
+ }
}
' "$file"
diff --git a/cdist/conf/type/__line/gencode-remote b/cdist/conf/type/__line/gencode-remote
index 03e90c1b..88cae68b 100755
--- a/cdist/conf/type/__line/gencode-remote
+++ b/cdist/conf/type/__line/gencode-remote
@@ -1,6 +1,7 @@
#!/bin/sh -e
#
# 2018 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -23,9 +24,20 @@ if [ -f "$__object/parameter/before" ] && [ -f "$__object/parameter/after" ]; th
exit 1
fi
+if [ -f "$__object/parameter/file" ]; then
+ file="$(cat "$__object/parameter/file")"
+else
+ file="/$__object_id"
+fi
+
state_should="$(cat "$__object/parameter/state")"
state_is="$(cat "$__object/explorer/state")"
+if [ -z "$state_is" ]; then
+ printf 'The file "%s" is missing. Please create it before using %s on it.\n' "$file" "${__type##*/}" >&2
+ exit 1
+fi
+
if [ "$state_should" = "$state_is" ]; then
# nothing to do
exit 0
@@ -46,12 +58,6 @@ else
needle="line"
fi
-if [ -f "$__object/parameter/file" ]; then
- file="$(cat "$__object/parameter/file")"
-else
- file="/$__object_id"
-fi
-
add=0
remove=0
case "$state_should" in
@@ -104,10 +110,12 @@ BEGIN {
if (anchor && match(\$0, anchor)) {
if (position == "before") {
print line
+ add = 0
print
} else if (position == "after") {
print
print line
+ add = 0
}
next
}
@@ -115,7 +123,7 @@ BEGIN {
print
}
END {
- if (add && position == "end") {
+ if (add) {
print line
}
}
diff --git a/cdist/conf/type/__locale/gencode-remote b/cdist/conf/type/__locale/gencode-remote
index 04e48712..1feb9884 100755
--- a/cdist/conf/type/__locale/gencode-remote
+++ b/cdist/conf/type/__locale/gencode-remote
@@ -1,6 +1,6 @@
#!/bin/sh -e
#
-# 2013 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013-2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -37,6 +37,15 @@ locale_remove=$(echo "$locale" | sed 's/UTF-8/utf8/')
state=$(cat "$__object/parameter/state")
+os=$(cat "$__global/explorer/os")
+
+# Nothing to be done on alpine
+case "$os" in
+ alpine)
+ exit 0
+ ;;
+esac
+
case "$state" in
present)
echo localedef -A "$alias" -f "$charmap" -i "$input" "$locale"
diff --git a/cdist/conf/type/__locale/man.rst b/cdist/conf/type/__locale/man.rst
index 60a4eacc..e36ab061 100644
--- a/cdist/conf/type/__locale/man.rst
+++ b/cdist/conf/type/__locale/man.rst
@@ -8,7 +8,8 @@ cdist-type__locale - Configure locales
DESCRIPTION
-----------
-This cdist type allows you to setup locales.
+This cdist type allows you to setup locales. On systems that don't
+support locale setting like alpine/musl libc, it is a no-op.
OPTIONAL PARAMETERS
@@ -44,6 +45,6 @@ Nico Schottelius
COPYING
-------
-Copyright \(C) 2013-2016 Nico Schottelius. Free use of this software is
+Copyright \(C) 2013-2019 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 or
later (GPLv3+).
diff --git a/cdist/conf/type/__locale/manifest b/cdist/conf/type/__locale/manifest
index cacd0b42..9f1e17ac 100755
--- a/cdist/conf/type/__locale/manifest
+++ b/cdist/conf/type/__locale/manifest
@@ -1,6 +1,6 @@
#!/bin/sh -e
#
-# 2013-2015 Nico Schottelius (nico-cdist at schottelius.org)
+# 2013-2019 Nico Schottelius (nico-cdist at schottelius.org)
# 2015 David Hürlimann (david at ungleich.ch)
#
# This file is part of cdist.
@@ -19,7 +19,7 @@
# along with cdist. If not, see .
#
#
-# Install required packages
+# Install required packages
#
os=$(cat "$__global/explorer/os")
@@ -30,7 +30,7 @@ case "$os" in
# Debian needs a seperate package
__package locales --state present
;;
- archlinux|suse|ubuntu|scientific|centos)
+ archlinux|suse|ubuntu|scientific|centos|alpine)
:
;;
*)
diff --git a/cdist/conf/type/__motd/gencode-remote b/cdist/conf/type/__motd/gencode-remote
index bc842cc8..738ea834 100755
--- a/cdist/conf/type/__motd/gencode-remote
+++ b/cdist/conf/type/__motd/gencode-remote
@@ -29,7 +29,18 @@ case "$os" in
echo "uname -snrvm > /var/run/motd"
echo "cat /etc/motd.tail >> /var/run/motd"
;;
+ freebsd)
+ # FreeBSD only updates /etc/motd on boot,
+ # as seen in /etc/rc.d/motd
+ echo "uname -sri > /etc/motd"
+ echo "cat /etc/motd.template >> /etc/motd"
+ # FreeBSD 13 starts treating motd slightly different from previous
+ # versions this ensures hosts have the expected config.
+ echo "rm /etc/motd.template || true"
+ echo "service motd start"
+ ;;
*)
+ # Other OS tend to treat /etc/motd statically
exit 0
;;
esac
diff --git a/cdist/conf/type/__motd/man.rst b/cdist/conf/type/__motd/man.rst
index 17369684..a567dc80 100644
--- a/cdist/conf/type/__motd/man.rst
+++ b/cdist/conf/type/__motd/man.rst
@@ -10,6 +10,13 @@ DESCRIPTION
-----------
This cdist type allows you to easily setup /etc/motd.
+.. note::
+ In some OS, motd is a bit special, check `motd(5)`.
+ Currently Debian, Devuan, Ubuntu and FreeBSD are taken into account.
+ If your OS of choice does something besides /etc/motd, check the source
+ and contribute support for it.
+ Otherwise it will likely just work.
+
REQUIRED PARAMETERS
-------------------
@@ -20,6 +27,7 @@ OPTIONAL PARAMETERS
-------------------
source
If supplied, copy this file from the host running cdist to the target.
+ If source is '-' (dash), take what was written to stdin as the file content.
If not supplied, a default message will be placed onto the target.
@@ -34,6 +42,15 @@ EXAMPLES
# Supply source file from a different type
__motd --source "$__type/files/my-motd"
+ # Supply source from stdin
+ __motd --source "-" <
COPYING
-------
-Copyright \(C) 2011 Nico Schottelius. You can redistribute it
+Copyright \(C) 2020 Nico Schottelius. 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.
diff --git a/cdist/conf/type/__motd/manifest b/cdist/conf/type/__motd/manifest
index cd741cf4..ded734d7 100755
--- a/cdist/conf/type/__motd/manifest
+++ b/cdist/conf/type/__motd/manifest
@@ -34,9 +34,17 @@ os=$(cat "$__global/explorer/os")
case "$os" in
debian|ubuntu|devuan)
+ # Debian-based systems use /etc/motd.tail as a template
destination=/etc/motd.tail
;;
+ freebsd)
+ # FreeBSD uses motd.template to prepend system information on boot
+ # (this actually only applies starting with version 13,
+ # but we fix that for whatever version in gencode-remote)
+ destination=/etc/motd.template
+ ;;
*)
+ # Most UNIX systems, including other Linux and OpenBSD just use /etc/motd
destination=/etc/motd
;;
esac
diff --git a/cdist/conf/type/__mysql_database/explorer/state b/cdist/conf/type/__mysql_database/explorer/state
new file mode 100755
index 00000000..79858695
--- /dev/null
+++ b/cdist/conf/type/__mysql_database/explorer/state
@@ -0,0 +1,33 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
+fi
+
+if [ -n "$( mysql -B -N -e "show databases like '$name'" )" ]
+then
+ echo 'present'
+else
+ echo 'absent'
+fi
diff --git a/cdist/conf/type/__mysql_database/gencode-remote b/cdist/conf/type/__mysql_database/gencode-remote
index 23e51b05..1bdb2b11 100755
--- a/cdist/conf/type/__mysql_database/gencode-remote
+++ b/cdist/conf/type/__mysql_database/gencode-remote
@@ -1,6 +1,6 @@
#!/bin/sh -e
#
-# 2012 Benedikt Koeppel (code@benediktkoeppel.ch)
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
#
# This file is part of cdist.
#
@@ -17,38 +17,30 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see .
#
-#
-# if --database was specified
-if [ -f "$__object/parameter/name" ]; then
- database="$(cat "$__object/parameter/name")"
-else # otherwise use the object id as database name
- database="$__object_id"
+state_is="$( cat "$__object/explorer/state" )"
+
+state_should="$( cat "$__object/parameter/state" )"
+
+if [ "$state_is" = "$state_should" ]
+then
+ exit 0
fi
-cat <<-EOFF
-mysql -u root <<-EOF
- CREATE DATABASE IF NOT EXISTS $database
-EOF
-EOFF
-
-# if --user was specified
-if [ -f "$__object/parameter/user" ]; then
- user="$(cat "$__object/parameter/user")"
-
- # if --password was specified
- if [ -f "$__object/parameter/password" ]; then
- password="$(cat "$__object/parameter/password")"
- cat <<-EOFF
- mysql -u root <<-EOF
- GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost' IDENTIFIED BY '$password';
-EOF
-EOFF
- else
- cat <<-EOFF
- mysql -u root <<-EOF
- GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost';
-EOF
-EOFF
- fi
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
fi
+
+case "$state_should" in
+ present)
+ echo "mysql -e 'create database \`$name\`'"
+ echo "create database $name" >> "$__messages_out"
+ ;;
+ absent)
+ echo "mysql -e 'drop database \`$name\`'"
+ echo "drop database $name" >> "$__messages_out"
+ ;;
+esac
diff --git a/cdist/conf/type/__mysql_database/man.rst b/cdist/conf/type/__mysql_database/man.rst
index 1e245a08..b3b56b5f 100644
--- a/cdist/conf/type/__mysql_database/man.rst
+++ b/cdist/conf/type/__mysql_database/man.rst
@@ -8,24 +8,24 @@ cdist-type__mysql_database - Manage a MySQL database
DESCRIPTION
-----------
-This cdist type allows you to install a MySQL database.
+Create MySQL database and optionally user with all privileges.
-REQUIRED PARAMETERS
--------------------
-None.
OPTIONAL PARAMETERS
-------------------
name
- The name of the database to install
- defaults to the object id
+ Name of database. Defaults to object id.
user
- A user that should have access to the database
+ Create user and give all privileges to database.
password
- The password for the user who manages the database
+ Password for user.
+
+state
+ Defaults to present.
+ If absent and user is also set, both will be removed (with privileges).
EXAMPLES
@@ -33,17 +33,23 @@ EXAMPLES
.. code-block:: sh
- __mysql_database "cdist" --name "cdist" --user "myuser" --password "mypwd"
+ # just create database
+ __mysql_database foo
+
+ # create database with respective user with all privileges to database
+ __mysql_database bar \
+ --user name \
+ --password secret
AUTHORS
-------
-Benedikt Koeppel
+Ander Punnar
COPYING
-------
-Copyright \(C) 2012 Benedikt Koeppel. 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.
+Copyright \(C) 2020 Ander Punnar. 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.
diff --git a/cdist/conf/type/__mysql_database/manifest b/cdist/conf/type/__mysql_database/manifest
new file mode 100755
index 00000000..a3c9ed5d
--- /dev/null
+++ b/cdist/conf/type/__mysql_database/manifest
@@ -0,0 +1,52 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+if [ -f "$__object/parameter/user" ]
+then
+ user="$( cat "$__object/parameter/user" )"
+fi
+
+if [ -f "$__object/parameter/password" ]
+then
+ password="$( cat "$__object/parameter/password" )"
+fi
+
+if [ -n "$user" ] && [ -n "$password" ]
+then
+ if [ -f "$__object/parameter/name" ]
+ then
+ database="$( cat "$__object/parameter/name" )"
+ else
+ database="$__object_id"
+ fi
+
+ state_should="$( cat "$__object/parameter/state" )"
+
+ __mysql_user "$user" \
+ --password "$password" \
+ --state "$state_should"
+
+ # removing user should remove all user's privileges
+ require="__mysql_user/$user" \
+ __mysql_privileges "$database/$user" \
+ --database "$database" \
+ --user "$user" \
+ --state "$state_should"
+fi
diff --git a/cdist/conf/type/__mysql_database/parameter/default/state b/cdist/conf/type/__mysql_database/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__mysql_database/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__mysql_database/parameter/optional b/cdist/conf/type/__mysql_database/parameter/optional
index 756afee7..6c0b1e85 100644
--- a/cdist/conf/type/__mysql_database/parameter/optional
+++ b/cdist/conf/type/__mysql_database/parameter/optional
@@ -1,3 +1,4 @@
name
user
password
+state
diff --git a/cdist/conf/type/__mysql_privileges/explorer/state b/cdist/conf/type/__mysql_privileges/explorer/state
new file mode 100755
index 00000000..4f13a70c
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/explorer/state
@@ -0,0 +1,40 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+privileges="$( cat "$__object/parameter/privileges" )"
+
+database="$( cat "$__object/parameter/database" )"
+
+table="$( cat "$__object/parameter/table" )"
+
+user="$( cat "$__object/parameter/user" )"
+
+host="$( cat "$__object/parameter/host" )"
+
+check_privileges="$(
+ mysql -B -N -e "show grants for '$user'@'$host'" \
+ | grep -Ei "^grant $privileges on .$database.\..?$table.? to " || true )"
+
+if [ -n "$check_privileges" ]
+then
+ echo 'present'
+else
+ echo 'absent'
+fi
diff --git a/cdist/conf/type/__mysql_privileges/gencode-remote b/cdist/conf/type/__mysql_privileges/gencode-remote
new file mode 100755
index 00000000..0656699f
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/gencode-remote
@@ -0,0 +1,55 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+state_is="$( cat "$__object/explorer/state" )"
+
+state_should="$( cat "$__object/parameter/state" )"
+
+if [ "$state_is" = "$state_should" ]
+then
+ exit 0
+fi
+
+privileges="$( cat "$__object/parameter/privileges" )"
+
+database="$( cat "$__object/parameter/database" )"
+
+table="$( cat "$__object/parameter/table" )"
+
+user="$( cat "$__object/parameter/user" )"
+
+host="$( cat "$__object/parameter/host" )"
+
+if [ "$table" != '*' ]
+then
+ # shellcheck disable=SC2016
+ table="$( printf '`%s`' "$table" )"
+fi
+
+case "$state_should" in
+ present)
+ echo "mysql -e 'grant $privileges on \`$database\`.$table to \`$user\`@\`$host\`'"
+ echo "grant $privileges on $database.$table to $user@$host" >> "$__messages_out"
+ ;;
+ absent)
+ echo "mysql -e 'revoke $privileges on \`$database\`.$table from \`$user\`@\`$host\`'"
+ echo "revoke $privileges on $database.$table from $user@$host" >> "$__messages_out"
+ ;;
+esac
diff --git a/cdist/conf/type/__mysql_privileges/man.rst b/cdist/conf/type/__mysql_privileges/man.rst
new file mode 100644
index 00000000..b72c9eba
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/man.rst
@@ -0,0 +1,57 @@
+cdist-type__mysql_privileges(7)
+===============================
+
+NAME
+----
+cdist-type__mysql_privileges - Manage MySQL privileges
+
+
+DESCRIPTION
+-----------
+
+Grant and revoke privileges of MySQL user.
+
+
+REQUIRED PARAMETERS
+-------------------
+database
+ Name of database.
+
+user
+ Name of user.
+
+
+OPTIONAL PARAMETERS
+-------------------
+privileges
+ Defaults to "all".
+
+table
+ Defaults to "*".
+
+host
+ Defaults to localhost.
+
+state
+ "present" grants and "absent" revokes. Defaults to present.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ __mysql_privileges user-to-db --database db --user user
+
+
+AUTHORS
+-------
+Ander Punnar
+
+
+COPYING
+-------
+Copyright \(C) 2020 Ander Punnar. 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.
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/host b/cdist/conf/type/__mysql_privileges/parameter/default/host
new file mode 100644
index 00000000..2fbb50c4
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/host
@@ -0,0 +1 @@
+localhost
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/privileges b/cdist/conf/type/__mysql_privileges/parameter/default/privileges
new file mode 100644
index 00000000..5472efad
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/privileges
@@ -0,0 +1 @@
+all privileges
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/state b/cdist/conf/type/__mysql_privileges/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/table b/cdist/conf/type/__mysql_privileges/parameter/default/table
new file mode 100644
index 00000000..72e8ffc0
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/default/table
@@ -0,0 +1 @@
+*
diff --git a/cdist/conf/type/__mysql_privileges/parameter/optional b/cdist/conf/type/__mysql_privileges/parameter/optional
new file mode 100644
index 00000000..d4ed5bc5
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/optional
@@ -0,0 +1,4 @@
+privileges
+table
+host
+state
diff --git a/cdist/conf/type/__mysql_privileges/parameter/required b/cdist/conf/type/__mysql_privileges/parameter/required
new file mode 100644
index 00000000..152b4a1e
--- /dev/null
+++ b/cdist/conf/type/__mysql_privileges/parameter/required
@@ -0,0 +1,2 @@
+database
+user
diff --git a/cdist/conf/type/__mysql_user/explorer/state b/cdist/conf/type/__mysql_user/explorer/state
new file mode 100755
index 00000000..6817ee9d
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/explorer/state
@@ -0,0 +1,54 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
+fi
+
+if [ -f "$__object/parameter/password" ]
+then
+ password="$( cat "$__object/parameter/password" )"
+else
+ password=''
+fi
+
+host="$( cat "$__object/parameter/host" )"
+
+check_user="$( mysql -B -N -e "select user from mysql.user where user = '$name' and host = '$host'" )"
+
+if [ -n "$check_user" ]
+then
+ if [ -n "$password" ]
+ then
+ check_password="$( mysql -B -N -e "select user from mysql.user where user = '$name' and host = '$host' and password = password( '$password' )" )"
+ fi
+
+ if [ -n "$password" ] && [ -z "$check_password" ]
+ then
+ echo 'change-password'
+ else
+ echo 'present'
+ fi
+else
+ echo 'absent'
+fi
diff --git a/cdist/conf/type/__mysql_user/gencode-remote b/cdist/conf/type/__mysql_user/gencode-remote
new file mode 100755
index 00000000..5f13bc87
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/gencode-remote
@@ -0,0 +1,68 @@
+#!/bin/sh -e
+#
+# 2020 Ander Punnar (ander-at-kvlt-dot-ee)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+state_is="$( cat "$__object/explorer/state" )"
+
+state_should="$( cat "$__object/parameter/state" )"
+
+if [ "$state_is" = "$state_should" ]
+then
+ exit 0
+fi
+
+if [ -f "$__object/parameter/name" ]
+then
+ name="$( cat "$__object/parameter/name" )"
+else
+ name="$__object_id"
+fi
+
+host="$( cat "$__object/parameter/host" )"
+
+if [ -f "$__object/parameter/password" ]
+then
+ password="$( cat "$__object/parameter/password" )"
+else
+ if [ "$state_should" = 'present' ]
+ then
+ echo '--password needed' >&2
+ exit 1
+ else
+ password=''
+ fi
+fi
+
+if [ "$state_is" = 'absent' ] && [ "$state_should" = 'present' ]
+then
+ echo "mysql -e 'create user \`$name\`@\`$host\` identified by \"$password\"'"
+ echo "create user $name@$host" >> "$__messages_out"
+
+elif [ "$state_is" != 'absent' ] && [ "$state_should" = 'absent' ]
+then
+ echo "mysql -e 'drop user \`$name\`@\`$host\`'"
+ echo "drop user $name@$host" >> "$__messages_out"
+
+elif [ "$state_is" = 'change-password' ]
+then
+ # this only works with MySQL 5.7.6 and later or MariaDB 10.1.20 and later
+ echo "mysql -e 'alter user \`$name\`@\`$host\` identified by \"$password\"'"
+ echo "mysql -e 'flush privileges'"
+ echo "change password $name@$host" >> "$__messages_out"
+fi
diff --git a/cdist/conf/type/__mysql_user/man.rst b/cdist/conf/type/__mysql_user/man.rst
new file mode 100644
index 00000000..c2b222d5
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/man.rst
@@ -0,0 +1,48 @@
+cdist-type__mysql_user(7)
+=========================
+
+NAME
+----
+cdist-type__mysql_user - Manage a MySQL user
+
+
+DESCRIPTION
+-----------
+
+Create MySQL user or change password for the user.
+
+
+OPTIONAL PARAMETERS
+-------------------
+name
+ Name of user. Defaults to object id.
+
+host
+ Host of user. Defaults to localhost.
+
+password
+ Password of user.
+
+state
+ Defaults to present.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ __mysql_user user --password secret
+
+
+AUTHORS
+-------
+Ander Punnar
+
+
+COPYING
+-------
+Copyright \(C) 2020 Ander Punnar. 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.
diff --git a/cdist/conf/type/__mysql_user/parameter/default/host b/cdist/conf/type/__mysql_user/parameter/default/host
new file mode 100644
index 00000000..2fbb50c4
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/parameter/default/host
@@ -0,0 +1 @@
+localhost
diff --git a/cdist/conf/type/__mysql_user/parameter/default/state b/cdist/conf/type/__mysql_user/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__mysql_user/parameter/optional b/cdist/conf/type/__mysql_user/parameter/optional
new file mode 100644
index 00000000..a286266c
--- /dev/null
+++ b/cdist/conf/type/__mysql_user/parameter/optional
@@ -0,0 +1,4 @@
+name
+host
+password
+state
diff --git a/cdist/conf/type/__openldap_server/gencode-remote b/cdist/conf/type/__openldap_server/gencode-remote
new file mode 100644
index 00000000..b1e98f8c
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/gencode-remote
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+manager_dn=$(cat "${__object}/parameter/manager-dn")
+manager_password=$(cat "${__object}/parameter/manager-password")
+description=$(cat "${__object}/parameter/description")
+suffix=$(cat "${__object}/parameter/suffix")
+suffix_dc=$(printf "%s" "${suffix}" | awk -F',' '{print $1}' | awk -F'=' '{print $2}')
+
+SLAPD_IPC=$(tr '\n' ' ' < "${__object}/parameter/slapd-url" | awk '{ print $1}')
+
+cat <&1 > /dev/null; then
+ # Already exists, use ldapmodify
+ ldapmodify -xZ -D "${manager_dn}" -w "${manager_password}" -H '${SLAPD_IPC}' <
+Evilham
+
+
+COPYING
+-------
+Copyright \(C) 2020 ungleich glarus ag. 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.
diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest
new file mode 100644
index 00000000..84ba176f
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/manifest
@@ -0,0 +1,267 @@
+#!/bin/sh
+
+name="${__target_host}"
+manager_dn=$(cat "${__object}/parameter/manager-dn")
+manager_password_hash=$(cat "${__object}/parameter/manager-password-hash")
+serverid=$(cat "${__object}/parameter/serverid")
+suffix=$(cat "${__object}/parameter/suffix")
+slapd_modules=$(cat "${__object}/parameter/module" 2>/dev/null || true)
+schemas=$(cat "${__object}/parameter/schema")
+slapd_urls=$(tr '\n' ' ' < "${__object}/parameter/slapd-url")
+tls_cipher_suite=$(cat "${__object}/parameter/tls-cipher-suite" 2>/dev/null || true)
+extra_config=$(cat "${__object}/parameter/extra-config" || true)
+
+
+os="$(cat "${__global}/explorer/os")"
+
+# Setup OS-dependent vars
+CONF_OWNER="root"
+CONF_GROUP="root"
+case "${os}" in
+ freebsd)
+ PKGS="openldap-server"
+ ETC="/usr/local/etc"
+ SLAPD_DIR="/usr/local/etc/openldap"
+ SLAPD_DATA_DIR="/var/db/openldap-data"
+ SLAPD_RUN_DIR="/var/run/openldap"
+ SLAPD_MODULE_PATH="/usr/local/libexec/openldap"
+ if [ -z "${slapd_modules}" ]; then
+ # It looks like ppolicy and syncprov must be compiled
+ slapd_modules="back_mdb back_monitor"
+ fi
+ CONF_OWNER="ldap"
+ CONF_GROUP="ldap"
+ if [ -z "${tls_cipher_suite}" ]; then
+ # TODO: research default for FreeBSD. 'NORMAL' appears to not work
+ tls_cipher_suite="HIGH:MEDIUM:+SSLv2"
+ fi
+ ;;
+ debian|ubuntu|devuan)
+ PKGS="slapd ldap-utils"
+ ETC="/etc"
+ SLAPD_DIR="/etc/ldap"
+ SLAPD_DATA_DIR="/var/lib/ldap"
+ SLAPD_RUN_DIR="/var/run/slapd"
+ SLAPD_MODULE_PATH="/usr/lib/ldap"
+ if [ -z "${slapd_modules}" ]; then
+ slapd_modules="back_mdb ppolicy syncprov back_monitor"
+ fi
+ if [ -z "${tls_cipher_suite}" ]; then
+ tls_cipher_suite="NORMAL"
+ fi
+ ;;
+ *)
+ echo "Don't know the openldap defaults for: $os" >&2
+ exit 1
+ ;;
+esac
+
+PKG_MAIN=$(echo "${PKGS}" | awk '{print $1;}')
+
+
+# Determine if __letsencrypt_cert is to be used and setup vars accordingly
+if [ -f "${__object}/parameter/tls-cert" ]; then
+ tls_cert=$(cat "${__object}/parameter/tls-cert")
+
+ if [ ! -f "${__object}/parameter/tls-privkey" ]; then
+ echo "When tls-cert is defined, tls-privkey is also required." >&2
+ exit 1
+ fi
+ tls_privkey=$(cat "${__object}/parameter/tls-privkey")
+
+ if [ ! -f "${__object}/parameter/tls-ca" ]; then
+ echo "When tls-cert is defined, tls-ca is also required." >&2
+ exit 1
+ fi
+ tls_ca=$(cat "${__object}/parameter/tls-ca")
+
+ _skip_letsencrypt_cert="YES"
+else
+ if [ ! -f "${__object}/parameter/admin-email" ]; then
+ echo "When using __letsencrypt_cert, admin-email is also required." >&2
+ exit 1
+ fi
+ admin_email=$(cat "${__object}/parameter/admin-email")
+
+ tls_cert="${SLAPD_DIR}/sasl2/cert.pem"
+ tls_privkey="${SLAPD_DIR}/sasl2/privkey.pem"
+ tls_ca="${SLAPD_DIR}/sasl2/chain.pem"
+fi
+
+mkdir "${__object}/files"
+ldapconf="${__object}/files/ldapconf"
+
+replication=""
+if [ -f "${__object}/parameter/replicate" ]; then
+ replication=yes
+
+ if [ ! -f "${__object}/parameter/syncrepl-searchbase" ]; then
+ echo "Requiring the searchbase for replication" >&2
+ exit 1
+ fi
+ syncrepl_searchbase=$(cat "${__object}/parameter/syncrepl-searchbase")
+
+ if [ ! -f "${__object}/parameter/syncrepl-credentials" ]; then
+ echo "Requiring credentials for replication" >&2
+ exit 1
+ fi
+
+ syncrepl_credentials=$(cat "${__object}/parameter/syncrepl-credentials")
+
+ if [ ! -f "${__object}/parameter/syncrepl-host" ]; then
+ echo "Requiring host(s) for replication" >&2
+ exit 1
+ fi
+ syncrepl_hosts=$(cat "${__object}/parameter/syncrepl-host")
+
+fi
+
+# Install required packages
+for pkg in ${PKGS}; do
+ __package "${pkg}"
+done
+
+
+require="__package/${PKG_MAIN}" __start_on_boot slapd
+
+# Setup -h flag for the listeners. See man slapd (-h flag).
+case "${os}" in
+ freebsd)
+ require="__start_on_boot/slapd" __key_value \
+ --file "/etc/rc.conf" \
+ --key "slapd_flags" \
+ --value "\"-h '${slapd_urls}'\"" \
+ --delimiter "=" \
+ --comment "# LDAP Listener URLs" \
+ "${__target_host}__slapd_flags"
+ ;;
+ debian|ubuntu|devuan)
+ require="__package/${PKG_MAIN}" __line rm_slapd_conf \
+ --file ${ETC}/default/slapd \
+ --regex 'SLAPD_CONF=.*' \
+ --state absent
+
+ require="__package/${PKG_MAIN}" __line rm_slapd_services \
+ --file ${ETC}/default/slapd \
+ --regex 'SLAPD_SERVICES=.*' \
+ --state absent
+
+ require="__line/rm_slapd_conf" __line add_slapd_conf \
+ --file ${ETC}/default/slapd \
+ --line "SLAPD_CONF=${SLAPD_DIR}/slapd.conf" \
+ --state present
+
+ require="__line/rm_slapd_services" __line add_slapd_services \
+ --file ${ETC}/default/slapd \
+ --line "SLAPD_SERVICES=\"${slapd_urls}\"" \
+ --state present
+ ;;
+ *)
+ # Nothing to do here, move on.
+ ;;
+esac
+
+
+if [ -z "${_skip_letsencrypt_cert}" ]; then
+ if [ -f "${__object}/parameter/staging" ]; then
+ staging="--staging"
+ else
+ staging=""
+ fi
+
+ # shellcheck disable=SC2086
+ __letsencrypt_cert "${name}" --admin-email "${admin_email}" \
+ --renew-hook "cp ${ETC}/letsencrypt/live/${name}/*.pem ${SLAPD_DIR}/sasl2 && chown -R openldap:openldap ${SLAPD_DIR}/sasl2 && service slapd restart" \
+ --automatic-renewal ${staging}
+fi
+
+require="__package/${PKG_MAIN}" __directory ${SLAPD_DIR}/slapd.d --state absent
+
+if [ -z "${_skip_letsencrypt_cert}" ]; then
+ require="__package/${PKG_MAIN} __letsencrypt_cert/${name}" \
+ __file ${SLAPD_DIR}/slapd.conf --owner ${CONF_OWNER} --group ${CONF_GROUP} --mode 644 \
+ --source "${ldapconf}"
+else
+ require="__package/${PKG_MAIN}" \
+ __file ${SLAPD_DIR}/slapd.conf --owner ${CONF_OWNER} --group ${CONF_GROUP} --mode 644 \
+ --source "${ldapconf}"
+fi
+
+# Start slapd.conf
+cat << EOF > "${ldapconf}"
+pidfile ${SLAPD_RUN_DIR}/slapd.pid
+argsfile ${SLAPD_RUN_DIR}/slapd.args
+
+TLSCipherSuite ${tls_cipher_suite}
+TLSCertificateFile ${tls_cert}
+TLSCertificateKeyFile ${tls_privkey}
+TLSCACertificateFile ${tls_ca}
+
+disallow bind_anon
+require bind
+security tls=1
+EOF
+
+# Add specified schemas
+for schema in ${schemas}; do
+ echo "include ${SLAPD_DIR}/schema/${schema}.schema" >> "${ldapconf}"
+done
+
+# Add specified modules
+echo "modulepath ${SLAPD_MODULE_PATH}" >> "${ldapconf}"
+for module in ${slapd_modules}; do
+ echo "moduleload ${module}.la" >> "${ldapconf}"
+done
+
+# Rest of the config
+cat << EOF >> "${ldapconf}"
+loglevel 1024
+
+database mdb
+maxsize 1073741824
+
+suffix "${suffix}"
+directory ${SLAPD_DATA_DIR}
+rootdn "${manager_dn}"
+rootpw "${manager_password_hash}"
+
+index objectClass eq,pres
+index ou,cn,mail,surname,givenname eq,pres,sub
+index uidNumber,gidNumber,loginShell eq,pres
+index uid,memberUid eq,pres,sub
+index nisMapName,nisMapEntry eq,pres,sub
+index entryCSN,entryUUID eq
+
+${extra_config}
+
+serverid ${serverid}
+EOF
+
+# Setup replication
+if [ "${replication}" ]; then
+ rid=1;
+ for syncrepl in ${syncrepl_hosts}; do
+ cat <> "${ldapconf}"
+syncrepl rid=${rid}
+ provider=ldap://${syncrepl}
+ bindmethod=simple
+ starttls=yes
+ binddn="${manager_dn}"
+ credentials=${syncrepl_credentials}
+ searchbase="${syncrepl_searchbase}"
+ type=refreshAndPersist
+ retry="5 + 5 +"
+ interval=00:00:00:05
+EOF
+ rid=$((rid + 1))
+ done
+ cat <> "${ldapconf}"
+mirrormode true
+overlay syncprov
+syncprov-checkpoint 100 5
+syncprov-sessionlog 100
+
+database monitor
+limits dn.exact="${manager_dn}" time=unlimited size=unlimited
+EOF
+fi
diff --git a/cdist/conf/type/__openldap_server/parameter/boolean b/cdist/conf/type/__openldap_server/parameter/boolean
new file mode 100644
index 00000000..45056fe9
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/boolean
@@ -0,0 +1,2 @@
+staging
+replicate
diff --git a/cdist/conf/type/__openldap_server/parameter/default/description b/cdist/conf/type/__openldap_server/parameter/default/description
new file mode 100644
index 00000000..6d8e37e1
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/default/description
@@ -0,0 +1 @@
+Managed by cdist, do not edit manually.
diff --git a/cdist/conf/type/__openldap_server/parameter/default/schema b/cdist/conf/type/__openldap_server/parameter/default/schema
new file mode 100644
index 00000000..825bdb15
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/default/schema
@@ -0,0 +1,12 @@
+corba
+core
+cosine
+duaconf
+dyngroup
+inetorgperson
+java
+misc
+nis
+openldap
+ppolicy
+collective
diff --git a/cdist/conf/type/__openldap_server/parameter/optional b/cdist/conf/type/__openldap_server/parameter/optional
new file mode 100644
index 00000000..71c64659
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/optional
@@ -0,0 +1,9 @@
+description
+syncrepl-credentials
+syncrepl-searchbase
+admin-email
+tls-cipher-suite
+tls-cert
+tls-privkey
+tls-ca
+extra-config
diff --git a/cdist/conf/type/__openldap_server/parameter/optional_multiple b/cdist/conf/type/__openldap_server/parameter/optional_multiple
new file mode 100644
index 00000000..52a83d5c
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/optional_multiple
@@ -0,0 +1,3 @@
+syncrepl-host
+module
+schema
diff --git a/cdist/conf/type/__openldap_server/parameter/required b/cdist/conf/type/__openldap_server/parameter/required
new file mode 100644
index 00000000..ff58158d
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/required
@@ -0,0 +1,5 @@
+manager-dn
+manager-password
+manager-password-hash
+serverid
+suffix
diff --git a/cdist/conf/type/__openldap_server/parameter/required_multiple b/cdist/conf/type/__openldap_server/parameter/required_multiple
new file mode 100644
index 00000000..848b8dc2
--- /dev/null
+++ b/cdist/conf/type/__openldap_server/parameter/required_multiple
@@ -0,0 +1 @@
+slapd-url
\ No newline at end of file
diff --git a/cdist/conf/type/__openldap_server/singleton b/cdist/conf/type/__openldap_server/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__package/manifest b/cdist/conf/type/__package/manifest
index f9de1145..a453c32b 100755
--- a/cdist/conf/type/__package/manifest
+++ b/cdist/conf/type/__package/manifest
@@ -1,6 +1,7 @@
#!/bin/sh -e
#
# 2011-2013 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -44,6 +45,7 @@ else
suse) type="zypper" ;;
openwrt) type="opkg" ;;
openbsd) type="pkg_openbsd" ;;
+ alpine) type="apk" ;;
*)
echo "Don't know how to manage packages on: $os" >&2
exit 1
diff --git a/cdist/conf/type/__pf_ruleset/explorer/cksum b/cdist/conf/type/__package_apk/explorer/state
similarity index 55%
rename from cdist/conf/type/__pf_ruleset/explorer/cksum
rename to cdist/conf/type/__package_apk/explorer/state
index 9be6c901..b477ca7c 100755
--- a/cdist/conf/type/__pf_ruleset/explorer/cksum
+++ b/cdist/conf/type/__package_apk/explorer/state
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# 2012 Jake Guffey (jake.guffey at eprotex.com)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -18,24 +18,21 @@
# along with cdist. If not, see .
#
#
-# Get the 256 bit SHA2 checksum of the pf ruleset on the target host.
+# Retrieve the status of a package - parsed apk output
#
-# Debug
-#exec >&2
-#set -x
-
-# Check /etc/rc.conf for pf's configuration file name. Default to /etc/pf.conf
-# See if file exists and if so, get checksum
-
-RC="/etc/rc.conf"
-TMP="$(grep '^pf_rules=' ${RC} | cut -d= -f2 | sed 's/"//g')"
-PFCONF="${TMP:-"/etc/pf.conf"}"
-
-if [ -f "${PFCONF}" ]; then # The pf config file exists, find its cksum.
- cksum -o 1 "${PFCONF}" | cut -d= -f2 | awk '{print $1}'
+if [ -f "$__object/parameter/name" ]; then
+ name="$(cat "$__object/parameter/name")"
+else
+ name="$__object_id"
fi
-# Debug
-#set +x
+# Remove the @.. repo tag for finding out whether it is installed
+# f.i. pass@testing => pass
+name="$(echo "$name" | sed 's/@.*//')"
+if [ "$(apk list -I "$name")" ]; then
+ echo present
+else
+ echo absent
+fi
diff --git a/cdist/conf/type/__package_apk/gencode-remote b/cdist/conf/type/__package_apk/gencode-remote
new file mode 100755
index 00000000..79e3d2b6
--- /dev/null
+++ b/cdist/conf/type/__package_apk/gencode-remote
@@ -0,0 +1,49 @@
+#!/bin/sh -e
+#
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+# Manage packages on Debian and co.
+#
+
+if [ -f "$__object/parameter/name" ]; then
+ name="$(cat "$__object/parameter/name")"
+else
+ name="$__object_id"
+fi
+
+state_should="$(cat "$__object/parameter/state")"
+state_is="$(cat "$__object/explorer/state")"
+
+# Nothing to be done
+[ "$state_is" = "$state_should" ] && exit 0
+
+case "$state_should" in
+ present)
+ echo "apk add -q '$name'"
+ echo "installed" >> "$__messages_out"
+ ;;
+ absent)
+ echo "apk del -q '$name'"
+ echo "removed" >> "$__messages_out"
+ ;;
+ *)
+ echo "Unknown state: $state_should" >&2
+ exit 1
+ ;;
+esac
diff --git a/cdist/conf/type/__package_apk/man.rst b/cdist/conf/type/__package_apk/man.rst
new file mode 100644
index 00000000..bc2408b4
--- /dev/null
+++ b/cdist/conf/type/__package_apk/man.rst
@@ -0,0 +1,55 @@
+cdist-type__package_akp(7)
+==========================
+
+NAME
+----
+cdist-type__package_akp - Manage packages with akp
+
+
+DESCRIPTION
+-----------
+apk is usually used on Alpine to manage packages.
+
+
+REQUIRED PARAMETERS
+-------------------
+None
+
+
+OPTIONAL PARAMETERS
+-------------------
+name
+ If supplied, use the name and not the object id as the package name.
+
+state
+ Either "present" or "absent", defaults to "present"
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # Ensure zsh in installed
+ __package_apk zsh --state present
+
+ # Remove package
+ __package_apk apache2 --state absent
+
+
+SEE ALSO
+--------
+:strong:`cdist-type__package`\ (7)
+
+
+AUTHORS
+-------
+Nico Schottelius
+
+
+COPYING
+-------
+Copyright \(C) 2019 Nico Schottelius. 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.
diff --git a/cdist/conf/type/__package_apk/nonparallel b/cdist/conf/type/__package_apk/nonparallel
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__package_apk/parameter/default/state b/cdist/conf/type/__package_apk/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__package_apk/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__package_apk/parameter/optional b/cdist/conf/type/__package_apk/parameter/optional
new file mode 100644
index 00000000..1b423dc4
--- /dev/null
+++ b/cdist/conf/type/__package_apk/parameter/optional
@@ -0,0 +1,2 @@
+name
+state
diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote
index 699eb0c9..e02564a2 100755
--- a/cdist/conf/type/__package_apt/gencode-remote
+++ b/cdist/conf/type/__package_apt/gencode-remote
@@ -74,6 +74,14 @@ fi
case "$state_should" in
present)
+ # following is bit ugly, but important hack.
+ # due to how cdist config run works, there isn't
+ # currently better way to do it :(
+ cat << EOF
+if [ ! -f /var/cache/apt/pkgcache.bin ] || [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ]
+then echo apt-get update > /dev/null 2>&1 || true
+fi
+EOF
if [ -n "$version" ]; then
name="${name}=${version}"
fi
diff --git a/cdist/conf/type/__package_apt/man.rst b/cdist/conf/type/__package_apt/man.rst
index a3a70d91..a1691eac 100644
--- a/cdist/conf/type/__package_apt/man.rst
+++ b/cdist/conf/type/__package_apt/man.rst
@@ -11,6 +11,9 @@ DESCRIPTION
apt-get is usually used on Debian and variants (like Ubuntu) to
manage packages.
+This type will also update package index, if it is older
+than one day, to avoid missing package error messages.
+
REQUIRED PARAMETERS
-------------------
diff --git a/cdist/conf/type/__package_update_index/explorer/currage b/cdist/conf/type/__package_update_index/explorer/currage
index 3539b8e1..8eadaf53 100644
--- a/cdist/conf/type/__package_update_index/explorer/currage
+++ b/cdist/conf/type/__package_update_index/explorer/currage
@@ -24,16 +24,19 @@ case "$type" in
if [ -f "/var/cache/apt/pkgcache.bin" ]; then
echo $(($(date +"%s")-$(stat --format '%Y' /var/cache/apt/pkgcache.bin)))
else
- echo 0
+ echo -- -1
fi
;;
pacman)
if [ -d "/var/lib/pacman/sync" ]; then
echo $(($(date +"%s")-$(stat --format '%Y' /var/lib/pacman/sync)))
else
- echo 0
+ echo -- -1
fi
;;
+ alpine)
+ echo -- -1
+ ;;
*) echo "Your specified type ($type) is currently not supported." >&2
echo "Please contribute an implementation for it if you can." >&2
;;
diff --git a/cdist/conf/type/__package_update_index/explorer/type b/cdist/conf/type/__package_update_index/explorer/type
index 35254c5f..c98e1e67 100644
--- a/cdist/conf/type/__package_update_index/explorer/type
+++ b/cdist/conf/type/__package_update_index/explorer/type
@@ -26,6 +26,7 @@ else
amazon|scientific|centos|fedora|redhat) echo "yum" ;;
debian|ubuntu|devuan) echo "apt" ;;
archlinux) echo "pacman" ;;
+ alpine) echo "apk" ;;
*)
echo "Don't know how to manage packages on: $os" >&2
exit 1
diff --git a/cdist/conf/type/__package_update_index/gencode-remote b/cdist/conf/type/__package_update_index/gencode-remote
index 738d38eb..803468b5 100755
--- a/cdist/conf/type/__package_update_index/gencode-remote
+++ b/cdist/conf/type/__package_update_index/gencode-remote
@@ -31,7 +31,8 @@ if [ -n "$maxage" ]; then
if [ "$type" != "apt" ] && [ "$type" != "pacman" ]; then
echo "ERROR: \"--maxage\" only supported for \"apt\" or \"pacman\" pkg-manager." >&2
exit 1
- elif [ "$currage" -lt "$maxage" ]; then
+ # do not exit if no value found (represented as -1)
+ elif [ "$currage" -ne -1 ] && [ "$currage" -lt "$maxage" ]; then
exit 0 # no need to update
fi
fi
@@ -47,6 +48,10 @@ case "$type" in
echo "pacman --noprogressbar --sync --refresh"
echo "pacman package database synced (age was: $currage)" >> "$__messages_out"
;;
+ apk)
+ echo "apk update"
+ echo "apk package database updated." >>"$__messages_out"
+ ;;
*)
echo "Don't know how to manage packages for type: $type" >&2
exit 1
diff --git a/cdist/conf/type/__pf_apply/deprecated b/cdist/conf/type/__pf_apply/deprecated
new file mode 100644
index 00000000..36cfed90
--- /dev/null
+++ b/cdist/conf/type/__pf_apply/deprecated
@@ -0,0 +1 @@
+Consider moving to __pf_apply_anchor. Get in touch if you need __pf_apply.
diff --git a/cdist/conf/type/__pf_apply_anchor/gencode-remote b/cdist/conf/type/__pf_apply_anchor/gencode-remote
new file mode 100755
index 00000000..36c26521
--- /dev/null
+++ b/cdist/conf/type/__pf_apply_anchor/gencode-remote
@@ -0,0 +1,33 @@
+#!/bin/sh -e
+#
+# 2016 Kamila Součková (coding at kamila.is)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+# Apply pf(4) ruleset on *BSD
+#
+
+ANCHORS_DIR="/etc/pf.d"
+
+if [ -f "${__object}/parameter/anchor_name" ]; then
+ anchor_name="$(cat "${__object}/parameter/anchor_name")"
+else
+ anchor_name="${__object_id}"
+fi
+anchor_file="${ANCHORS_DIR}/${anchor_name}"
+
+echo "pfctl -a \"${anchor_name}\" -f \"${anchor_file}\""
diff --git a/cdist/conf/type/__pf_apply_anchor/man.rst b/cdist/conf/type/__pf_apply_anchor/man.rst
new file mode 100644
index 00000000..aef6cdf4
--- /dev/null
+++ b/cdist/conf/type/__pf_apply_anchor/man.rst
@@ -0,0 +1,62 @@
+cdist-type__pf_apply_anchor(7)
+==============================
+
+NAME
+----
+cdist-type__pf_apply_anchor - Apply a pf(4) anchor on $__target_host
+
+
+DESCRIPTION
+-----------
+This type is used on \*BSD systems to manage anchors for the pf firewall.
+
+Notice this type does not take care of copying the ruleset, that must be
+done by the user with, e.g. `__file`.
+
+
+OPTIONAL PARAMETERS
+-------------------
+anchor_name
+ The name of the anchor to apply. If not set, `${__object_id}` is used.
+ This type requires `/etc/pf.d/${anchor_name}` to exist on
+ `$__target_host`.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # Copy anchor file to ${__target_host}
+ __file "/etc/pf.d/80_dns" --source - <
+Kamila Součková
+Jake Guffey
+
+
+COPYING
+-------
+Copyright \(C) 2020 Evilham.
+Copyright \(C) 2016 Kamila Součková.
+Copyright \(C) 2012 Jake Guffey. 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.
diff --git a/cdist/conf/type/__pf_apply_anchor/parameter/optional b/cdist/conf/type/__pf_apply_anchor/parameter/optional
new file mode 100644
index 00000000..b9f61e28
--- /dev/null
+++ b/cdist/conf/type/__pf_apply_anchor/parameter/optional
@@ -0,0 +1 @@
+anchor_name
diff --git a/cdist/conf/type/__pf_rdr/manifest b/cdist/conf/type/__pf_rdr/manifest
new file mode 100644
index 00000000..39ab4470
--- /dev/null
+++ b/cdist/conf/type/__pf_rdr/manifest
@@ -0,0 +1,40 @@
+#!/bin/sh -e
+#
+# 2016 Kamila Součková (coding at kamila.is)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+# TODO it would be cool to print a warning if a generated anchor is unused in pf.conf
+
+ANCHORS_DIR=/etc/pf.d
+
+proto="$(cat "${__object}/parameter/proto")"
+from="$(cat "${__object}/parameter/from")"
+to="$(cat "${__object}/parameter/to")"
+state="$(cat "${__object}/parameter/state")"
+
+# This breaks utterly with IPv6
+from="$(echo ${from} | sed 's/:/ port /')"
+to="$(echo ${to} | sed 's/:/ port /')"
+
+anchor_name="$(echo ${__object_id} | cut -d/ -f1)"
+rule="rdr pass log proto ${proto} from any to ${from} -> ${to}"
+
+__directory "${ANCHORS_DIR}" --parents
+
+require="__directory/${ANCHORS_DIR}" \
+__line __pf_rdr/${__object_id} --state ${state} --line "${rule}" --file ${ANCHORS_DIR}/${anchor_name}
diff --git a/cdist/conf/type/__pf_rdr/parameter/default/proto b/cdist/conf/type/__pf_rdr/parameter/default/proto
new file mode 100644
index 00000000..28a29e6f
--- /dev/null
+++ b/cdist/conf/type/__pf_rdr/parameter/default/proto
@@ -0,0 +1 @@
+tcp
diff --git a/cdist/conf/type/__pf_rdr/parameter/default/state b/cdist/conf/type/__pf_rdr/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__pf_rdr/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__pf_rdr/parameter/optional b/cdist/conf/type/__pf_rdr/parameter/optional
new file mode 100644
index 00000000..09ec92ca
--- /dev/null
+++ b/cdist/conf/type/__pf_rdr/parameter/optional
@@ -0,0 +1,2 @@
+proto
+state
diff --git a/cdist/conf/type/__pf_rdr/parameter/required b/cdist/conf/type/__pf_rdr/parameter/required
new file mode 100644
index 00000000..4a568482
--- /dev/null
+++ b/cdist/conf/type/__pf_rdr/parameter/required
@@ -0,0 +1,2 @@
+from
+to
diff --git a/cdist/conf/type/__pf_ruleset/gencode-local b/cdist/conf/type/__pf_ruleset/gencode-local
deleted file mode 100755
index 11bfb0b1..00000000
--- a/cdist/conf/type/__pf_ruleset/gencode-local
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/sh -e
-#
-# 2012 Jake Guffey (jake.guffey at eprotex.com)
-#
-# This file is part of cdist.
-#
-# cdist 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.
-#
-# cdist 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 cdist. If not, see .
-#
-#
-# Manage pf(4) on *BSD
-#
-
-# Debug
-#exec >&2
-#set -x
-
-# Send files to $__target_host via $__remote_copy
-
-uname=$(uname) # Need to know what the cdist host is running so we know how to compute the ruleset's checksum
-state=$(cat "$__object/parameter/state")
-
-if [ "$state" = "absent" ]; then # There is nothing more for a *local* script to do
- exit 0
-fi
-
-if [ -f "$__object/parameter/source" ]; then
- source=$(cat "$__object/parameter/source")
-fi
-
-rcvar=$(cat "$__object/explorer/rcvar")
-cksum=$(cat "$__object/explorer/cksum")
-
-
-cat <&2
- exit 1
- ;;
-esac
-
-# IPv6 fix
-if $(echo "${__target_host}" | grep -q -E '^[0-9a-fA-F:]+$')
-then
- my_target_host="[${__target_host}]"
-else
- my_target_host="${__target_host}"
-fi
-
-if [ -n "${cksum}" ]; then
- if [ ! "\${currentSum}" = "${cksum}" ]; then
- $__remote_copy "${source}" "\${my_target_host}:${rcvar}.new"
- fi
-else # File just doesn't exist yet
- $__remote_copy "${source}" "\${my_target_host}:${rcvar}.new"
-fi
-EOF
-
-# Debug
-#exec +x
-
diff --git a/cdist/conf/type/__pf_ruleset/man.rst b/cdist/conf/type/__pf_ruleset/man.rst
index 5719e94e..db8873ac 100644
--- a/cdist/conf/type/__pf_ruleset/man.rst
+++ b/cdist/conf/type/__pf_ruleset/man.rst
@@ -10,6 +10,9 @@ DESCRIPTION
-----------
This type is used on \*BSD systems to manage the pf firewall's ruleset.
+It will also enable and disable the pf firewall as requested in the `state`
+parameter.
+
REQUIRED PARAMETERS
-------------------
@@ -20,9 +23,8 @@ state
OPTIONAL PARAMETERS
-------------------
source
- If supplied, use to define the ruleset to load onto the $__target_host for pf(4).
- Note that this type is almost useless without a ruleset defined, but it's technically not
- needed, e.g. for the case of disabling the firewall temporarily.
+ Required when state is "present".
+ Defines the ruleset to load onto the $__target_host for `pf(4)`.
EXAMPLES
@@ -30,10 +32,10 @@ EXAMPLES
.. code-block:: sh
- # Remove the current ruleset in place
+ # Remove the current ruleset in place and disable pf
__pf_ruleset --state absent
- # Enable the firewall with the ruleset defined in $__manifest/files/pf.conf
+ # Enable pf with the ruleset defined in $__manifest/files/pf.conf
__pf_ruleset --state present --source $__manifest/files/pf.conf
@@ -44,11 +46,13 @@ SEE ALSO
AUTHORS
-------
+Kamila Součková
Jake Guffey
COPYING
-------
+Copyright \(C) 2016 Kamila Součková.
Copyright \(C) 2012 Jake Guffey. 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
diff --git a/cdist/conf/type/__pf_ruleset/manifest b/cdist/conf/type/__pf_ruleset/manifest
new file mode 100755
index 00000000..27b35328
--- /dev/null
+++ b/cdist/conf/type/__pf_ruleset/manifest
@@ -0,0 +1,46 @@
+#!/bin/sh -e
+#
+# 2016 Kamila Součková (coding at kamila.is)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+# Manage pf(4) on *BSD
+#
+
+rcvar="$(cat "${__object}/explorer/rcvar")"
+state="$(cat "${__object}/parameter/state")"
+if [ -f "${__object}/parameter/source" ]; then
+ source="$(cat "${__object}/parameter/source")"
+fi
+
+if [ "${state}" = "absent" ]; then
+ action="/etc/rc.d/pf stop"
+else
+ action="/etc/rc.d/pf reload || /etc/rc.d/pf start"
+fi
+
+__key_value __pf_ruleset/rcvar \
+ --state "${state}" \
+ --file /etc/rc.conf \
+ --delimiter "=" \
+ --key "pf_enable" \
+ --value "YES"
+
+require="__key_value/__pf_ruleset/rcvar" __config_file "${rcvar}" \
+ --source "${source}" \
+ --state "${state}" \
+ --onchange "${action}"
diff --git a/cdist/conf/type/__postfix/manifest b/cdist/conf/type/__postfix/manifest
index 1aea53a1..121bba96 100755
--- a/cdist/conf/type/__postfix/manifest
+++ b/cdist/conf/type/__postfix/manifest
@@ -1,6 +1,7 @@
#!/bin/sh -e
#
# 2012-2014 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -18,16 +19,4 @@
# along with cdist. If not, see .
#
-
-os=$(cat "$__global/explorer/os")
-
-case "$os" in
- ubuntu|debian|archlinux|suse|scientific|centos|devuan)
- __package postfix --state present
- ;;
- *)
- echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
- echo "Please contribute an implementation for it if you can." >&2
- exit 1
- ;;
-esac
+__package postfix --state present
diff --git a/cdist/conf/type/__postfix_postconf/explorer/value b/cdist/conf/type/__postfix_postconf/explorer/value
index 17126c94..67dacad8 100755
--- a/cdist/conf/type/__postfix_postconf/explorer/value
+++ b/cdist/conf/type/__postfix_postconf/explorer/value
@@ -22,7 +22,7 @@
os=$("$__explorer/os")
case "$os" in
- ubuntu|debian|archlinux|suse|scientific|centos|devuan)
+ alpine|ubuntu|debian|archlinux|suse|scientific|centos|devuan)
:
;;
*)
diff --git a/cdist/conf/type/__postfix_postconf/gencode-remote b/cdist/conf/type/__postfix_postconf/gencode-remote
index 6df0da7f..279dddd4 100755
--- a/cdist/conf/type/__postfix_postconf/gencode-remote
+++ b/cdist/conf/type/__postfix_postconf/gencode-remote
@@ -1,6 +1,7 @@
#!/bin/sh -e
#
# 2012-2014 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -21,7 +22,7 @@
os=$(cat "$__global/explorer/os")
case "$os" in
- ubuntu|debian|archlinux|suse|scientific|centos|devuan)
+ alpine|archlinux|centos|debian|devuan|suse|scientific|ubuntu)
:
;;
*)
diff --git a/cdist/conf/type/__postgres_database/explorer/state b/cdist/conf/type/__postgres_database/explorer/state
index 652d81e7..d68d4120 100755
--- a/cdist/conf/type/__postgres_database/explorer/state
+++ b/cdist/conf/type/__postgres_database/explorer/state
@@ -34,7 +34,7 @@ esac
name="$__object_id"
-if test -n "$(su - "$postgres_user" -c "psql postgres -tAc \"SELECT 1 FROM pg_database WHERE datname='$name'\"")"
+if test -n "$(su - "$postgres_user" -c "psql postgres -twAc \"SELECT 1 FROM pg_database WHERE datname='$name'\"")"
then
echo 'present'
else
diff --git a/cdist/conf/type/__postgres_database/gencode-remote b/cdist/conf/type/__postgres_database/gencode-remote
index 61cfa50d..0f11cff4 100755
--- a/cdist/conf/type/__postgres_database/gencode-remote
+++ b/cdist/conf/type/__postgres_database/gencode-remote
@@ -41,12 +41,37 @@ if [ "$state_should" != "$state_is" ]; then
present)
owner=""
if [ -f "$__object/parameter/owner" ]; then
- owner="-O '$(cat "$__object/parameter/owner")'"
+ owner="-O \"$(cat "$__object/parameter/owner")\""
fi
- echo "su - '$postgres_user' -c \"createdb $owner '$name'\""
+
+ template=""
+ if [ -f "$__object/parameter/template" ]; then
+ template="--template \"$(cat "$__object/parameter/template")\""
+ fi
+
+ encoding=""
+ if [ -f "$__object/parameter/encoding" ]; then
+ encoding="--encoding \"$(cat "$__object/parameter/encoding")\""
+ fi
+
+ lc_collate=""
+ if [ -f "$__object/parameter/lc-collate" ]; then
+ lc_collate="--lc-collate \"$(cat "$__object/parameter/lc-collate")\""
+ fi
+
+ lc_ctype=""
+ if [ -f "$__object/parameter/lc-ctype" ]; then
+ lc_ctype="--lc-ctype \"$(cat "$__object/parameter/lc-ctype")\""
+ fi
+
+ cat << EOF
+su - '$postgres_user' -c "createdb $owner \"$name\" $template $encoding $lc_collate $lc_ctype"
+EOF
;;
absent)
- echo "su - '$postgres_user' -c \"dropdb '$name'\""
+ cat << EOF
+su - '$postgres_user' -c "dropdb \"$name\""
+EOF
;;
esac
fi
diff --git a/cdist/conf/type/__postgres_database/man.rst b/cdist/conf/type/__postgres_database/man.rst
index acceec9b..870b4917 100644
--- a/cdist/conf/type/__postgres_database/man.rst
+++ b/cdist/conf/type/__postgres_database/man.rst
@@ -14,10 +14,22 @@ This cdist type allows you to create or drop postgres databases.
OPTIONAL PARAMETERS
-------------------
state
- either 'present' or 'absent', defaults to 'present'.
+ Either 'present' or 'absent', defaults to 'present'.
owner
- the role owning this database
+ Specifies the database user who will own the new database.
+
+encoding
+ Specifies the character encoding scheme to be used in this database.
+
+lc-collate
+ Specifies the LC_COLLATE setting to be used in this database.
+
+lc-ctype
+ Specifies the LC_CTYPE setting to be used in this database.
+
+template
+ Specifies the template database from which to build this database.
EXAMPLES
diff --git a/cdist/conf/type/__postgres_database/parameter/optional b/cdist/conf/type/__postgres_database/parameter/optional
index d86b6469..877fbf32 100644
--- a/cdist/conf/type/__postgres_database/parameter/optional
+++ b/cdist/conf/type/__postgres_database/parameter/optional
@@ -1,2 +1,6 @@
state
owner
+encoding
+lc-collate
+lc-ctype
+template
diff --git a/cdist/conf/type/__postgres_role/explorer/state b/cdist/conf/type/__postgres_role/explorer/state
index 5cc71477..c8e1fa9d 100755
--- a/cdist/conf/type/__postgres_role/explorer/state
+++ b/cdist/conf/type/__postgres_role/explorer/state
@@ -34,7 +34,7 @@ esac
name="$__object_id"
-if test -n "$(su - "$postgres_user" -c "psql postgres -tAc \"SELECT 1 FROM pg_roles WHERE rolname='$name'\"")"
+if test -n "$(su - "$postgres_user" -c "psql postgres -twAc \"SELECT 1 FROM pg_roles WHERE rolname='$name'\"")"
then
echo 'present'
else
diff --git a/cdist/conf/type/__postgres_role/gencode-remote b/cdist/conf/type/__postgres_role/gencode-remote
index 30d0689c..282294c9 100755
--- a/cdist/conf/type/__postgres_role/gencode-remote
+++ b/cdist/conf/type/__postgres_role/gencode-remote
@@ -53,11 +53,13 @@ case "$state_should" in
done
[ -n "$password" ] && password="PASSWORD '$password'"
-
- cmd="CREATE ROLE $name WITH $password $booleans"
- echo "su - '$postgres_user' -c \"psql postgres -c \\\"$cmd\\\"\""
+ cat << EOF
+su - '$postgres_user' -c "psql postgres -wc \"CREATE ROLE \\\\\"$name\\\\\" WITH $password $booleans;\""
+EOF
;;
absent)
- echo "su - '$postgres_user' -c \"dropuser \\\"$name\\\"\""
+ cat << EOF
+su - '$postgres_user' -c "dropuser \"$name\""
+EOF
;;
esac
diff --git a/cdist/conf/type/__prometheus_alertmanager/manifest b/cdist/conf/type/__prometheus_alertmanager/manifest
index 8ee818c3..cf410c44 100755
--- a/cdist/conf/type/__prometheus_alertmanager/manifest
+++ b/cdist/conf/type/__prometheus_alertmanager/manifest
@@ -30,6 +30,7 @@ if [ -f "$__object/parameter/install-from-backports" ]; then
*)
echo "--install-from-backports is only supported on Devuan -- ignoring." >&2
echo "Send a pull request if you require it." >&2
+ exit 1
;;
esac
else
@@ -60,5 +61,5 @@ require="$require __directory/$storage_path $require_pkg" \
__config_file $CONF \
--source "$config" \
--group prometheus --mode 640 \
- --onchange "service prometheus-alertmanager reload" # TODO when a config-check tool is available, check config here
+ --onchange "service prometheus-alertmanager restart" # TODO when a config-check tool is available, check config here
diff --git a/cdist/conf/type/__prometheus_exporter/manifest b/cdist/conf/type/__prometheus_exporter/manifest
index b9e14531..f3930ac6 100644
--- a/cdist/conf/type/__prometheus_exporter/manifest
+++ b/cdist/conf/type/__prometheus_exporter/manifest
@@ -5,9 +5,11 @@ export GOBIN=/opt/gocode/bin # where to find go binaries
exporter="$(cat "$__object/parameter/exporter")"
[ -z "$exporter" ] && exporter="$__object_id"
-__user prometheus --system
+__user prometheus
+require="__user/prometheus" __group prometheus
+require="__group/prometheus" __user_groups prometheus --group prometheus
-require=""
+require="__user_groups/prometheus"
case $exporter in
node)
TEXTFILES=/service/node-exporter/textfiles # path for the textfiles collector
diff --git a/cdist/conf/type/__prometheus_server/manifest b/cdist/conf/type/__prometheus_server/manifest
index 8685130f..9756169e 100755
--- a/cdist/conf/type/__prometheus_server/manifest
+++ b/cdist/conf/type/__prometheus_server/manifest
@@ -33,11 +33,13 @@ if [ -f "$__object/parameter/install-from-backports" ]; then
*)
echo "--install-from-backports is only supported on Devuan -- ignoring." >&2
echo "Send a pull request if you require it." >&2
+ exit 1
;;
esac
else
__package prometheus
- require_pkg="__package/prometheus"
+ __package prometheus-blackbox-exporter
+ require_pkg="__package/prometheus __package/prometheus-blackbox-exporter"
fi
##### PREPARE PATHS AND SUCH ################################################
@@ -58,7 +60,7 @@ require="$require __directory/$storage_path $require_pkg" \
__config_file $CONF \
--source "$config" \
--group prometheus --mode 640 \
- --onchange "promtool check config $CONF && service prometheus reload"
+ --onchange "promtool check config $CONF && service prometheus restart"
for file in $rule_files; do
dest=$CONF_DIR/$(basename "$file")
@@ -66,6 +68,6 @@ for file in $rule_files; do
__config_file "$dest" \
--source "$file" \
--owner prometheus \
- --onchange "promtool check rules '$dest' && service prometheus reload"
+ --onchange "promtool check rules '$dest' && service prometheus restart"
done
diff --git a/cdist/conf/type/__pyvenv/gencode-remote b/cdist/conf/type/__pyvenv/gencode-remote
index 04700683..9c7b7fab 100755
--- a/cdist/conf/type/__pyvenv/gencode-remote
+++ b/cdist/conf/type/__pyvenv/gencode-remote
@@ -37,11 +37,21 @@ mode="$(cat "$__object/parameter/mode")"
destination="/$__object_id"
venvparams="$(cat "$__object/parameter/venvparams")"
pyvenvparam="$__object/parameter/pyvenv"
+
+os=$(cat "$__global/explorer/os")
+
if [ -f "$pyvenvparam" ]
then
pyvenv=$(cat "$pyvenvparam")
else
- pyvenv="pyvenv"
+ case "$os" in
+ alpine) # no pyvenv on alpine - I assume others will follow
+ pyvenv="python3 -m venv"
+ ;;
+ *)
+ pyvenv="pyvenv"
+ ;;
+ esac
fi
case $state_should in
diff --git a/cdist/conf/type/__sensible_editor/explorer/editor_path b/cdist/conf/type/__sensible_editor/explorer/editor_path
new file mode 100644
index 00000000..dcf63c9b
--- /dev/null
+++ b/cdist/conf/type/__sensible_editor/explorer/editor_path
@@ -0,0 +1,131 @@
+#!/bin/sh -e
+#
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+# Check if the given editor is present on the target system and determine its
+# absolute path.
+#
+
+die() {
+ echo "$@" >&2
+ exit 1
+}
+
+editor_missing() { die "Editor '$1' is missing on the target system."; }
+editor_no_alternative() {
+ die "Editor '$1' is not in the alternatives list of the target system." \
+ "$(test -n "${editors}" && printf '\nPlease choose one of:\n\n%s\n' "${editors}")"
+}
+
+# No need to check for the path if the file is supposed to be removed.
+test "$(cat "${__object}/parameter/state")" != 'absent' || exit 0
+
+
+case $("${__explorer}/os")
+in
+ debian|devuan|ubuntu)
+ has_alternatives=true
+
+ # NOTE: Old versions do not support `--list`, in this case ignore the errors.
+ # This will require an absolute path to be provided, though.
+ editors=$(update-alternatives --list editor 2>/dev/null)
+ ;;
+ *)
+ # NOTE: RedHat has an alternatives system but it doesn't usually track
+ # editors and it is a pain to extract the list.
+ has_alternatives=false
+ ;;
+esac
+
+# Read --editor parameter and check its value since it is "optional"
+editor=$(cat "${__object}/parameter/editor" 2>/dev/null) || true
+test -n "${editor}" || die 'Please provide an --editor to configure.'
+
+case $editor
+in
+ /*)
+ is_abspath=true
+ ;;
+ */*)
+ die 'Relative editor paths are not supported'
+ ;;
+ *)
+ is_abspath=false
+ ;;
+esac
+
+
+if $has_alternatives && test -n "${editors}"
+then
+ IFS='
+'
+ if ! $is_abspath
+ then
+ # First, try to resolve the absolute path using $editors.
+ while true
+ do
+ for e in $editors
+ do
+ if test "$(basename "${e}")" = "${editor}"
+ then
+ editor="${e}"
+ break 2 # break out of both loops
+ fi
+ done
+
+ # Iterating through alternatives did not yield a result
+ editor_no_alternative "${editor}"
+ break
+ done
+ fi
+
+ # Check if editor is present
+ test -f "${editor}" || editor_missing "${editor}"
+
+ for e in $editors
+ do
+ if test "${editor}" = "${e}"
+ then
+ # Editor is part of the alternatives list -> use it!
+ echo "${editor}"
+ exit 0
+ fi
+ done
+
+ editor_no_alternative "${editor}"
+else
+ # NOTE: This branch is mostly for RedHat-based systems which do
+ # not track editor alternatives. To make this type useful
+ # on RedHat at all we allow an absoloute path to be provided
+ # in any case.
+
+ if $is_abspath
+ then
+ test -x "${editor}" || editor_missing "${editor}"
+
+ echo "${editor}"
+ exit 0
+ else
+ die "The target doesn't list any editor alternatives. " \
+ "Please specify an absolute path or populate the alternatives list."
+ fi
+fi
+
+# The script should never reach this statement!
+exit 1
diff --git a/cdist/conf/type/__sensible_editor/explorer/group b/cdist/conf/type/__sensible_editor/explorer/group
new file mode 100644
index 00000000..5d288189
--- /dev/null
+++ b/cdist/conf/type/__sensible_editor/explorer/group
@@ -0,0 +1,26 @@
+#!/bin/sh -e
+#
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+# Determines the primary group of the user.
+#
+
+user=$__object_id
+
+id -gn "${user}" 2>/dev/null
diff --git a/cdist/conf/type/__sensible_editor/explorer/user_home b/cdist/conf/type/__sensible_editor/explorer/user_home
new file mode 100644
index 00000000..b88243f7
--- /dev/null
+++ b/cdist/conf/type/__sensible_editor/explorer/user_home
@@ -0,0 +1,33 @@
+#!/bin/sh -e
+#
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+# Determines the home folder of the target user.
+#
+
+user=$__object_id
+home=$(getent passwd "${user}" | cut -d':' -f6)
+
+if ! test -d "${home}"
+then
+ echo "Cannot find home directory of user ${user}" >&2
+ exit 1
+fi
+
+echo "${home}"
diff --git a/cdist/conf/type/__sensible_editor/man.rst b/cdist/conf/type/__sensible_editor/man.rst
new file mode 100644
index 00000000..9b805e06
--- /dev/null
+++ b/cdist/conf/type/__sensible_editor/man.rst
@@ -0,0 +1,78 @@
+cdist-type__sensible_editor(7)
+==============================
+
+NAME
+----
+cdist-type__sensible_editor - Select the sensible-editor
+
+
+DESCRIPTION
+-----------
+This cdist type allows you to select the :strong:`sensible-editor` for
+a given user.
+
+
+REQUIRED PARAMETERS
+-------------------
+editor
+ Name or path of the editor to be selected.
+ On systems other than Debian derivatives an absolute path is required.
+
+ It is permissible to omit this parameter if --state is absent.
+
+
+OPTIONAL PARAMETERS
+-------------------
+state
+ 'present', 'absent', or 'exists'. Defaults to 'present', where:
+
+ present
+ the sensible-editor is exactly what is specified in --editor.
+ absent
+ no sensible-editor configuration is present.
+ exists
+ the sensible-editor will be set to what is specified in --editor,
+ unless there already is a configuration on the target system.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ __sensible_editor root --editor /bin/ed # ed(1) is the standard
+ __sensible_editor noob --editor nano
+
+
+LIMITATIONS
+-----------
+
+This type depends upon the :strong:`sensible-editor`\ (1) script which
+is part of the sensible-utils package.
+
+Therefore, the following operating systems are supported:
+ * Debian 8 (jessie) or later
+ * Devuan
+ * Ubuntu 8.10 (intrepid) or later
+ * RHEL/CentOS 7 or later (EPEL repo required)
+ * Fedora 21 or later
+
+Note: on old versions of Ubuntu the sensible-* utils are part of the
+debianutils package.
+
+SEE ALSO
+--------
+:strong:`select-editor`\ (1), :strong:`sensible-editor`\ (1).
+
+
+AUTHOR
+-------
+Dennis Camera
+
+
+COPYING
+-------
+Copyright \(C) 2019 Dennis Camera.
+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.
diff --git a/cdist/conf/type/__sensible_editor/manifest b/cdist/conf/type/__sensible_editor/manifest
new file mode 100644
index 00000000..1cdb0c2c
--- /dev/null
+++ b/cdist/conf/type/__sensible_editor/manifest
@@ -0,0 +1,94 @@
+#!/bin/sh -e
+# -*- mode: sh; indent-tabs-mode: t -*-
+#
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+version_ge() {
+ awk -F '[^0-9.]' -v target="${1:?}" '
+ function max(x, y) { return x > y ? x : y; }
+ BEGIN {
+ getline;
+ nx = split($1, x, ".");
+ ny = split(target, y, ".");
+ for (i = 1; i <= max(nx, ny); ++i) {
+ diff = int(x[i]) - int(y[i]);
+ if (diff < 0) exit 1;
+ else if (diff > 0) exit 0;
+ else continue;
+ }
+ }'
+}
+
+not_supported() {
+ echo "OS ${os} does not support __sensible_editor." >&2
+ echo 'If it does, please provide a patch.' >&2
+ exit 1
+}
+
+os=$(cat "${__global}/explorer/os")
+os_version=$(cat "${__global}/explorer/os_version")
+
+state=$(cat "${__object}/parameter/state")
+user=$__object_id
+
+if test "${state}" != 'present' && test "${state}" != 'exists' && test "${state}" != 'absent'
+then
+ echo 'Only "present", "exists", and "absent" are allowed for --state' >&2
+ exit 1
+fi
+
+package_name='sensible-utils'
+
+case $os
+in
+ debian)
+ pkg_type='apt'
+ ;;
+ devuan)
+ pkg_type='apt'
+ ;;
+ ubuntu)
+ (echo "${os_version}" | version_ge 10.04) || package_name='debianutils'
+ pkg_type='apt'
+ ;;
+ centos|fedora|redhat|scientific)
+ pkg_type='yum'
+ ;;
+ *)
+ not_supported
+ ;;
+esac
+
+if test "${state}" != 'absent'
+then
+ __package "${package_name}" --state present \
+ --type "${pkg_type}"
+ export require="__package/${package_name}"
+fi
+
+editor_path=$(cat "${__object}/explorer/editor_path")
+user_home=$(cat "${__object}/explorer/user_home")
+group=$(cat "${__object}/explorer/group")
+
+__file "${user_home}/.selected_editor" --state "${state}" \
+ --owner "${user}" --group "${group}" --mode 0644 \
+ --source - <
+
+
+COPYING
+-------
+Copyright \(C) 2019 Timothée Floure. 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.
diff --git a/cdist/conf/type/__service/manifest b/cdist/conf/type/__service/manifest
new file mode 100644
index 00000000..cb5af234
--- /dev/null
+++ b/cdist/conf/type/__service/manifest
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+manager="$(cat "$__object/explorer/service-manager")"
+
+name=$__object_id
+action="$(cat "$__object/parameter/action")"
+
+case "$manager" in
+ systemd)
+ __systemd_service "$name" --action "$action"
+ ;;
+ *)
+ # Unknown: handled by `service $NAME $action` in gencode-remote.
+ ;;
+esac
diff --git a/cdist/conf/type/__service/parameter/required b/cdist/conf/type/__service/parameter/required
new file mode 100644
index 00000000..a9f84d41
--- /dev/null
+++ b/cdist/conf/type/__service/parameter/required
@@ -0,0 +1 @@
+action
diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/file b/cdist/conf/type/__ssh_authorized_keys/explorer/file
index 5a02721a..017bcb38 100755
--- a/cdist/conf/type/__ssh_authorized_keys/explorer/file
+++ b/cdist/conf/type/__ssh_authorized_keys/explorer/file
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -19,9 +20,42 @@
#
if [ -f "$__object/parameter/file" ]; then
- cat "$__object/parameter/file"
+ cat "$__object/parameter/file"
else
- owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
- home=$(getent passwd "$owner" | cut -d':' -f 6)
- echo "$home/.ssh/authorized_keys"
+ if [ -s "$__object/parameter/owner" ]
+ then
+ owner=$(cat "$__object/parameter/owner")
+ else
+ owner="$__object_id"
+ fi
+
+ if command -v getent >/dev/null
+ then
+ owner_line=$(getent passwd "$owner")
+ elif [ -f /etc/passwd ]
+ then
+ case $owner
+ in
+ [0-9][0-9]*)
+ owner_line=$(awk -F: "\$3 == \"${owner}\" { print }" /etc/passwd)
+ ;;
+ *)
+ owner_line=$(awk -F: "\$1 == \"${owner}\" { print }" /etc/passwd)
+ ;;
+ esac
+ fi
+
+ if [ "$owner_line" ]
+ then
+ home=$(echo "$owner_line" | cut -d':' -f6)
+ fi
+
+ if [ ! -d "$home" ]
+ then
+ # Don't know how to determine user's home directory, fall back to ~
+ home="~$owner"
+ command -v realpath >/dev/null && home=$(realpath "$home")
+ fi
+
+ [ -d "$home" ] && echo "$home/.ssh/authorized_keys"
fi
diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/group b/cdist/conf/type/__ssh_authorized_keys/explorer/group
index 72a4e314..d259050f 100755
--- a/cdist/conf/type/__ssh_authorized_keys/explorer/group
+++ b/cdist/conf/type/__ssh_authorized_keys/explorer/group
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -18,6 +19,28 @@
# along with cdist. If not, see .
#
-owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
-gid="$(getent passwd "$owner" | cut -d':' -f 4)"
-getent group "$gid" || true
+if [ -s "$__object/parameter/owner" ]
+then
+ owner=$(cat "$__object/parameter/owner")
+else
+ owner="$__object_id"
+fi
+
+if command -v getent >/dev/null
+then
+ gid=$(getent passwd "$owner" | cut -d':' -f4)
+ getent group "$gid" || true
+else
+ # Fallback to local file scanning
+ case $owner
+ in
+ [0-9][0-9]*)
+ gid=$(awk -F: "\$3 == \"${owner}\" { print \$4 }" /etc/passwd)
+ ;;
+ *)
+ gid=$(awk -F: "\$1 == \"${owner}\" { print \$4 }" /etc/passwd)
+ ;;
+ esac
+
+ awk -F: "\$3 == \"$gid\" { print }" /etc/group
+fi
diff --git a/cdist/conf/type/__ssh_authorized_keys/manifest b/cdist/conf/type/__ssh_authorized_keys/manifest
index a8ded2f6..b9f0582e 100755
--- a/cdist/conf/type/__ssh_authorized_keys/manifest
+++ b/cdist/conf/type/__ssh_authorized_keys/manifest
@@ -23,6 +23,12 @@ owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
state="$(cat "$__object/parameter/state" 2>/dev/null)"
file="$(cat "$__object/explorer/file")"
+if [ ! -f "$__object/parameter/nofile" ] && [ -z "$file" ]
+then
+ echo "Cannot determine path of authorized_keys file" >&2
+ exit 1
+fi
+
if [ ! -f "$__object/parameter/noparent" ] || [ ! -f "$__object/parameter/nofile" ]; then
group="$(cut -d':' -f 1 "$__object/explorer/group")"
if [ -z "$group" ]; then
@@ -45,18 +51,6 @@ if [ ! -f "$__object/parameter/noparent" ] || [ ! -f "$__object/parameter/nofile
fi
fi
-# Remove legacy blocks created by old versions of this type
-# FIXME: remove me in 3.2+
-__block "$__object_name" \
- --file "$file" \
- --prefix "#cdist:$__object_name" \
- --suffix "#/cdist:$__object_name" \
- --state 'absent' \
- --text - << DONE
-remove legacy block
-DONE
-export require="__block/$__object_name"
-
_cksum() {
echo "$1" | cksum | cut -d' ' -f 1
}
diff --git a/cdist/conf/type/__ssh_dot_ssh/explorer/group b/cdist/conf/type/__ssh_dot_ssh/explorer/group
index cdea6fe7..faf44cb8 100755
--- a/cdist/conf/type/__ssh_dot_ssh/explorer/group
+++ b/cdist/conf/type/__ssh_dot_ssh/explorer/group
@@ -1,6 +1,7 @@
#!/bin/sh
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -18,5 +19,11 @@
# along with cdist. If not, see .
#
-gid="$("$__type_explorer/passwd" | cut -d':' -f 4)"
-getent group "$gid" || true
+gid=$("$__type_explorer/passwd" | cut -d':' -f4)
+
+if command -v getent >/dev/null
+then
+ getent group "$gid" || true
+else
+ awk -F: "\$3 == \"$gid\" { print }" /etc/group
+fi
diff --git a/cdist/conf/type/__ssh_dot_ssh/explorer/passwd b/cdist/conf/type/__ssh_dot_ssh/explorer/passwd
index 3fbad06f..42686b20 100755
--- a/cdist/conf/type/__ssh_dot_ssh/explorer/passwd
+++ b/cdist/conf/type/__ssh_dot_ssh/explorer/passwd
@@ -2,6 +2,7 @@
#
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
# 2014 Nico Schottelius (nico-cdist at schottelius.org)
+# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch)
#
# This file is part of cdist.
#
@@ -21,4 +22,16 @@
owner="$__object_id"
-getent passwd "$owner" || true
+if command -v getent >/dev/null
+then
+ getent passwd "$owner" || true
+else
+ case $owner in
+ [0-9][0-9]*)
+ awk -F: "\$3 == \"$owner\" { print }" /etc/passwd
+ ;;
+ *)
+ grep "^$owner:" /etc/passwd || true
+ ;;
+ esac
+fi
diff --git a/cdist/conf/type/__start_on_boot/explorer/state b/cdist/conf/type/__start_on_boot/explorer/state
index 19dfc74b..b7a6cf0f 100644
--- a/cdist/conf/type/__start_on_boot/explorer/state
+++ b/cdist/conf/type/__start_on_boot/explorer/state
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# 2012-2015 Nico Schottelius (nico-cdist at schottelius.org)
+# 2012-2019 Nico Schottelius (nico-cdist at schottelius.org)
# 2013 Daniel Heule (hda at sfs.biz)
#
# This file is part of cdist.
@@ -75,9 +75,14 @@ else
state=$(chkconfig --check "$name" "$runlevel" || echo absent)
[ "$state" ] || state="present"
;;
- gentoo)
- state="present"
- [ -f "/etc/runlevels/${target_runlevel}/${name}" ] || state="absent"
+ gentoo|alpine)
+ state="absent"
+ for d in /etc/runlevels/*; do
+ if [ -f "/etc/runlevels/${d}/${name}" ];then
+ state="present"
+ break
+ fi
+ done
;;
freebsd)
state="absent"
@@ -88,6 +93,7 @@ else
# OpenBSD 5.7 and higher
rcctl ls on | grep "^${name}$" && state='present'
;;
+
*)
echo "Unsupported os: $os" >&2
exit 1
diff --git a/cdist/conf/type/__start_on_boot/gencode-remote b/cdist/conf/type/__start_on_boot/gencode-remote
index 1a3b6ff6..c900933f 100755
--- a/cdist/conf/type/__start_on_boot/gencode-remote
+++ b/cdist/conf/type/__start_on_boot/gencode-remote
@@ -58,7 +58,7 @@ case "$state_should" in
echo "update-rc.d '$name' defaults >/dev/null"
;;
- gentoo)
+ alpine|gentoo)
echo "rc-update add '$name' '$target_runlevel'"
;;
@@ -106,7 +106,7 @@ case "$state_should" in
echo "update-rc.d -f '$name' remove"
;;
- gentoo)
+ alpine|gentoo)
echo "rc-update del '$name' '$target_runlevel'"
;;
diff --git a/cdist/conf/type/__start_on_boot/man.rst b/cdist/conf/type/__start_on_boot/man.rst
index 851d1a89..f8afe94b 100644
--- a/cdist/conf/type/__start_on_boot/man.rst
+++ b/cdist/conf/type/__start_on_boot/man.rst
@@ -12,7 +12,7 @@ This cdist type allows you to enable or disable stuff to be started
at boot of your operating system.
Warning: This type has not been tested intensively and is not fully
-supported (i.e. \*BSD are not implemented).
+supported.
REQUIRED PARAMETERS
@@ -55,7 +55,7 @@ Nico Schottelius
COPYING
-------
-Copyright \(C) 2012 Nico Schottelius. You can redistribute it
+Copyright \(C) 2012-2019 Nico Schottelius. 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.
diff --git a/cdist/conf/type/__sysctl/manifest b/cdist/conf/type/__sysctl/manifest
index b4e2e902..71dea7f7 100755
--- a/cdist/conf/type/__sysctl/manifest
+++ b/cdist/conf/type/__sysctl/manifest
@@ -2,6 +2,7 @@
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
# 2018 Takashi Yoshi (takashi at yoshi.email)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -24,7 +25,7 @@ os=$(cat "$__global/explorer/os")
case "$os" in
# Linux
- redhat|centos|ubuntu|debian|devuan|archlinux|coreos)
+ alpine|redhat|centos|ubuntu|debian|devuan|archlinux|coreos)
:
;;
# BSD
diff --git a/cdist/conf/type/__systemd_service/explorer/state b/cdist/conf/type/__systemd_service/explorer/state
new file mode 100755
index 00000000..f5f751d4
--- /dev/null
+++ b/cdist/conf/type/__systemd_service/explorer/state
@@ -0,0 +1,43 @@
+#!/bin/sh -e
+# explorer/state
+#
+# 2020 Matthias Stecher
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+# Check if the service is running or stopped.
+#
+# The explorer must check before if the service exist, because 'systemctl is-active'
+# will return "inactive" even if there is no service there:
+# systemctl cat foo # does not exist
+# systemctl is-active foo # is "inactive"
+
+
+# get name of the service
+if [ -f "$__object/parameter/name" ]; then
+ name="$(cat "$__object/parameter/name")"
+else
+ name="$__object_id"
+fi
+
+
+# check if the service exist, else exit without output (also if systemd doesn't exist)
+# do not exit here with an error code, will be done in the gencode-remote script
+systemctl cat "$name" > /dev/null 2>&1 || exit 0
+
+# print if the service is running or not
+systemctl is-active -q "$name" && printf "running" || printf "stopped"
diff --git a/cdist/conf/type/__systemd_service/gencode-remote b/cdist/conf/type/__systemd_service/gencode-remote
new file mode 100755
index 00000000..c867ff22
--- /dev/null
+++ b/cdist/conf/type/__systemd_service/gencode-remote
@@ -0,0 +1,98 @@
+#!/bin/sh -e
+# gencode-remote
+#
+# 2020 Matthias Stecher
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+
+# Checks the given state of the service and set it to the given
+# state. Optionally, it executes the action if service running.
+
+
+# get name of the service
+name="$__object/parameter/name"
+if [ -f "$name" ]; then
+ name="$(cat "$name")"
+else
+ name="$__object_id"
+fi
+
+
+# read current status and parameters
+state="$(cat "$__object/explorer/state")"
+should="$(cat "$__object/parameter/state")"
+
+# if systemd/service does not exist
+if [ -z "$state" ]; then
+ printf "systemd or service '%s' does not exist!\n" "$name" >&2
+ exit 1
+fi
+
+
+# save the action required
+required_action=""
+
+# check the state of the service that should be
+if [ "$state" != "$should" ]; then
+ # select what to do to get the $should state
+ case "$should" in
+ running)
+ if [ "$state" = "stopped" ]; then required_action="start"; fi
+ ;;
+
+ stopped)
+ if [ "$state" = "running" ]; then required_action="stop"; fi
+ ;;
+ esac
+fi
+
+# check if the action can be achieved if given
+if [ -f "$__object/parameter/action" ] \
+ && [ -z "$required_action" ] && [ "$state" = "running" ]; then
+
+ # there must be an action
+ action="$(cat "$__object/parameter/action")"
+
+ # select the action to the required element
+ case "$action" in
+ restart)
+ required_action="restart"
+ ;;
+
+ reload)
+ required_action="reload"
+ ;;
+
+ *)
+ printf "action '%s' does not exist!" "$action" >&2
+ exit 2
+ esac
+
+ # Make a special check: only do this action if a dependency did something
+ # it is required that the dependencies write there action to $__messages_in
+ if [ -f "$__object/parameter/if-required" ]; then
+ # exit here if there are no changes from the dependencies affected (nothing to do)
+ if ! grep -q -f "$__object/require" "$__messages_in"; then exit 0; fi
+ fi
+fi
+
+# print the execution command if a action given
+if [ -n "$required_action" ]; then
+ # also print it as message
+ echo "$required_action" >> "$__messages_out"
+ echo "systemctl $required_action '$name'"
+fi
diff --git a/cdist/conf/type/__systemd_service/man.rst b/cdist/conf/type/__systemd_service/man.rst
new file mode 100644
index 00000000..7eca398b
--- /dev/null
+++ b/cdist/conf/type/__systemd_service/man.rst
@@ -0,0 +1,110 @@
+cdist-type__systemd-service(7)
+==============================
+
+NAME
+----
+cdist-type__systemd-service - Controls a systemd service state
+
+DESCRIPTION
+-----------
+This type controls systemd services to define a state of the service,
+or an action like reloading or restarting. It is useful to reload a
+service after configuration applied or shutdown one service.
+
+The activation or deactivation is out of scope. Look for the
+:strong:`cdist-type__systemd_util`\ (7) type instead.
+
+REQUIRED PARAMETERS
+-------------------
+
+None.
+
+OPTIONAL PARAMETERS
+-------------------
+
+name
+ String which will used as name instead of the object id.
+
+state
+ The state which the service should be in:
+
+ running
+ Service should run (default)
+
+ stoppend
+ Service should stopped
+
+action
+ Executes an action on on the service. It will only execute it if the
+ service keeps the state **running**. There are following actions, where:
+
+ reload
+ Reloads the service
+
+ restart
+ Restarts the service
+
+BOOLEAN PARAMETERS
+------------------
+
+if-required
+ Only execute the action if minimum one required type outputs a message to
+ **$__messages_out**. Through this, the action should only executed if a
+ dependency did something. The action will not executed if no dependencies
+ given.
+
+MESSAGES
+--------
+
+start
+ Started the service
+
+stop
+ Stopped the service
+
+restart
+ Restarted the service
+
+reload
+ Reloaded the service
+
+ABORTS
+------
+Aborts in following cases:
+
+systemd or the service does not exist
+
+EXAMPLES
+--------
+.. code-block:: sh
+
+ # service must run
+ __systemd_service nginx
+
+ # service must stopped
+ __systemd_service sshd \
+ --state stopped
+
+ # restart the service
+ __systemd_service apache2 \
+ --action restart
+
+ # makes sure the service exist with an alternative name
+ __systemd_service foo \
+ --name sshd
+
+ # reload the service for a modified configuration file
+ # only reloads the service if the file really changed
+ require="__config_file/etc/foo.conf" __systemd_service foo \
+ --action reload --if-required
+
+AUTHORS
+-------
+Matthias Stecher
+
+COPYRIGHT
+---------
+Copyright \(C) 2020 Matthias Stecher. 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.
diff --git a/cdist/conf/type/__systemd_service/parameter/boolean b/cdist/conf/type/__systemd_service/parameter/boolean
new file mode 100644
index 00000000..a4bccb66
--- /dev/null
+++ b/cdist/conf/type/__systemd_service/parameter/boolean
@@ -0,0 +1 @@
+if-required
diff --git a/cdist/conf/type/__systemd_service/parameter/default/state b/cdist/conf/type/__systemd_service/parameter/default/state
new file mode 100644
index 00000000..a2ae71b3
--- /dev/null
+++ b/cdist/conf/type/__systemd_service/parameter/default/state
@@ -0,0 +1 @@
+running
diff --git a/cdist/conf/type/__systemd_service/parameter/optional b/cdist/conf/type/__systemd_service/parameter/optional
new file mode 100644
index 00000000..fc78265f
--- /dev/null
+++ b/cdist/conf/type/__systemd_service/parameter/optional
@@ -0,0 +1,3 @@
+name
+state
+action
diff --git a/cdist/conf/type/__timezone/gencode-remote b/cdist/conf/type/__timezone/gencode-remote
index 1f3f0196..5299f548 100755
--- a/cdist/conf/type/__timezone/gencode-remote
+++ b/cdist/conf/type/__timezone/gencode-remote
@@ -1,6 +1,7 @@
#!/bin/sh -e
#
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -29,7 +30,7 @@ if [ "$timezone_is" = "$timezone_should" ]; then
fi
case "$os" in
- ubuntu|debian|devuan|coreos)
+ ubuntu|debian|devuan|coreos|alpine)
echo "echo \"$timezone_should\" > /etc/timezone"
;;
esac
diff --git a/cdist/conf/type/__timezone/manifest b/cdist/conf/type/__timezone/manifest
index c908f087..3d28ccba 100755
--- a/cdist/conf/type/__timezone/manifest
+++ b/cdist/conf/type/__timezone/manifest
@@ -2,7 +2,7 @@
#
# 2011 Ramon Salvadó (rsalvado at gnuine dot com)
# 2012-2015 Steven Armstrong (steven-cdist at armstrong.cc)
-# 2012 Nico Schottelius (nico-cdist at schottelius.org)
+# 2012-2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -26,7 +26,7 @@ timezone="$__object_id"
os=$(cat "$__global/explorer/os")
case "$os" in
- archlinux|debian|ubuntu|devuan)
+ archlinux|debian|ubuntu|devuan|alpine)
__package tzdata
export require="__package/tzdata"
;;
diff --git a/cdist/conf/type/__tinydns/gencode-remote b/cdist/conf/type/__tinydns/gencode-remote
new file mode 100644
index 00000000..824479b6
--- /dev/null
+++ b/cdist/conf/type/__tinydns/gencode-remote
@@ -0,0 +1,7 @@
+servicename=$__object_id
+user="$(cat "$__object/parameter/user")"
+server_ip="$(cat "$__object/parameter/server-ip")"
+
+cat</dev/null || ./add-host $name $ip
+make
+EOF
diff --git a/cdist/conf/type/__tinydns_host/manifest b/cdist/conf/type/__tinydns_host/manifest
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__tinydns_host/parameter/required b/cdist/conf/type/__tinydns_host/parameter/required
new file mode 100644
index 00000000..93d111b2
--- /dev/null
+++ b/cdist/conf/type/__tinydns_host/parameter/required
@@ -0,0 +1 @@
+ip
diff --git a/cdist/conf/type/__tinydns_ns/gencode-remote b/cdist/conf/type/__tinydns_ns/gencode-remote
new file mode 100644
index 00000000..7305e605
--- /dev/null
+++ b/cdist/conf/type/__tinydns_ns/gencode-remote
@@ -0,0 +1,13 @@
+set -x
+
+servicename=$(echo $__object_id | cut -d/ -f1)
+name=$(echo $__object_id | cut -d/ -f2-)
+ip="$(cat "$__object/parameter/ip")"
+
+cat</dev/null || ./add-ns $name $ip
+make
+EOF
+
+set +x
diff --git a/cdist/conf/type/__tinydns_ns/parameter/required b/cdist/conf/type/__tinydns_ns/parameter/required
new file mode 100644
index 00000000..93d111b2
--- /dev/null
+++ b/cdist/conf/type/__tinydns_ns/parameter/required
@@ -0,0 +1 @@
+ip
diff --git a/cdist/conf/type/__ufw/manifest b/cdist/conf/type/__ufw/manifest
index 54309ff5..370b7ff5 100755
--- a/cdist/conf/type/__ufw/manifest
+++ b/cdist/conf/type/__ufw/manifest
@@ -31,7 +31,7 @@ case "$state" in
__package epel-release
require='__package/epel-release' __package ufw
else
- echo 'CentOS version 7 is required!'
+ echo 'CentOS version 7 is required!' >&2
exit 1
fi
;;
diff --git a/cdist/conf/type/__update_alternatives/explorer/state b/cdist/conf/type/__update_alternatives/explorer/state
new file mode 100755
index 00000000..04a78aaa
--- /dev/null
+++ b/cdist/conf/type/__update_alternatives/explorer/state
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+path="$(cat "$__object/parameter/path")"
+name="$__object_id"
+link="$(readlink "/etc/alternatives/$name")"
+if [ "$path" = "$link" ]
+then echo present
+else echo absent
+fi
diff --git a/cdist/conf/type/__update_alternatives/gencode-remote b/cdist/conf/type/__update_alternatives/gencode-remote
index 0e7b0d89..c0b49814 100755
--- a/cdist/conf/type/__update_alternatives/gencode-remote
+++ b/cdist/conf/type/__update_alternatives/gencode-remote
@@ -17,9 +17,10 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see .
#
-#
-# Setup alternative - no standard way to create, always set
-#
+
+if [ "$(cat "$__object/explorer/state")" = 'present' ]
+then exit 0
+fi
path="$(cat "$__object/parameter/path")"
name="$__object_id"
diff --git a/cdist/conf/type/__user/explorer/group b/cdist/conf/type/__user/explorer/group
index 2aae2973..0fd1471a 100755
--- a/cdist/conf/type/__user/explorer/group
+++ b/cdist/conf/type/__user/explorer/group
@@ -23,11 +23,9 @@
if [ -f "$__object/parameter/gid" ]; then
gid=$(cat "$__object/parameter/gid")
- getent=$(command -v getent)
- if [ X != X"${getent}" ]; then
- "${getent}" group "$gid" || true
+ if command -v getent >/dev/null; then
+ getent group "$gid" || true
elif [ -f /etc/group ]; then
grep -E "^(${gid}|([^:]+:){2}${gid}):" /etc/group || true
fi
fi
-
diff --git a/cdist/conf/type/__user/explorer/passwd b/cdist/conf/type/__user/explorer/passwd
index 677e3ff0..b8391a6f 100755
--- a/cdist/conf/type/__user/explorer/passwd
+++ b/cdist/conf/type/__user/explorer/passwd
@@ -23,9 +23,8 @@
name=$__object_id
-getent=$(command -v getent)
-if [ X != X"${getent}" ]; then
- "${getent}" passwd "$name" || true
+if command -v getent >/dev/null; then
+ getent passwd "$name" || true
elif [ -f /etc/passwd ]; then
grep "^${name}:" /etc/passwd || true
fi
diff --git a/cdist/conf/type/__user/explorer/shadow b/cdist/conf/type/__user/explorer/shadow
index c49992d5..63d38f0d 100755
--- a/cdist/conf/type/__user/explorer/shadow
+++ b/cdist/conf/type/__user/explorer/shadow
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/sh -e
#
# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
#
@@ -22,18 +22,19 @@
#
name=$__object_id
-os="$("$__explorer/os")"
-# Default to using shadow passwords
-database="shadow"
-case "$os" in
- "freebsd"|"netbsd"|"openbsd") database="passwd";;
+case $("$__explorer/os") in
+ 'freebsd'|'netbsd'|'openbsd'|'alpine')
+ database='passwd'
+ ;;
+ # Default to using shadow passwords
+ *)
+ database='shadow'
+ ;;
esac
-
-getent=$(command -v getent)
-if [ X != X"${getent}" ]; then
- "${getent}" "$database" "$name" || true
+if command -v getent >/dev/null; then
+ getent "$database" "$name" || true
elif [ -f /etc/shadow ]; then
grep "^${name}:" /etc/shadow || true
fi
diff --git a/cdist/conf/type/__hostname/explorer/hostname_sysconfig b/cdist/conf/type/__user/manifest
old mode 100755
new mode 100644
similarity index 75%
rename from cdist/conf/type/__hostname/explorer/hostname_sysconfig
rename to cdist/conf/type/__user/manifest
index d0d7b4e7..8f10b38c
--- a/cdist/conf/type/__hostname/explorer/hostname_sysconfig
+++ b/cdist/conf/type/__user/manifest
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/sh -e
#
-# 2014 Nico Schottelius (nico-cdist at schottelius.org)
+# 2019 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@@ -18,9 +18,15 @@
# along with cdist. If not, see .
#
#
-# Retrieve the contents of /etc/hostname
-#
+# Manage users.
-if [ -f /etc/sysconfig/network ]; then
- awk -F= '/^HOSTNAME=/ { print $2 }' /etc/sysconfig/network
-fi
+os=$(cat "$__global/explorer/os")
+
+case "$os" in
+ alpine)
+ __package shadow
+ ;;
+ *)
+ :
+ ;;
+esac
diff --git a/cdist/conf/type/__xymon_apache/explorer/active-conf b/cdist/conf/type/__xymon_apache/explorer/active-conf
new file mode 100755
index 00000000..bd281e21
--- /dev/null
+++ b/cdist/conf/type/__xymon_apache/explorer/active-conf
@@ -0,0 +1,22 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+if [ -d /etc/apache2/mods-enabled ]; then
+ ls -1 /etc/apache2/conf-enabled/
+fi
diff --git a/cdist/conf/type/__xymon_apache/explorer/active-modules b/cdist/conf/type/__xymon_apache/explorer/active-modules
new file mode 100755
index 00000000..4c745ced
--- /dev/null
+++ b/cdist/conf/type/__xymon_apache/explorer/active-modules
@@ -0,0 +1,5 @@
+#!/bin/sh -e
+
+if [ -d /etc/apache2/mods-enabled ]; then
+ /usr/sbin/apachectl -t -D DUMP_MODULES | awk '/.*_module/ { gsub(/_module.*$/, ""); gsub(/^ /, ""); print }'
+fi
diff --git a/cdist/conf/type/__xymon_apache/gencode-remote b/cdist/conf/type/__xymon_apache/gencode-remote
new file mode 100755
index 00000000..e7d8e344
--- /dev/null
+++ b/cdist/conf/type/__xymon_apache/gencode-remote
@@ -0,0 +1,56 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+state=$(cat "$__object/parameter/state")
+
+os=$(cat "$__global/explorer/os")
+case "$os" in
+ debian|ubuntu)
+ :
+ ;;
+ *)
+ echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+esac
+
+if [ "$state" = "present" ]; then
+ if ! grep -q ^rewrite "$__object/explorer/active-modules"; then
+ echo "a2enmod rewrite >/dev/null"
+ echo "mod:rewrite enabled" >> "$__messages_out"
+ fi
+ if ! grep -q "^cgi$" "$__object/explorer/active-modules"; then
+ echo "a2enmod cgi >/dev/null"
+ echo "mod:cgi enabled" >> "$__messages_out"
+ fi
+
+ if ! grep -q ^xymon.conf "$__object/explorer/active-conf"; then
+ echo "a2enconf xymon >/dev/null"
+ echo "conf:xymon enabled" >> "$__messages_out"
+ fi
+fi
+
+if grep -q "^mod:.* enabled" "$__messages_out"; then
+ echo "systemctl restart apache2.service"
+ echo "apache restarted" >> "$__messages_out"
+elif grep -q "^conf:xymon enabled" "$__messages_out"; then
+ echo "systemctl reload apache2.service"
+ echo "apache reloaded" >> "$__messages_out"
+fi
diff --git a/cdist/conf/type/__xymon_apache/man.rst b/cdist/conf/type/__xymon_apache/man.rst
new file mode 100644
index 00000000..8358c821
--- /dev/null
+++ b/cdist/conf/type/__xymon_apache/man.rst
@@ -0,0 +1,79 @@
+cdist-type__xymon_apache(7)
+===========================
+
+NAME
+----
+cdist-type__xymon_apache - Configure apache2-webserver for Xymon
+
+
+DESCRIPTION
+-----------
+This cdist type installs and configures apache2 to be used "exclusively" (in
+the sense that no other use is taken care of) with Xymon (the systems and
+network monitor).
+
+It depends on `__xymon_server`.
+
+
+REQUIRED PARAMETERS
+-------------------
+None.
+
+
+OPTIONAL PARAMETERS
+-------------------
+state
+ 'present', 'absent', defaults to 'present'.
+
+ipacl
+ IP(-ranges) that have access to the Xymon webpages and CGIs. Apache2-style
+ syntax suitable for `Require ip ...`. Example: `192.168.1.0/24 10.0.0.0/8`
+
+
+MESSAGES
+--------
+mod:rewrite enabled
+ apache module enabled
+conf:xymon enabled
+ apache config for xymon enabled
+apache restarted
+ apache2.service was reloaded
+apache reloaded
+ apache2.service was restarted
+
+
+EXPLORERS
+---------
+active-conf
+ lists apache2 `conf-enabled`
+active-modules
+ lists active apache2-modules
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # minmal, only localhost-access:
+ __xymon_apache
+ # allow more IPs to access the Xymon-webinterface:
+ __xymon_apache --ipacl "192.168.0.0/16 10.0.0.0/8" --state "present"
+
+
+SEE ALSO
+--------
+:strong:`cdist__xymon_server`\ (7)
+
+
+AUTHORS
+-------
+Thomas Eckert
+
+
+COPYING
+-------
+Copyright \(C) 2018-2019 Thomas Eckert. 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.
diff --git a/cdist/conf/type/__pf_ruleset/gencode-remote b/cdist/conf/type/__xymon_apache/manifest
similarity index 53%
rename from cdist/conf/type/__pf_ruleset/gencode-remote
rename to cdist/conf/type/__xymon_apache/manifest
index 12760fdf..bfd0af79 100755
--- a/cdist/conf/type/__pf_ruleset/gencode-remote
+++ b/cdist/conf/type/__xymon_apache/manifest
@@ -1,6 +1,6 @@
#!/bin/sh -e
#
-# 2012 Jake Guffey (jake.guffey at eprotex.com)
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
#
# This file is part of cdist.
#
@@ -16,34 +16,27 @@
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see .
-#
-#
-# Manage pf(4) on *BSD
-#
-
-# Debug
-#exec >&2
-#set -x
-
-# Remove ${rcvar} in the case of --state absent
state=$(cat "$__object/parameter/state")
-rcvar=$(cat "$__object/explorer/rcvar")
-if [ "$state" = "present" ]; then # There is nothing more for a *remote* script to do
- exit 0
-elif [ "$state" = "absent" ]; then
- # --state absent, so ensure that .new doesn't exist and that conf is renamed to .old
- cat <&2
- exit 1
+os=$(cat "$__global/explorer/os")
+case "$os" in
+ debian|ubuntu)
+ :
+ ;;
+ *)
+ echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+esac
+
+__package apache2 --state "$state"
+
+## edit xymon.conf IP-ranges
+if [ -f "$__object/parameter/ipacl" ]; then
+ require="__package/xymon" __line /etc/apache2/conf-available/xymon.conf \
+ --line " Require ip $(cat "$__object/parameter/ipacl")" \
+ --after "^[[:space:]]*Require local" \
+ --state "present"
fi
-
diff --git a/cdist/conf/type/__xymon_apache/parameter/default/state b/cdist/conf/type/__xymon_apache/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__xymon_apache/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__xymon_apache/parameter/optional b/cdist/conf/type/__xymon_apache/parameter/optional
new file mode 100644
index 00000000..d374ec41
--- /dev/null
+++ b/cdist/conf/type/__xymon_apache/parameter/optional
@@ -0,0 +1,2 @@
+state
+ipacl
diff --git a/cdist/conf/type/__xymon_apache/singleton b/cdist/conf/type/__xymon_apache/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__xymon_client/gencode-remote b/cdist/conf/type/__xymon_client/gencode-remote
new file mode 100755
index 00000000..49eed317
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/gencode-remote
@@ -0,0 +1,28 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+servers=$(cat "$__object/parameter/servers")
+
+if grep -q ^__key_value/CLIENTHOSTNAME "$__messages_in" || grep -q ^__key_value/XYMONSERVERS "$__messages_in" ; then
+ echo "systemctl restart xymon-client"
+ echo "restarted" >> "$__messages_out"
+ cat <<-EOT
+ echo "xymon-client xymon-client/XYMONSERVERS string $servers" | debconf-set-selections
+ EOT
+fi
diff --git a/cdist/conf/type/__xymon_client/man.rst b/cdist/conf/type/__xymon_client/man.rst
new file mode 100644
index 00000000..05d085dc
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/man.rst
@@ -0,0 +1,66 @@
+cdist-type__xymon_client(7)
+===========================
+
+NAME
+----
+cdist-type__xymon_client - Install the Xymon client
+
+
+DESCRIPTION
+-----------
+This cdist type installs the Xymon client and configures it to report with
+FQDN.
+
+
+REQUIRED PARAMETERS
+-------------------
+None.
+
+
+OPTIONAL PARAMETERS
+-------------------
+state
+ 'present', 'absent', defaults to 'present'.
+
+servers
+ One or more IP addresses (space separated) of the Xymon server(s) to report
+ to. While DNS-names are ok it is discouraged, defaults to 127.0.0.1.
+
+
+BOOLEAN PARAMETERS
+------------------
+msgcache
+ Enable xymon `msgcache`. Note: XYMONSERVER has to be `127.0.0.1` for using
+ `msgcache` (see `msgcache (8)` of the xymon documentation for details).
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # minimal, report to 127.0.0.1
+ __xymon_client
+
+ # specify server:
+ __xymon_client --servers "192.168.1.1"
+
+ # activate `msgcache` for passive client:
+ __xymon_client --msgcache
+
+
+SEE ALSO
+--------
+:strong:`cdist__xymon_server`\ (7), :strong:`xymon`\ (7), :strong:`msgcache`\ (8)
+
+
+AUTHORS
+-------
+Thomas Eckert
+
+
+COPYING
+-------
+Copyright \(C) 2018-2019 Thomas Eckert. 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.
diff --git a/cdist/conf/type/__xymon_client/manifest b/cdist/conf/type/__xymon_client/manifest
new file mode 100755
index 00000000..88293a12
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/manifest
@@ -0,0 +1,54 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+state=$(cat "$__object/parameter/state")
+servers=$(cat "$__object/parameter/servers")
+
+os=$(cat "$__global/explorer/os")
+case "$os" in
+ debian|ubuntu)
+ :
+ ;;
+ *)
+ echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+esac
+
+__package xymon-client --state "$state"
+
+if [ -f "$__object/parameter/msgcache" ]; then
+ require="__package/xymon-client" __line /etc/xymon/clientlaunch.cfg \
+ --regex DISABLED --state absent
+fi
+
+require="__package/xymon-client" __key_value CLIENTHOSTNAME \
+ --file /etc/default/xymon-client \
+ --value "'$__target_hostname'" \
+ --delimiter '=' \
+ --state "$state"
+require="__package/xymon-client" __key_value XYMONSERVERS \
+ --file /etc/default/xymon-client \
+ --value "'$servers'" \
+ --delimiter '=' \
+ --state "$state"
+
+## CLI-usage often requires a shell:
+require="__package/xymon-client" __user xymon --shell "/bin/bash" --state "$state"
diff --git a/cdist/conf/type/__xymon_client/parameter/boolean b/cdist/conf/type/__xymon_client/parameter/boolean
new file mode 100644
index 00000000..0dd7839d
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/parameter/boolean
@@ -0,0 +1 @@
+msgcache
diff --git a/cdist/conf/type/__xymon_client/parameter/default/servers b/cdist/conf/type/__xymon_client/parameter/default/servers
new file mode 100644
index 00000000..7b9ad531
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/parameter/default/servers
@@ -0,0 +1 @@
+127.0.0.1
diff --git a/cdist/conf/type/__xymon_client/parameter/default/state b/cdist/conf/type/__xymon_client/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__xymon_client/parameter/optional b/cdist/conf/type/__xymon_client/parameter/optional
new file mode 100644
index 00000000..7c34489a
--- /dev/null
+++ b/cdist/conf/type/__xymon_client/parameter/optional
@@ -0,0 +1,2 @@
+state
+servers
diff --git a/cdist/conf/type/__xymon_client/singleton b/cdist/conf/type/__xymon_client/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__xymon_config/files/.keep b/cdist/conf/type/__xymon_config/files/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__xymon_config/gencode-remote b/cdist/conf/type/__xymon_config/gencode-remote
new file mode 100644
index 00000000..b25a0fda
--- /dev/null
+++ b/cdist/conf/type/__xymon_config/gencode-remote
@@ -0,0 +1,23 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+## to speed up config-reload we send a HUP to the server process:
+cat <<-EOT
+ pkill -HUP xymond || { echo "HUPing xymond failed" >&2; exit 1; }
+EOT
diff --git a/cdist/conf/type/__xymon_config/man.rst b/cdist/conf/type/__xymon_config/man.rst
new file mode 100644
index 00000000..8adfbe1f
--- /dev/null
+++ b/cdist/conf/type/__xymon_config/man.rst
@@ -0,0 +1,78 @@
+cdist-type__xymon_config(7)
+===========================
+
+NAME
+----
+cdist-type__xymon_config - Deploy a Xymon configuration-directory
+
+
+DESCRIPTION
+-----------
+This cdist type deploys a full Xymon configuration directory from the files-dir
+to the host. This type requires an installed Xymon server, e.g. deployed by
+`__xymon_server`.
+
+WARNING: This type _replaces_ the `/etc/xymon/`-directory! The previous
+contents is replaced/deleted!
+
+
+REQUIRED PARAMETERS
+-------------------
+confdir
+ The directory in `./files/` that contains the `/etc/xymon/`-content to be
+ deployed.
+
+
+OPTIONAL PARAMETERS
+-------------------
+owner
+ passed as-is as `--owner` to `__rsync`
+
+group
+ passed as-is as `--group` to `__rsync`
+
+
+OPTIONAL MULTIPLE PARAMETERS
+----------------------------
+rsync-opts
+ identical to __rsync type, only `--`-options are supported
+
+
+REQUIRED FILES
+--------------
+The directory specified by `confdir` has to contain a valid xymon-configuration
+(`/etc/xymon/`) _plus_ the `ext/`-directory that normally resides in
+`/usr/lib/xymon/server/`.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ __xymon_config --confdir=xymon.example.com
+ # this will replace /etc/xymon/ on the target host with
+ # the contents from __xymon_config/files/xymon.example.com/
+
+ ## the same but set ownership to `xymon:xymon` and exclude
+ ## the `netrc`-file:
+ __xymon_config --confdir=xymon.example.com \
+ --owner xymon --group xymon \
+ --rsync-opts "exclude=netrc"
+
+
+SEE ALSO
+--------
+:strong:`cdist__xymon_server`\ (7), :strong:`cdist__rsync`\ (7), :strong:`xymon`\ (7)
+
+AUTHORS
+-------
+Thomas Eckert
+
+
+COPYING
+-------
+Copyright \(C) 2018-2019 Thomas Eckert. 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.
diff --git a/cdist/conf/type/__xymon_config/manifest b/cdist/conf/type/__xymon_config/manifest
new file mode 100644
index 00000000..4a5fb6c9
--- /dev/null
+++ b/cdist/conf/type/__xymon_config/manifest
@@ -0,0 +1,43 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+confdir=$(cat "$__object/parameter/confdir")
+set --
+if [ -f "$__object/parameter/owner" ]; then
+ owner=$(cat "$__object/parameter/owner")
+ set -- "$@" "--owner $owner"
+fi
+if [ -f "$__object/parameter/group" ]; then
+ group=$(cat "$__object/parameter/group")
+ set -- "$@" "--group $group"
+fi
+
+## pass `--rsync-opts` as-is to `__rsync`:
+if [ -f "$__object/parameter/rsync-opts" ]; then
+ while read -r opts; do
+ # shellcheck disable=SC2089
+ set -- "$@" "--rsync-opts '$opts'"
+ done < "$__object/parameter/rsync-opts"
+fi
+
+# shellcheck disable=SC2068,SC2090
+__rsync /etc/xymon/ \
+ --source "$__type/files/$confdir/" \
+ --rsync-opts "delete" \
+ $@
diff --git a/cdist/conf/type/__xymon_config/parameter/optional b/cdist/conf/type/__xymon_config/parameter/optional
new file mode 100644
index 00000000..866b4bde
--- /dev/null
+++ b/cdist/conf/type/__xymon_config/parameter/optional
@@ -0,0 +1,2 @@
+owner
+group
diff --git a/cdist/conf/type/__xymon_config/parameter/optional_multiple b/cdist/conf/type/__xymon_config/parameter/optional_multiple
new file mode 100644
index 00000000..fdb7cd88
--- /dev/null
+++ b/cdist/conf/type/__xymon_config/parameter/optional_multiple
@@ -0,0 +1 @@
+rsync-opts
diff --git a/cdist/conf/type/__xymon_config/parameter/required b/cdist/conf/type/__xymon_config/parameter/required
new file mode 100644
index 00000000..43222f13
--- /dev/null
+++ b/cdist/conf/type/__xymon_config/parameter/required
@@ -0,0 +1 @@
+confdir
diff --git a/cdist/conf/type/__xymon_config/singleton b/cdist/conf/type/__xymon_config/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__xymon_server/gencode-remote b/cdist/conf/type/__xymon_server/gencode-remote
new file mode 100755
index 00000000..0770e319
--- /dev/null
+++ b/cdist/conf/type/__xymon_server/gencode-remote
@@ -0,0 +1,26 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+## "move" user-modified dirs to /etc/xymon to be managed by __xymon_config:
+cat <<-EOT
+ if [ ! -L /usr/lib/xymon/server/ext ]; then
+ mv /usr/lib/xymon/server/ext /etc/xymon
+ ln -s /etc/xymon/ext /usr/lib/xymon/server/
+ fi
+EOT
diff --git a/cdist/conf/type/__xymon_server/man.rst b/cdist/conf/type/__xymon_server/man.rst
new file mode 100644
index 00000000..a9a180e1
--- /dev/null
+++ b/cdist/conf/type/__xymon_server/man.rst
@@ -0,0 +1,87 @@
+cdist-type__xymon_server(7)
+===========================
+
+NAME
+----
+cdist-type__xymon_server - Install a Xymon server
+
+
+DESCRIPTION
+-----------
+This cdist type installs a Xymon (https://www.xymon.com/) server and (optional)
+required helper packages.
+
+This includes the Xymon client as a dependency, so NO NEED to install
+`__xymon_client` separately.
+
+To access the webinterface a webserver is required. The cdist-type
+`__xymon_apache` can be used to install and configure the apache webserver for
+the use with Xymon.
+
+Further and day-to-day configuration of Xymon can either be done manually in
+`/etc/xymon/` or the directory can be deployed and managed by `__xymon_config`.
+
+
+REQUIRED PARAMETERS
+-------------------
+None.
+
+
+OPTIONAL PARAMETERS
+-------------------
+state
+ 'present', 'absent', defaults to 'present'. If '--install_helpers' is
+ specified for 'absent' the helper packages will be un-installed.
+
+
+BOOLEAN PARAMETERS
+------------------
+install_helpers
+ Install helper packages used by Xymon (fping, heirloom-mailx, traceroute,
+ ntpdate).
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # minmal
+ __xymon_server
+
+ # the same
+ __xymon_server --state present
+
+ # also install helper packages:
+ __xymon_server --install_helpers
+
+ # examples to give a more complete picture: __xymon_server installed on
+ # `xymon.example.com` w/ IP 192.168.1.1:
+ #
+ # install webserver and grant 2 private subnets access to the webinterface:
+ __xymon_apache --ipacl "192.168.0.0/16 10.0.0.0/8"
+ # deploy server-configuration with __xymon_config:
+ __xymon_config --confdir=xymon.example.com
+
+ # install xymon-client on other machines (not needed on the server):
+ __xymon_client --servers "192.168.1.1"
+
+
+
+SEE ALSO
+--------
+:strong:`cdist__xymon_apache`\ (7), :strong:`cdist__xymon_config`\ (7),
+:strong:`cdist__xymon_client`\ (7), :strong:`xymon`\ (7)
+
+
+AUTHORS
+-------
+Thomas Eckert
+
+
+COPYING
+-------
+Copyright \(C) 2018-2019 Thomas Eckert. 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.
diff --git a/cdist/conf/type/__xymon_server/manifest b/cdist/conf/type/__xymon_server/manifest
new file mode 100755
index 00000000..7cee0d23
--- /dev/null
+++ b/cdist/conf/type/__xymon_server/manifest
@@ -0,0 +1,50 @@
+#!/bin/sh -e
+#
+# 2018-2019 Thomas Eckert (tom at it-eckert.de)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+
+state=$(cat "$__object/parameter/state")
+if [ -f "$__object/parameter/install_helpers" ]; then
+ install_helpers=1
+else
+ install_helpers=0
+fi
+
+os=$(cat "$__global/explorer/os")
+case "$os" in
+ debian|ubuntu)
+ :
+ ;;
+ *)
+ echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+esac
+
+__package xymon --state "$state"
+
+## install helper-packages/tools used by the xymon server if requested:
+if [ "$install_helpers" = "1" ]; then
+ __package fping --state "$state"
+ __package heirloom-mailx --state "$state"
+ __package traceroute --state "$state"
+ __package ntpdate --state "$state"
+fi
+
+## CLI-usage often requires a shell:
+require="__package/xymon" __user xymon --shell "/bin/bash" --state "$state"
diff --git a/cdist/conf/type/__xymon_server/parameter/boolean b/cdist/conf/type/__xymon_server/parameter/boolean
new file mode 100644
index 00000000..56ebcb2c
--- /dev/null
+++ b/cdist/conf/type/__xymon_server/parameter/boolean
@@ -0,0 +1 @@
+install_helpers
diff --git a/cdist/conf/type/__xymon_server/parameter/default/state b/cdist/conf/type/__xymon_server/parameter/default/state
new file mode 100644
index 00000000..e7f6134f
--- /dev/null
+++ b/cdist/conf/type/__xymon_server/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/cdist/conf/type/__xymon_server/parameter/optional b/cdist/conf/type/__xymon_server/parameter/optional
new file mode 100644
index 00000000..ff72b5c7
--- /dev/null
+++ b/cdist/conf/type/__xymon_server/parameter/optional
@@ -0,0 +1 @@
+state
diff --git a/cdist/conf/type/__xymon_server/singleton b/cdist/conf/type/__xymon_server/singleton
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/conf/type/__zypper_service/man.rst b/cdist/conf/type/__zypper_service/man.rst
index ea48aebb..e082dc02 100644
--- a/cdist/conf/type/__zypper_service/man.rst
+++ b/cdist/conf/type/__zypper_service/man.rst
@@ -46,10 +46,10 @@ EXAMPLES
# Ensure that internal SLES11 SP3 RIS is in installed and all other services and repos are discarded
__zypper_service INTERNAL_SLES11_SP3 --service_desc "Internal SLES11 SP3 RIS" --uri "http://path/to/your/ris/dir" --remove-all-other-services --remove-all-repos
- # Ensure that internal SLES11 SP3 RIS is in installed, no changes to ohter services or repos
+ # Ensure that internal SLES11 SP3 RIS is in installed, no changes to other services or repos
__zypper_service INTERNAL_SLES11_SP3 --service_desc "Internal SLES11 SP3 RIS" --uri "http://path/to/your/ris/dir"
- # Drop service by uri, no changes to ohter services or repos
+ # Drop service by uri, no changes to other services or repos
__zypper_service INTERNAL_SLES11_SP3 --state absent --uri "http://path/to/your/ris/dir"
diff --git a/cdist/config.py b/cdist/config.py
index 11c433db..97cc1da6 100644
--- a/cdist/config.py
+++ b/cdist/config.py
@@ -43,6 +43,33 @@ from cdist import core, inventory
from cdist.util.remoteutil import inspect_ssh_mux_opts
+def graph_check_cycle(graph):
+ # Start from each node in the graph and check for cycle starting from it.
+ for node in graph:
+ # Cycle path.
+ path = [node]
+ has_cycle = _graph_dfs_cycle(graph, node, path)
+ if has_cycle:
+ return has_cycle, path
+ return False, None
+
+
+def _graph_dfs_cycle(graph, node, path):
+ for neighbour in graph.get(node, ()):
+ # If node is already in path then this is cycle.
+ if neighbour in path:
+ path.append(neighbour)
+ return True
+ path.append(neighbour)
+ rv = _graph_dfs_cycle(graph, neighbour, path)
+ if rv:
+ return True
+ # Remove last item from list - neighbour whose DFS path we have have
+ # just checked.
+ del path[-1]
+ return False
+
+
class Config(object):
"""Cdist main class to hold arbitrary data"""
@@ -77,9 +104,12 @@ class Config(object):
self.remove_remote_files_dirs = remove_remote_files_dirs
self.explorer = core.Explorer(self.local.target_host, self.local,
- self.remote, jobs=self.jobs)
- self.manifest = core.Manifest(self.local.target_host, self.local)
- self.code = core.Code(self.local.target_host, self.local, self.remote)
+ self.remote, jobs=self.jobs,
+ dry_run=self.dry_run)
+ self.manifest = core.Manifest(self.local.target_host, self.local,
+ dry_run=self.dry_run)
+ self.code = core.Code(self.local.target_host, self.local, self.remote,
+ dry_run=self.dry_run)
def _init_files_dirs(self):
"""Prepare files and directories for the run"""
@@ -94,6 +124,7 @@ class Config(object):
"""Remove files and directories for the run"""
if self.remove_remote_files_dirs:
self._remove_remote_files_dirs()
+ self.manifest.cleanup()
@staticmethod
def hosts(source):
@@ -254,14 +285,14 @@ class Config(object):
cls.onehost(host, host_tags, host_base_path, hostdir,
args, parallel=False,
configuration=configuration)
- except cdist.Error as e:
+ except cdist.Error:
failed_hosts.append(host)
if args.parallel and len(process_args) == 1:
log.debug("Only 1 host for parallel processing, doing it "
"sequentially")
try:
cls.onehost(*process_args[0])
- except cdist.Error as e:
+ except cdist.Error:
failed_hosts.append(host)
elif args.parallel:
log.trace("Multiprocessing start method is {}".format(
@@ -338,7 +369,7 @@ class Config(object):
def resolve_target_addresses(host, family):
try:
return ipaddr.resolve_target_addresses(host, family)
- except:
+ except: # noqa
e = sys.exc_info()[1]
raise cdist.Error(("Error resolving target addresses for host '{}'"
": {}").format(host, e))
@@ -653,6 +684,28 @@ class Config(object):
self.__dict__.update(state)
self._open_logger()
+ def _validate_dependencies(self):
+ '''
+ Build dependency graph for unfinished objects and
+ check for cycles.
+ '''
+ graph = {}
+ for cdist_object in self.object_list():
+ obj_name = cdist_object.name
+ if obj_name not in graph:
+ graph[obj_name] = []
+ if cdist_object.state == cdist_object.STATE_DONE:
+ continue
+
+ for requirement in cdist_object.requirements_unfinished(
+ cdist_object.requirements):
+ graph[obj_name].append(requirement.name)
+
+ for requirement in cdist_object.requirements_unfinished(
+ cdist_object.autorequire):
+ graph[obj_name].append(requirement.name)
+ return graph_check_cycle(graph)
+
def iterate_until_finished(self):
"""
Go through all objects and solve them
@@ -662,6 +715,12 @@ class Config(object):
objects_changed = True
while objects_changed:
+ # Check for cycles as early as possible.
+ has_cycle, path = self._validate_dependencies()
+ if has_cycle:
+ raise cdist.UnresolvableRequirementsError(
+ "Cycle detected in object dependencies:\n{}!".format(
+ " -> ".join(path)))
objects_changed = self.iterate_once()
# Check whether all objects have been finished
@@ -700,15 +759,38 @@ class Config(object):
("The requirements of the following objects could not be "
"resolved:\n%s") % ("\n".join(info_string)))
+ def _handle_deprecation(self, cdist_object):
+ cdist_type = cdist_object.cdist_type
+ deprecated = cdist_type.deprecated
+ if deprecated is not None:
+ if deprecated:
+ self.log.warning("Type %s is deprecated: %s", cdist_type.name,
+ deprecated)
+ else:
+ self.log.warning("Type %s is deprecated.", cdist_type.name)
+ for param in cdist_object.parameters:
+ if param in cdist_type.deprecated_parameters:
+ msg = cdist_type.deprecated_parameters[param]
+ if msg:
+ format = "%s parameter of type %s is deprecated: %s"
+ args = [param, cdist_type.name, msg]
+ else:
+ format = "%s parameter of type %s is deprecated."
+ args = [param, cdist_type.name]
+ self.log.warning(format, *args)
+
def object_prepare(self, cdist_object, transfer_type_explorers=True):
"""Prepare object: Run type explorer + manifest"""
+ self._handle_deprecation(cdist_object)
+ self.log.verbose("Preparing object {}".format(cdist_object.name))
+ self.log.verbose(
+ "Running manifest and explorers for " + cdist_object.name)
+ self.explorer.run_type_explorers(cdist_object, transfer_type_explorers)
try:
- self.log.verbose("Preparing object {}".format(cdist_object.name))
- self.log.verbose(
- "Running manifest and explorers for " + cdist_object.name)
- self.explorer.run_type_explorers(cdist_object,
- transfer_type_explorers)
self.manifest.run_type_manifest(cdist_object)
+ self.log.trace("[ORDER_DEP] Removing order dep files for %s",
+ cdist_object)
+ cdist_object.cleanup()
cdist_object.state = core.CdistObject.STATE_PREPARED
except cdist.Error as e:
raise cdist.CdistObjectError(cdist_object, e)
diff --git a/cdist/configuration.py b/cdist/configuration.py
index f05a5963..1011a382 100644
--- a/cdist/configuration.py
+++ b/cdist/configuration.py
@@ -274,7 +274,8 @@ class Configuration(metaclass=Singleton):
os.path.isfile(_local_config_file))):
_local_config_file = os.path.join(
os.environ.get('XDG_CONFIG_HOME',
- os.path.expanduser('~/.config/cdist')),
+ os.path.expanduser('~/.config/')),
+ 'cdist',
_config_basename)
_dist_config_file = os.path.join(
os.path.abspath(os.path.join(os.path.dirname(cdist.__file__), "conf")),
diff --git a/cdist/core/cdist_object.py b/cdist/core/cdist_object.py
index 237f0ddd..114a47e0 100644
--- a/cdist/core/cdist_object.py
+++ b/cdist/core/cdist_object.py
@@ -243,6 +243,16 @@ class CdistObject(object):
lambda obj: os.path.join(obj.base_path, obj.code_local_path))
code_remote = fsproperty.FileStringProperty(
lambda obj: os.path.join(obj.base_path, obj.code_remote_path))
+ typeorder = fsproperty.FileListProperty(
+ lambda obj: os.path.join(obj.absolute_path, 'typeorder'))
+ typeorder_dep = fsproperty.FileListProperty(
+ lambda obj: os.path.join(obj.absolute_path, 'typeorder_dep'))
+
+ def cleanup(self):
+ try:
+ os.remove(os.path.join(self.absolute_path, 'typeorder_dep'))
+ except FileNotFoundError:
+ pass
@property
def exists(self):
diff --git a/cdist/core/cdist_type.py b/cdist/core/cdist_type.py
index 99e40e70..4500f50d 100644
--- a/cdist/core/cdist_type.py
+++ b/cdist/core/cdist_type.py
@@ -69,6 +69,7 @@ class CdistType(object):
self.__optional_multiple_parameters = None
self.__boolean_parameters = None
self.__parameter_defaults = None
+ self.__deprecated_parameters = None
def __hash__(self):
return hash(self.name)
@@ -133,6 +134,17 @@ class CdistType(object):
cannot run in parallel."""
return os.path.isfile(os.path.join(self.absolute_path, "nonparallel"))
+ @property
+ def deprecated(self):
+ """Get type deprecation message. If message is None then type
+ is not deprecated."""
+ deprecated_path = os.path.join(self.absolute_path, "deprecated")
+ try:
+ with open(deprecated_path, 'r') as f:
+ return f.read()
+ except FileNotFoundError:
+ return None
+
@property
def explorers(self):
"""Return a list of available explorers"""
@@ -264,3 +276,23 @@ class CdistType(object):
finally:
self.__parameter_defaults = defaults
return self.__parameter_defaults
+
+ @property
+ def deprecated_parameters(self):
+ if not self.__deprecated_parameters:
+ deprecated = {}
+ try:
+ deprecated_dir = os.path.join(self.absolute_path,
+ "parameter",
+ "deprecated")
+ for name in cdist.core.listdir(deprecated_dir):
+ try:
+ with open(os.path.join(deprecated_dir, name)) as fd:
+ deprecated[name] = fd.read().strip()
+ except EnvironmentError:
+ pass # Swallow errors raised by open() or read()
+ except EnvironmentError:
+ pass # Swallow error raised by os.listdir()
+ finally:
+ self.__deprecated_parameters = deprecated
+ return self.__deprecated_parameters
diff --git a/cdist/core/code.py b/cdist/core/code.py
index 670029ed..1550880a 100644
--- a/cdist/core/code.py
+++ b/cdist/core/code.py
@@ -97,7 +97,7 @@ class Code(object):
"""
# target_host is tuple (target_host, target_hostname, target_fqdn)
- def __init__(self, target_host, local, remote):
+ def __init__(self, target_host, local, remote, dry_run=False):
self.target_host = target_host
self.local = local
self.remote = remote
@@ -113,6 +113,9 @@ class Code(object):
local.log),
}
+ if dry_run:
+ self.env['__cdist_dry_run'] = '1'
+
def _run_gencode(self, cdist_object, which):
cdist_type = cdist_object.cdist_type
script = os.path.join(self.local.type_path,
diff --git a/cdist/core/explorer.py b/cdist/core/explorer.py
index 0b3d7b2e..353d7681 100644
--- a/cdist/core/explorer.py
+++ b/cdist/core/explorer.py
@@ -67,7 +67,7 @@ class Explorer(object):
"""Executes cdist explorers.
"""
- def __init__(self, target_host, local, remote, jobs=None):
+ def __init__(self, target_host, local, remote, jobs=None, dry_run=False):
self.target_host = target_host
self._open_logger()
@@ -84,6 +84,10 @@ class Explorer(object):
'__cdist_log_level_name': util.log_level_name_env_var_val(
self.log),
}
+
+ if dry_run:
+ self.env['__cdist_dry_run'] = '1'
+
self._type_explorers_transferred = []
self.jobs = jobs
@@ -109,10 +113,17 @@ class Explorer(object):
self._run_global_explorers_parallel(out_path)
def _run_global_explorer(self, explorer, out_path):
- output = self.run_global_explorer(explorer)
- path = os.path.join(out_path, explorer)
- with open(path, 'w') as fd:
- fd.write(output)
+ try:
+ path = os.path.join(out_path, explorer)
+ output = self.run_global_explorer(explorer)
+ with open(path, 'w') as fd:
+ fd.write(output)
+ except cdist.Error as e:
+ local_path = os.path.join(self.local.global_explorer_path,
+ explorer)
+ stderr_path = os.path.join(self.local.stderr_base_path, "remote")
+ raise cdist.GlobalExplorerError(explorer, local_path, stderr_path,
+ e)
def _run_global_explorers_seq(self, out_path):
self.log.debug("Running global explorers sequentially")
@@ -186,11 +197,21 @@ class Explorer(object):
self.log.trace("Transferring object parameters for object: %s",
cdist_object.name)
self.transfer_object_parameters(cdist_object)
- for explorer in self.list_type_explorer_names(cdist_object.cdist_type):
- output = self.run_type_explorer(explorer, cdist_object)
+ cdist_type = cdist_object.cdist_type
+ for explorer in self.list_type_explorer_names(cdist_type):
self.log.trace("Running type explorer '%s' for object '%s'",
explorer, cdist_object.name)
- cdist_object.explorers[explorer] = output
+ try:
+ output = self.run_type_explorer(explorer, cdist_object)
+ cdist_object.explorers[explorer] = output
+ except cdist.Error as e:
+ path = os.path.join(self.local.type_path,
+ cdist_type.explorer_path,
+ explorer)
+ stderr_path = os.path.join(self.local.stderr_base_path,
+ "remote")
+ raise cdist.CdistObjectExplorerError(
+ cdist_object, explorer, path, stderr_path, e)
def run_type_explorer(self, explorer, cdist_object):
"""Run the given type explorer for the given object and return
diff --git a/cdist/core/manifest.py b/cdist/core/manifest.py
index 938ad8b8..8aeaf860 100644
--- a/cdist/core/manifest.py
+++ b/cdist/core/manifest.py
@@ -96,7 +96,11 @@ class Manifest(object):
"""Executes cdist manifests.
"""
- def __init__(self, target_host, local):
+
+ ORDER_DEP_STATE_NAME = 'order_dep_state'
+ TYPEORDER_DEP_NAME = 'typeorder_dep'
+
+ def __init__(self, target_host, local, dry_run=False):
self.target_host = target_host
self.local = local
@@ -117,6 +121,9 @@ class Manifest(object):
self.log),
}
+ if dry_run:
+ self.env['__cdist_dry_run'] = '1'
+
def _open_logger(self):
self.log = logging.getLogger(self.target_host[0])
@@ -209,3 +216,13 @@ class Manifest(object):
type_manifest,
env=self.env_type_manifest(cdist_object),
message_prefix=message_prefix)
+
+ def cleanup(self):
+ def _rm_file(fname):
+ try:
+ self.log.trace("[ORDER_DEP] Removing %s", fname)
+ os.remove(os.path.join(self.local.base_path, fname))
+ except FileNotFoundError:
+ pass
+ _rm_file(Manifest.ORDER_DEP_STATE_NAME)
+ _rm_file(Manifest.TYPEORDER_DEP_NAME)
diff --git a/cdist/emulator.py b/cdist/emulator.py
index 65d044d7..4800e2a3 100644
--- a/cdist/emulator.py
+++ b/cdist/emulator.py
@@ -29,6 +29,7 @@ import sys
import cdist
from cdist import core
from cdist import flock
+from cdist.core.manifest import Manifest
class MissingRequiredEnvironmentVariableError(cdist.Error):
@@ -44,7 +45,7 @@ class MissingRequiredEnvironmentVariableError(cdist.Error):
class DefaultList(list):
"""Helper class to allow default values for optional_multiple parameters.
- @see https://groups.google.com/forum/#!msg/comp.lang.python/sAUvkJEDpRc/RnRymrzJVDYJ
+ @see https://groups.google.com/forum/#!msg/comp.lang.python/sAUvkJEDpRc/RnRymrzJVDYJ # noqa
"""
def __copy__(self):
return []
@@ -82,6 +83,11 @@ class Emulator(object):
self.object_base_path = os.path.join(self.global_path, "object")
self.typeorder_path = os.path.join(self.global_path, "typeorder")
+ self.typeorder_dep_path = os.path.join(self.global_path,
+ Manifest.TYPEORDER_DEP_NAME)
+ self.order_dep_state_path = os.path.join(self.global_path,
+ Manifest.ORDER_DEP_STATE_NAME)
+
self.type_name = os.path.basename(argv[0])
self.cdist_type = core.CdistType(self.type_base_path, self.type_name)
@@ -206,6 +212,14 @@ class Emulator(object):
return params
def setup_object(self):
+ # CDIST_ORDER_DEPENDENCY state
+ order_dep_on = self._order_dep_on()
+ order_dep_defined = "CDIST_ORDER_DEPENDENCY" in self.env
+ if not order_dep_defined and order_dep_on:
+ self._set_order_dep_state_off()
+ if order_dep_defined and not order_dep_on:
+ self._set_order_dep_state_on()
+
# Create object with given parameters
self.parameters = {}
for key, value in vars(self.args).items():
@@ -237,6 +251,20 @@ class Emulator(object):
# record the created object in typeorder file
with open(self.typeorder_path, 'a') as typeorderfile:
print(self.cdist_object.name, file=typeorderfile)
+ # record the created object in parent object typeorder file
+ __object_name = self.env.get('__object_name', None)
+ depname = self.cdist_object.name
+ if __object_name:
+ parent = self.cdist_object.object_from_name(__object_name)
+ parent.typeorder.append(self.cdist_object.name)
+ if self._order_dep_on():
+ self.log.trace(('[ORDER_DEP] Adding %s to typeorder dep'
+ ' for %s'), depname, parent.name)
+ parent.typeorder_dep.append(depname)
+ elif self._order_dep_on():
+ self.log.trace('[ORDER_DEP] Adding %s to global typeorder dep',
+ depname)
+ self._add_typeorder_dep(depname)
# Record / Append source
self.cdist_object.source.append(self.object_source)
@@ -283,7 +311,8 @@ class Emulator(object):
self.object_source)))
raise
- self.log.debug("Recording requirement: %s", requirement)
+ self.log.debug("Recording requirement %s for %s",
+ requirement, self.cdist_object.name)
# Save the sanitised version, not the user supplied one
# (__file//bar => __file/bar)
@@ -292,30 +321,73 @@ class Emulator(object):
return cdist_object.name
+ def _order_dep_on(self):
+ return os.path.exists(self.order_dep_state_path)
+
+ def _set_order_dep_state_on(self):
+ self.log.trace('[ORDER_DEP] Setting order dep state on')
+ with open(self.order_dep_state_path, 'w'):
+ pass
+
+ def _set_order_dep_state_off(self):
+ self.log.trace('[ORDER_DEP] Setting order dep state off')
+ # remove order dep state file
+ try:
+ os.remove(self.order_dep_state_path)
+ except FileNotFoundError:
+ pass
+ # remove typeorder dep file
+ try:
+ os.remove(self.typeorder_dep_path)
+ except FileNotFoundError:
+ pass
+
+ def _add_typeorder_dep(self, name):
+ with open(self.typeorder_dep_path, 'a') as f:
+ print(name, file=f)
+
+ def _read_typeorder_dep(self):
+ try:
+ with open(self.typeorder_dep_path, 'r') as f:
+ return f.readlines()
+ except FileNotFoundError:
+ return []
+
def record_requirements(self):
"""Record requirements."""
+ order_dep_on = self._order_dep_on()
+
# Inject the predecessor, but not if its an override
# (this would leed to an circular dependency)
- if ("CDIST_ORDER_DEPENDENCY" in self.env and
- 'CDIST_OVERRIDE' not in self.env):
- # load object name created befor this one from typeorder file ...
- with open(self.typeorder_path, 'r') as typecreationfile:
- typecreationorder = typecreationfile.readlines()
- # get the type created before this one ...
- try:
- lastcreatedtype = typecreationorder[-2].strip()
- if 'require' in self.env:
+ if (order_dep_on and 'CDIST_OVERRIDE' not in self.env):
+ try:
+ # __object_name is the name of the object whose type
+ # manifest is currently executed
+ __object_name = self.env.get('__object_name', None)
+ # load object name created befor this one from typeorder
+ # dep file
+ if __object_name:
+ parent = self.cdist_object.object_from_name(
+ __object_name)
+ typeorder = parent.typeorder_dep
+ else:
+ typeorder = self._read_typeorder_dep()
+ # get the type created before this one
+ lastcreatedtype = typeorder[-2].strip()
+ if 'require' in self.env:
+ if lastcreatedtype not in self.env['require']:
self.env['require'] += " " + lastcreatedtype
- else:
- self.env['require'] = lastcreatedtype
- self.log.debug(("Injecting require for "
- "CDIST_ORDER_DEPENDENCY: %s for %s"),
- lastcreatedtype, self.cdist_object.name)
- except IndexError:
- # if no second last line, we are on the first type,
- # so do not set a requirement
- pass
+ else:
+ self.env['require'] = lastcreatedtype
+ self.log.debug(("Injecting require for "
+ "CDIST_ORDER_DEPENDENCY: %s for %s"),
+ lastcreatedtype,
+ self.cdist_object.name)
+ except IndexError:
+ # if no second last line, we are on the first type,
+ # so do not set a requirement
+ pass
reqs = set()
if "require" in self.env:
@@ -360,4 +432,6 @@ class Emulator(object):
# But only if the user hasn't said otherwise.
# Must prevent circular dependencies.
if parent.name not in current_object.requirements:
+ self.log.debug("Recording autorequirement %s for %s",
+ current_object.name, parent.name)
parent.autorequire.append(current_object.name)
diff --git a/cdist/exec/local.py b/cdist/exec/local.py
index f83c85df..ad6c6e36 100644
--- a/cdist/exec/local.py
+++ b/cdist/exec/local.py
@@ -69,7 +69,6 @@ class Local(object):
self.exec_path = exec_path
self.custom_initial_manifest = initial_manifest
- self._add_conf_dirs = add_conf_dirs
self.cache_path_pattern = cache_path_pattern
self.quiet_mode = quiet_mode
if configuration:
@@ -84,16 +83,7 @@ class Local(object):
self._init_cache_dir(None)
self._init_paths()
self._init_object_marker()
- self._init_conf_dirs()
-
- @property
- def dist_conf_dir(self):
- return os.path.abspath(os.path.join(os.path.dirname(cdist.__file__),
- "conf"))
-
- @property
- def home_dir(self):
- return cdist.home_dir()
+ self._init_conf_dirs(add_conf_dirs)
def _init_log(self):
self.log = logging.getLogger(self.target_host[0])
@@ -140,28 +130,9 @@ class Local(object):
# Does not need to be secure - just randomly different from .cdist
self.object_marker_name = tempfile.mktemp(prefix='.cdist-', dir='')
- def _init_conf_dirs(self):
- self.conf_dirs = []
-
- self.conf_dirs.append(self.dist_conf_dir)
-
- # Is the default place for user created explorer, type and manifest
- if self.home_dir:
- self.conf_dirs.append(self.home_dir)
-
- # Add directories defined in the CDIST_PATH environment variable
- # if 'CDIST_PATH' in os.environ:
- # cdist_path_dirs = re.split(r'(?.
+#
+#
+
+import cdist
+import cdist.configuration
+import cdist.core
+import cdist.exec.util as util
+import os
+import glob
+import fnmatch
+
+
+class Info(object):
+
+ def __init__(self, conf_dirs, args):
+ self.conf_dirs = conf_dirs
+ self.all = args.all
+ self.display_global_explorers = args.global_explorers
+ self.display_types = args.types
+ if not self.display_global_explorers and not self.display_types:
+ self.all = True
+ self.fixed_string = args.fixed_string
+ self._setup_glob_pattern(args.pattern)
+ self.full = args.full
+
+ def _setup_glob_pattern(self, pattern):
+ if pattern is None:
+ self.glob_pattern = '*'
+ elif ('?' in pattern or '*' in pattern or '[' in pattern or
+ self.fixed_string):
+ self.glob_pattern = pattern
+ else:
+ self.glob_pattern = '*' + pattern + '*'
+
+ @classmethod
+ def commandline(cls, args):
+ conf_dirs = util.resolve_conf_dirs_from_config_and_args(args)
+ c = cls(conf_dirs, args)
+ c.run()
+
+ def _get_global_explorers(self, conf_path):
+ rv = []
+ global_explorer_path = os.path.join(conf_path, "explorer",
+ self.glob_pattern)
+ if self.fixed_string:
+ if os.path.exists(global_explorer_path):
+ rv.append(global_explorer_path)
+ else:
+ for explorer in glob.glob(global_explorer_path):
+ rv.append(explorer)
+ return rv
+
+ def _should_display_type(self, dir_entry):
+ if not dir_entry.is_dir():
+ return False
+ if self.glob_pattern is None:
+ return True
+ if self.fixed_string:
+ return dir_entry.name == self.glob_pattern
+ else:
+ return fnmatch.fnmatch(dir_entry.name, self.glob_pattern)
+
+ def _get_types(self, conf_path):
+ rv = []
+ types_path = os.path.join(conf_path, "type")
+ if not os.path.exists(types_path):
+ return rv
+ with os.scandir(types_path) as it:
+ for entry in it:
+ if self._should_display_type(entry):
+ rv.append(entry.path)
+ return rv
+
+ def _display_details(self, title, details, default_values=None,
+ deprecated=None):
+ if not details:
+ return
+ if isinstance(details, bool):
+ print("\t{}: {}".format(title, 'yes' if details else 'no'))
+ elif isinstance(details, str):
+ print("\t{}: {}".format(title, details))
+ elif isinstance(details, list):
+ dv = dict(default_values) if default_values else {}
+ dp = dict(deprecated) if deprecated else {}
+
+ print("\t{}:".format(title))
+ for x in sorted(details):
+ print("\t\t{}".format(x), end='')
+ has_default = x in dv
+ is_deprecated = x in dp
+ need_comma = False
+ if has_default or is_deprecated:
+ print(" (", end='')
+ if has_default:
+ print("default: {}".format(dv[x]), end='')
+ need_comma = True
+ if is_deprecated:
+ print("{}deprecated".format(', ' if need_comma else ''),
+ end='')
+ if has_default or is_deprecated:
+ print(")", end='')
+ print()
+
+ def _display_type_parameters(self, cdist_type):
+ self._display_details("required parameters",
+ cdist_type.required_parameters,
+ default_values=cdist_type.parameter_defaults,
+ deprecated=cdist_type.deprecated_parameters)
+ self._display_details("required multiple parameters",
+ cdist_type.required_multiple_parameters,
+ default_values=cdist_type.parameter_defaults,
+ deprecated=cdist_type.deprecated_parameters)
+ self._display_details("optional parameters",
+ cdist_type.optional_parameters,
+ default_values=cdist_type.parameter_defaults,
+ deprecated=cdist_type.deprecated_parameters)
+ self._display_details("optional multiple parameters",
+ cdist_type.optional_multiple_parameters,
+ default_values=cdist_type.parameter_defaults,
+ deprecated=cdist_type.deprecated_parameters)
+ self._display_details("boolean parameters",
+ cdist_type.boolean_parameters,
+ default_values=cdist_type.parameter_defaults,
+ deprecated=cdist_type.deprecated_parameters)
+
+ def _display_type_characteristics(self, cdist_type):
+ characteristics = []
+ if cdist_type.is_install:
+ characteristics.append('install')
+ else:
+ characteristics.append('config')
+ if cdist_type.is_singleton:
+ characteristics.append('singleton')
+ if cdist_type.is_nonparallel:
+ characteristics.append('nonparallel')
+ else:
+ characteristics.append('parallel')
+ if cdist_type.deprecated is not None:
+ characteristics.append('deprecated')
+ print("\t{}".format(', '.join(characteristics)))
+
+ def _display_type_details(self, type_path):
+ dirname, basename = os.path.split(type_path)
+ cdist_type = cdist.core.CdistType(dirname, basename)
+
+ self._display_type_characteristics(cdist_type)
+ self._display_type_parameters(cdist_type)
+
+ def run(self):
+ rv = []
+ for cp in self.conf_dirs:
+ conf_path = os.path.expanduser(cp)
+ if self.all or self.display_global_explorers:
+ rv.extend((x, 'E', ) for x in self._get_global_explorers(
+ conf_path))
+ if self.all or self.display_types:
+ rv.extend((x, 'T', ) for x in self._get_types(conf_path))
+ rv = sorted(rv, key=lambda x: x[0])
+ for x, t in rv:
+ print(x)
+ if self.full and t == 'T':
+ self._display_type_details(x)
diff --git a/cdist/inventory.py b/cdist/inventory.py
index 7da306fa..138a2034 100644
--- a/cdist/inventory.py
+++ b/cdist/inventory.py
@@ -315,7 +315,7 @@ class InventoryHost(Inventory):
hostpath = self._host_path(host)
self.log.trace("hostpath: {}".format(hostpath))
if self.action == "add" and not os.path.exists(hostpath):
- self._new_hostpath(hostpath)
+ self._new_hostpath(hostpath)
else:
if not os.path.isfile(hostpath):
raise cdist.Error(("Host path \'{}\' is"
diff --git a/cdist/preos.py b/cdist/preos.py
new file mode 100644
index 00000000..bf2a8e60
--- /dev/null
+++ b/cdist/preos.py
@@ -0,0 +1,130 @@
+import os
+import os.path
+import sys
+import inspect
+import argparse
+import cdist
+import logging
+import cdist.argparse
+import cdist.configuration
+import cdist.exec.util as util
+
+
+_PREOS_CALL = "commandline"
+_PREOS_NAME = "_preos_name"
+_PREOS_MARKER = "_cdist_preos"
+_PLUGINS_DIR = "preos"
+_PLUGINS_PATH = [os.path.join(os.path.dirname(__file__), _PLUGINS_DIR), ]
+log = logging.getLogger("PreOS")
+
+
+def extend_plugins_path(dirs):
+ for dir in dirs:
+ preos_dir = os.path.expanduser(os.path.join(dir, "preos"))
+ if os.path.isdir(preos_dir):
+ _PLUGINS_PATH.append(preos_dir)
+
+
+def preos_plugin(obj):
+ """It is preos if _PREOS_MARKER is True and has _PREOS_CALL."""
+ if hasattr(obj, _PREOS_MARKER):
+ is_preos = getattr(obj, _PREOS_MARKER)
+ else:
+ is_preos = False
+
+ if is_preos and hasattr(obj, _PREOS_CALL):
+ yield obj
+
+
+def scan_preos_dir_plugins(dir):
+ for fname in os.listdir(dir):
+ if os.path.isfile(os.path.join(dir, fname)):
+ fname = os.path.splitext(fname)[0]
+ module_name = fname
+ try:
+ module = __import__(module_name)
+ yield from preos_plugin(module)
+ clsmembers = inspect.getmembers(module, inspect.isclass)
+ for cm in clsmembers:
+ c = cm[1]
+ yield from preos_plugin(c)
+ except ImportError as e:
+ log.warning("Cannot import '{}': {}".format(module_name, e))
+
+
+def find_preos_plugins():
+ for dir in _PLUGINS_PATH:
+ yield from scan_preos_dir_plugins(dir)
+
+
+def find_preoses():
+ preoses = {}
+ for preos in find_preos_plugins():
+ if hasattr(preos, _PREOS_NAME):
+ preos_name = getattr(preos, _PREOS_NAME)
+ else:
+ preos_name = preos.__name__.lower()
+ preoses[preos_name] = preos
+ return preoses
+
+
+def check_root():
+ if os.geteuid() != 0:
+ raise cdist.Error("Must be run with root privileges")
+
+
+def get_available_preoses_string(cls):
+ preoses = [' - {}'.format(x) for x in sorted(set(cls.preoses))]
+ return "Available PreOS-es:\n{}".format("\n".join(preoses))
+
+
+class PreOS(object):
+ preoses = None
+
+ @classmethod
+ def commandline(cls, argv):
+ cdist_parser = cdist.argparse.get_parsers()
+ parser = argparse.ArgumentParser(
+ description="Create PreOS", prog="cdist preos",
+ parents=[cdist_parser['loglevel'], ])
+ parser.add_argument('preos', help='PreOS to create',
+ nargs='?', default=None)
+ parser.add_argument('-c', '--conf-dir',
+ help=('Add configuration directory (one that '
+ 'contains "preos" subdirectory)'),
+ action='append')
+ parser.add_argument('-g', '--config-file',
+ help='Use specified custom configuration file.',
+ dest="config_file", required=False)
+ parser.add_argument('-L', '--list-preoses',
+ help='List available PreOS-es',
+ action='store_true', default=False)
+ parser.add_argument('remainder_args', nargs=argparse.REMAINDER)
+ args = parser.parse_args(argv[1:])
+ cdist.argparse.handle_loglevel(args)
+ log.debug("preos args : {}".format(args))
+
+ conf_dirs = util.resolve_conf_dirs_from_config_and_args(args)
+
+ extend_plugins_path(conf_dirs)
+ sys.path.extend(_PLUGINS_PATH)
+ cls.preoses = find_preoses()
+
+ if args.list_preoses or not args.preos:
+ print(get_available_preoses_string(cls))
+ sys.exit(0)
+
+ preos_name = args.preos
+ if preos_name in cls.preoses:
+ preos = cls.preoses[preos_name]
+ func = getattr(preos, _PREOS_CALL)
+ if inspect.ismodule(preos):
+ func_args = [preos, args.remainder_args, ]
+ else:
+ func_args = [args.remainder_args, ]
+ log.info("Running preos : {}".format(preos_name))
+ func(*func_args)
+ else:
+ raise cdist.Error(
+ "Invalid PreOS {}. {}".format(
+ preos_name, get_available_preoses_string(cls)))
diff --git a/cdist/preos/debootstrap/__init__.py b/cdist/preos/debootstrap/__init__.py
new file mode 100644
index 00000000..6d340b4a
--- /dev/null
+++ b/cdist/preos/debootstrap/__init__.py
@@ -0,0 +1 @@
+from debootstrap.debootstrap import Debian, Ubuntu, Devuan
diff --git a/cdist/preos/debootstrap/debootstrap.py b/cdist/preos/debootstrap/debootstrap.py
new file mode 100644
index 00000000..f53dd4a7
--- /dev/null
+++ b/cdist/preos/debootstrap/debootstrap.py
@@ -0,0 +1,239 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# 2016 Darko Poljak (darko.poljak at ungleich.ch)
+#
+# This file is part of cdist.
+#
+# cdist 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.
+#
+# cdist 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 cdist. If not, see .
+#
+#
+
+import cdist
+import cdist.config
+import cdist.core
+import cdist.preos
+import argparse
+import cdist.argparse
+import logging
+import os
+import subprocess
+
+
+class Debian(object):
+ _preos_name = 'debian'
+ _cdist_preos = True
+
+ _files_dir = os.path.join(os.path.dirname(__file__), "files")
+
+ @classmethod
+ def default_args(cls):
+ default_remote_exec = os.path.join(cls._files_dir, "remote-exec.sh")
+ default_remote_copy = os.path.join(cls._files_dir, "remote-copy.sh")
+ default_init_manifest = os.path.join(
+ cls._files_dir, "init-manifest-{}".format(cls._preos_name))
+
+ defargs = argparse.Namespace()
+ defargs.arch = 'amd64'
+ defargs.bootstrap = False
+ defargs.configure = False
+ defargs.cdist_params = '-v'
+ defargs.rm_bootstrap_dir = False
+ defargs.suite = 'stable'
+ defargs.remote_exec = default_remote_exec
+ defargs.remote_copy = default_remote_copy
+ defargs.manifest = default_init_manifest
+
+ return defargs
+
+ @classmethod
+ def get_parser(cls):
+ defargs = cls.default_args()
+ cdist_parser = cdist.argparse.get_parsers()
+ parser = argparse.ArgumentParser(
+ prog='cdist preos {}'.format(cls._preos_name),
+ parents=[cdist_parser['loglevel'], cdist_parser['beta']])
+ parser.add_argument('target_dir', nargs=1,
+ help=("target directory where PreOS will be "
+ "bootstrapped"))
+ parser.add_argument(
+ '-a', '--arch',
+ help="target debootstrap architecture, by default '{}'".format(
+ defargs.arch), dest='arch', default=defargs.arch)
+ parser.add_argument(
+ '-B', '--bootstrap',
+ help='do bootstrap step',
+ dest='bootstrap', action='store_true', default=defargs.bootstrap)
+ parser.add_argument(
+ '-C', '--configure',
+ help='do configure step',
+ dest='configure', action='store_true', default=defargs.configure)
+ parser.add_argument(
+ '-c', '--cdist-params',
+ help=("parameters that will be passed to cdist config, by default"
+ " '{}' is used".format(defargs.cdist_params)),
+ dest='cdist_params', default=defargs.cdist_params)
+ parser.add_argument(
+ '-D', '--drive-boot',
+ help='create bootable PreOS on specified drive',
+ dest='drive')
+ parser.add_argument(
+ '-e', '--remote-exec',
+ help=("remote exec that cdist config will use, by default "
+ "internal script is used"),
+ dest='remote_exec', default=defargs.remote_exec)
+ parser.add_argument(
+ '-i', '--init-manifest',
+ help=("init manifest that cdist config will use, by default "
+ "internal init manifest is used"),
+ dest='manifest', default=defargs.manifest)
+ parser.add_argument(
+ '-k', '--keyfile', action="append",
+ help=("ssh key files that will be added to cdist config; "
+ "'__ssh_authorized_keys root ...' type is appended to "
+ "initial manifest"),
+ dest='keyfile')
+ parser.add_argument(
+ '-m', '--mirror',
+ help='use specified mirror for debootstrap',
+ dest='mirror')
+ parser.add_argument(
+ '-P', '--root-password',
+ help='Set specified password for root, generated by default',
+ dest='root_password')
+ parser.add_argument('-p', '--pxe-boot-dir', help='PXE boot directory',
+ dest='pxe_boot_dir')
+ parser.add_argument(
+ '-r', '--rm-bootstrap-dir',
+ help='remove target directory after finishing',
+ dest='rm_bootstrap_dir', action='store_true',
+ default=defargs.rm_bootstrap_dir)
+ parser.add_argument(
+ '-S', '--script',
+ help='use specified script for debootstrap',
+ dest='script')
+ parser.add_argument('-s', '--suite',
+ help="suite used for debootstrap, "
+ "by default '{}'".format(defargs.suite),
+ dest='suite', default=defargs.suite)
+ parser.add_argument(
+ '-y', '--remote-copy',
+ help=("remote copy that cdist config will use, by default "
+ "internal script is used"),
+ dest='remote_copy', default=defargs.remote_copy)
+ parser.epilog = cdist.argparse.EPILOG
+
+ return parser
+
+ @classmethod
+ def update_env(cls, env):
+ pass
+
+ @classmethod
+ def commandline(cls, argv):
+ log = logging.getLogger(cls.__name__)
+
+ parser = cls.get_parser()
+ args = parser.parse_args(argv)
+ if args.script and not args.mirror:
+ raise cdist.Error("script option cannot be used without "
+ "mirror option")
+
+ args.command = cls._preos_name
+ cdist.argparse.check_beta(vars(args))
+
+ cdist.preos.check_root()
+
+ args.target_dir = os.path.realpath(args.target_dir[0])
+ args.os = cls._preos_name
+ args.remote_exec = os.path.realpath(args.remote_exec)
+ args.remote_copy = os.path.realpath(args.remote_copy)
+ args.manifest = os.path.realpath(args.manifest)
+ if args.keyfile:
+ new_keyfile = [os.path.realpath(x) for x in args.keyfile]
+ args.keyfile = new_keyfile
+ if args.pxe_boot_dir:
+ args.pxe_boot_dir = os.path.realpath(args.pxe_boot_dir)
+
+ cdist.argparse.handle_loglevel(args)
+ log.debug("preos: {}, args: {}".format(cls._preos_name, args))
+ try:
+ env = vars(args)
+ new_env = {}
+ for key in env:
+ if key == 'verbose' and env[key]:
+ if env[key] >= 3:
+ new_env['debug'] = "yes"
+ elif env[key] == 2:
+ new_env['verbose'] = "yes"
+ elif not env[key]:
+ new_env[key] = ''
+ elif isinstance(env[key], bool) and env[key]:
+ new_env[key] = "yes"
+ elif isinstance(env[key], list):
+ val = env[key]
+ new_env[key + "_cnt"] = str(len(val))
+ for i, v in enumerate(val):
+ new_env[key + "_" + str(i)] = v
+ else:
+ new_env[key] = str(env[key])
+ env = new_env
+ env.update(os.environ)
+ cls.update_env(env)
+ log.debug("preos: {} env: {}".format(cls._preos_name, env))
+ cmd = os.path.join(cls._files_dir, "code")
+ info_msg = ["Running preos: {}, suite: {}, arch: {}".format(
+ cls._preos_name, args.suite, args.arch), ]
+ if args.mirror:
+ info_msg.append("mirror: {}".format(args.mirror))
+ if args.script:
+ info_msg.append("script: {}".format(args.script))
+ if args.bootstrap:
+ info_msg.append("bootstrapping")
+ if args.configure:
+ info_msg.append("configuring")
+ if args.pxe_boot_dir:
+ info_msg.append("creating PXE")
+ if args.drive:
+ info_msg.append("creating bootable drive")
+ log.info(info_msg)
+ log.debug("cmd={}".format(cmd))
+ subprocess.check_call(cmd, env=env, shell=True)
+ except subprocess.CalledProcessError as e:
+ log.error("preos {} failed: {}".format(cls._preos_name, e))
+
+
+class Ubuntu(Debian):
+ _preos_name = "ubuntu"
+
+ @classmethod
+ def default_args(cls):
+ defargs = super().default_args()
+ defargs.suite = 'xenial'
+ return defargs
+
+
+class Devuan(Debian):
+ _preos_name = "devuan"
+
+ @classmethod
+ def default_args(cls):
+ defargs = super().default_args()
+ defargs.suite = 'jessie'
+ return defargs
+
+ @classmethod
+ def update_env(cls, env):
+ env['DEBOOTSTRAP_DIR'] = os.path.join(cls._files_dir,
+ 'devuan-debootstrap')
diff --git a/cdist/preos/debootstrap/files/code b/cdist/preos/debootstrap/files/code
new file mode 100755
index 00000000..9e37003b
--- /dev/null
+++ b/cdist/preos/debootstrap/files/code
@@ -0,0 +1,274 @@
+#!/bin/sh
+##
+## 2016 Darko Poljak (darko.poljak at ungleich.ch)
+##
+## This file is part of cdist.
+##
+## cdist 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.
+##
+## cdist 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 cdist. If not, see .
+
+set -e
+
+if [ "${debug}" ]
+then
+ set -x
+ cdist_params="${cdist_params} -d"
+fi
+
+bootstrap_dir="${target_dir}"
+
+case "${os}" in
+ ubuntu|debian|devuan)
+ # nothing, those are valid values
+ ;;
+ *)
+ echo "ERROR: invalid os value: ${os}" >&2
+ exit 1
+ ;;
+esac
+
+check_bootstrap_dir() {
+ if [ ! -e "$1" ]
+ then
+ echo "ERROR: bootstrap directory $1 does not exist" >&2
+ exit 1
+ fi
+}
+
+# bootstrap
+if [ "${bootstrap}" ]
+then
+ if [ "${DEBOOTSTRAP_DIR}" ]
+ then
+ debootstrap_cmd="${DEBOOTSTRAP_DIR}/debootstrap"
+ else
+ command -v debootstrap 2>&1 > /dev/null || {
+ echo "ERROR: debootstrap not found" >&2
+ exit 1
+ }
+ debootstrap_cmd="debootstrap"
+ fi
+
+ # If PreOS on drive then do not check for directory emptiness.
+ # Partition can at least contain 'lost+found' directory.
+ if [ ! "${drive}" ]
+ then
+ if [ -e "${bootstrap_dir}" ]
+ then
+ dir_content=$(ls -A "${bootstrap_dir}" | wc -l)
+ else
+ dir_content=0
+ fi
+ if [ "${dir_content}" -ne 0 ]
+ then
+ echo "ERROR: "${bootstrap_dir}" not empty " >&2
+ exit 1
+ fi
+ fi
+
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "bootstrapping..."
+ fi
+ mkdir -p "${bootstrap_dir}"
+ "${debootstrap_cmd}" --include=openssh-server --arch=${arch} ${suite} ${bootstrap_dir} \
+ ${mirror} ${script}
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "bootstrap finished"
+ fi
+fi
+
+chroot_mount() {
+ mount -t proc none "${bootstrap_dir}/proc" || true
+ mount -t sysfs none "${bootstrap_dir}/sys" || true
+ mount -o bind /dev "${bootstrap_dir}/dev" || true
+ mount -t devpts none "${bootstrap_dir}/dev/pts" || true
+}
+
+chroot_umount() {
+ umount "${bootstrap_dir}/dev/pts" || true
+ umount "${bootstrap_dir}/dev" || true
+ umount "${bootstrap_dir}/sys" || true
+ umount "${bootstrap_dir}/proc" || true
+}
+
+TRAPFUNC="umount \"${bootstrap_dir}/dev/pts\" || true; \
+umount \"${bootstrap_dir}/dev\" || true; \
+umount \"${bootstrap_dir}/sys\" || true; \
+umount \"${bootstrap_dir}/proc\" || true;"
+
+# config
+if [ "${configure}" ]
+then
+ if [ ! -f "${manifest}" ]
+ then
+ echo "ERROR: ${manifest} does not exist" >&2
+ exit 1
+ fi
+ if [ ! -f "${remote_exec}" ]
+ then
+ echo "ERROR: ${remote_exec} does not exist" >&2
+ exit 1
+ fi
+ if [ ! -f "${remote_copy}" ]
+ then
+ echo "ERROR: ${remote_copy} does not exist" >&2
+ exit 1
+ fi
+
+ if [ "${keyfile_cnt}" -a "${keyfile_cnt}" -gt 0 ]
+ then
+ i="$((keyfile_cnt - 1))"
+ keyfiles=""
+ while [ "${i}" -ge 0 ]
+ do
+ kf_var="keyfile_${i}"
+ eval kf='$'"${kf_var}"
+ if [ ! -f "${kf}" ]
+ then
+ echo "ERROR: ${kf} does not exist" >&2
+ exit 1
+ fi
+ key=$(cat "${kf}")
+ keyfiles="${keyfiles} --key '${key}'"
+ i=$((i - 1))
+ done
+ ssh_auth_keys_line="__ssh_authorized_keys root ${keyfiles}\n"
+ else
+ ssh_auth_keys_line=""
+ fi
+
+ check_bootstrap_dir "${bootstrap_dir}"
+
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "configuring..."
+ fi
+
+ trap "${TRAPFUNC}" 0 1 2 3 15
+
+ chroot_mount
+
+ chroot "${bootstrap_dir}" /usr/bin/apt-get update
+
+ if [ "${drive}" ]
+ then
+ grub_manifest_line="__package grub-pc --state present\n"
+ grub_kern_params_line="__line linux_kernel_params \
+--file /etc/default/grub \
+--line 'GRUB_CMDLINE_LINUX_DEFAULT=\"quiet splash net.ifnames=0\"'\n"
+ else
+ grub_manifest_line=""
+ grub_kern_params_line=""
+ fi
+ grub_lines="${grub_manifest_line}${grub_kern_params_line}"
+
+ printf "${ssh_auth_keys_line}${grub_lines}" \
+ | cat "${manifest}" - |\
+ cdist config \
+ ${cdist_params} -i - \
+ --remote-exec "${remote_exec}" \
+ --remote-copy "${remote_copy}" \
+ "${bootstrap_dir}"
+
+ # __hostname with systmed uses hostnamectl which needs dbus running
+ # set hostname explicitly here instead
+ printf "preos\n" > "${bootstrap_dir}/etc/hostname"
+
+ chroot "${bootstrap_dir}" /usr/bin/apt-get autoclean
+ chroot "${bootstrap_dir}" /usr/bin/apt-get clean
+ chroot "${bootstrap_dir}" /usr/bin/apt-get autoremove
+
+ chroot_umount
+
+ trap - 0 1 2 3 15
+
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "configuring finished"
+ fi
+fi
+
+if [ "${pxe_boot_dir}" ]
+then
+ check_bootstrap_dir "${bootstrap_dir}"
+
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "creating pxe..."
+ fi
+
+ mkdir -p "${pxe_boot_dir}"
+ cp "${bootstrap_dir}"/boot/vmlinuz-* "${pxe_boot_dir}/kernel"
+ cd "${bootstrap_dir}"
+ find . -print0 | cpio --null -o --format=newc | gzip -9 > "${pxe_boot_dir}/initramfs"
+
+ mkdir -p "${pxe_boot_dir}/pxelinux.cfg"
+ cat < "${pxe_boot_dir}/pxelinux.cfg/default"
+ DEFAULT preos
+ LABEL preos
+ KERNEL kernel
+ APPEND utf8 load_ramdisk=1 root=/dev/ram nofb initrd=initramfs console=ttyS1,115200 net.ifnames=0
+EOPXEF
+
+ cp "${bootstrap_dir}/usr/lib/PXELINUX/pxelinux.0" "${pxe_boot_dir}/pxelinux.0"
+ cp "${bootstrap_dir}/usr/lib/syslinux/modules/bios/ldlinux.c32" \
+ "${pxe_boot_dir}/ldlinux.c32"
+ # network boot need all files world readable
+ chmod -R 644 "${pxe_boot_dir}"/*
+
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "pxe creation finished"
+ fi
+fi
+
+if [ "${drive}" ]
+then
+ trap "${TRAPFUNC}" 0 1 2 3 15
+ chroot_mount
+ chroot "${bootstrap_dir}" grub-install ${drive}
+ chroot "${bootstrap_dir}" /bin/sh -c "GRUB_DISABLE_OS_PROBER=true update-grub"
+ # set root password
+ if [ ! "${root_password}" ]
+ then
+ if ! which strings >/dev/null 2>&1
+ then
+ printf "strings is missing\n" >&2
+ exit 1
+ fi
+ root_password="$(head -n 1000 /dev/urandom | strings | \
+ grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n')"
+ printf "Generated root password (without quotes):'${root_password}'\n"
+ fi
+ chroot "${bootstrap_dir}" /bin/sh -c "echo \"root:${root_password}\" | \
+ chpasswd"
+ # /etc/securetty must not be world writeable.
+ chmod 644 "${bootstrap_dir}"/etc/securetty
+ chroot_umount
+ trap - 0 1 2 3 15
+fi
+
+if [ "${rm_bootstrap_dir}" ]
+then
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "removing bootstrap dir..."
+ fi
+ rm -r -f "${bootstrap_dir}"
+ if [ "${verbose}" -o "${debug}" ]
+ then
+ echo "removing bootstrap dir finished"
+ fi
+fi
diff --git a/cdist/preos/debootstrap/files/devuan-debootstrap/Makefile b/cdist/preos/debootstrap/files/devuan-debootstrap/Makefile
new file mode 100644
index 00000000..85168031
--- /dev/null
+++ b/cdist/preos/debootstrap/files/devuan-debootstrap/Makefile
@@ -0,0 +1,18 @@
+# avoid dpkg-dev dependency; fish out the version with sed
+VERSION := $(shell sed 's/.*(\(.*\)).*/\1/; q' debian/changelog)
+
+all:
+
+clean:
+
+DSDIR=$(DESTDIR)/usr/share/debootstrap
+install:
+ mkdir -p $(DSDIR)/scripts
+ mkdir -p $(DESTDIR)/usr/sbin
+
+ cp -a scripts/* $(DSDIR)/scripts/
+ install -o root -g root -m 0644 functions $(DSDIR)/
+
+ sed 's/@VERSION@/$(VERSION)/g' debootstrap >$(DESTDIR)/usr/sbin/debootstrap
+ chown root:root $(DESTDIR)/usr/sbin/debootstrap
+ chmod 0755 $(DESTDIR)/usr/sbin/debootstrap
diff --git a/cdist/preos/debootstrap/files/devuan-debootstrap/README b/cdist/preos/debootstrap/files/devuan-debootstrap/README
new file mode 100644
index 00000000..4d8c3049
--- /dev/null
+++ b/cdist/preos/debootstrap/files/devuan-debootstrap/README
@@ -0,0 +1,65 @@
+README for debootstrap
+======================
+
+See the manpage for (some) documentation.
+
+Running debootstrap from source
+-------------------------------
+
+You can run debootstrap from its source tree without installing it. This
+can be useful if you want a quick way to make a Debian chroot on another
+system, or if you are testing modifications to debootstrap.
+
+First, get the source.
+
+* Either by using git
+ git clone https://anonscm.debian.org/git/d-i/debootstrap.git
+
+* Or by visiting
+ and downloading the tar.gz file
+
+Then in the debootstrap source directory:
+
+ export DEBOOTSTRAP_DIR=`pwd`
+ sudo ./debootstrap stable my-stable-dir
+
+If you are running a multi-stage boot strap (for example for a QEMU
+rootfs) you don't even need root:
+
+ export DEBOOTSTRAP_DIR=`pwd`
+ fakeroot ./debootstrap --foreign --arch=armhf testing my-testing-dir http://deb.debian.org/debian
+
+Of course you will need to execute the second stage as root to finish the bootstrap:
+
+ (on foreign hardware)
+ /debootstrap/debootstrap --second-stage
+
+
+Future
+------
+
+ * Cross-strap support - so you can bootstrap a filesystem to the
+ point where it will successfully boot, and finish installing itself
+ without having to be running the target architecture or OS yourself.
+
+ debootstrap --arch powerpc sarge ./sarge-ppc-chroot ...
+
+ on an i386 system, boot a powerpc box with sarge-ppc-chroot as its
+ root files system, and have it "work". The cross-hurd package does
+ something similar, and should be replaced by this feature.
+
+ * There should be some (better) way of telling debootstrap what "base"
+ packages you want to install -- this varies between making a chroot,
+ doing an install, and doing a buildd. Also, some installs want
+ different base packages (to setup networking, or kernels, eg)
+
+
+NMUing
+------
+
+If there's a problem with debootstrap that you need fixed, feel free to do
+an NMU to fix it. Usual rules: try not to break anything, and mail the
+patch to the BTS. Don't worry about asking first though.
+
+However, note that debootstrap is now team maintained. Anyone in d-i can do
+a release without the bother of a NMU.
diff --git a/cdist/preos/debootstrap/files/devuan-debootstrap/TODO b/cdist/preos/debootstrap/files/devuan-debootstrap/TODO
new file mode 100644
index 00000000..e5fde0e4
--- /dev/null
+++ b/cdist/preos/debootstrap/files/devuan-debootstrap/TODO
@@ -0,0 +1,11 @@
+
+Features:
+ ++ second stage via chroot debootstrap/debootstrap
+ ++ debootstrap/deb file to record deb destinations/information
+
+ -- configuration file
+ -- versus command line
+ -- support for sources (vs mirrors)
+ -- faux-pinning for packages
+
+ ++ makedev in second stage
diff --git a/cdist/preos/debootstrap/files/devuan-debootstrap/debian/.gitignore b/cdist/preos/debootstrap/files/devuan-debootstrap/debian/.gitignore
new file mode 100644
index 00000000..39638d97
--- /dev/null
+++ b/cdist/preos/debootstrap/files/devuan-debootstrap/debian/.gitignore
@@ -0,0 +1,6 @@
+debootstrap
+debootstrap-udeb
+files
+*.debhelper.log
+*.substvars
+
diff --git a/cdist/preos/debootstrap/files/devuan-debootstrap/debian/README.DevuanSource b/cdist/preos/debootstrap/files/devuan-debootstrap/debian/README.DevuanSource
new file mode 100644
index 00000000..6446a088
--- /dev/null
+++ b/cdist/preos/debootstrap/files/devuan-debootstrap/debian/README.DevuanSource
@@ -0,0 +1,15 @@
+To sync up with debians source for inspiration you should run the following:
+
+ `git remote add alioth-git git://anonscm.debian.org/d-i/debootstrap.git`
+ `git fetch alioth-git`
+
+After that you can either cherry-pick or merge releases from debian. To
+merge a release, it's do:
+ `git tag` to list the release tags
+and
+ `git merge `
+followed by all the fixups and then commit with an appropriate message like
+ "Merging Release from debian"
+
+Copyright 2016 Daniel Reurich
+
diff --git a/cdist/preos/debootstrap/files/devuan-debootstrap/debian/changelog b/cdist/preos/debootstrap/files/devuan-debootstrap/debian/changelog
new file mode 100644
index 00000000..8688197d
--- /dev/null
+++ b/cdist/preos/debootstrap/files/devuan-debootstrap/debian/changelog
@@ -0,0 +1,2655 @@
+debootstrap (1.0.87+devuan1.1) unstable; urgency=medium
+
+ * add git to builddeps
+
+ -- Daniel Reurich Fri, 13 Jan 2017 23:12:50 +1300
+
+debootstrap (1.0.87+devuan1.0) unstable; urgency=high
+
+ [ Julien Cristau ]
+ * Default to split /usr again, as merged-/usr breaks dpkg-shlibdeps
+ (closes: #844221).
+
+ [ Riku Voipio ]
+ * remove scratchbox2 support (closes: #796189)
+
+ -- Christian Perrier Wed, 16 Nov 2016 06:47:27 +0100
+
+debootstrap (1.0.86+devuan1.0) unstable; urgency=high
+
+ [ Daniel Reurich ]
+ * Restore Devuan Jessie version
+ * switch to 3.0 (git) source format
+ * set git-depth
+ * Add directions for inspiration from debians source
+ * removed file so we can build using git source format
+ * merge 1.0.86 for jessie
+
+ -- Daniel Reurich Fri, 13 Jan 2017 15:58:19 +1300
+
+debootstrap (1.0.86) unstable; urgency=high
+
+ * Rework split_inline_sig by using shell built-ins instead of trying to
+ mix sed and tr together, which might work on regular systems but not
+ from inside the Debian Installer (Closes: #842591). Thanks to Ansgar
+ Burchardt for the proof of concept!
+
+ -- Cyril Brulebois Sun, 30 Oct 2016 23:35:45 +0100
+
+debootstrap (1.0.85-1+devuan1) unstable; urgency=medium
+
+ * sync with debian upstream package
+ * add right keyrings with the new schema on devuan-keyring package
+
+ -- Franco (nextime) Lanza Sat, 29 Oct 2016 23:21:57 +0200
+
+
+debootstrap (1.0.85) unstable; urgency=medium
+
+ [ Julien Cristau ]
+ * Add support for downloading and validating InRelease files, by splitting
+ up detached signature from signed data.
+ * Switch default mirror to deb.debian.org.
+
+ [ Colin Watson ]
+ * Add (Ubuntu) zesty as a symlink to gutsy.
+
+ [ Ansgar Burchardt ]
+ * Add jessie-kfreebsd to merged-/usr blacklist.
+ * No longer Build-Depend on makedev. The code using it was already
+ removed in debootstrap 1.0.82.
+ * Do not use `tar -k` for older releases which might have file
+ conflicts between the packages to be installed. (Closes: #838388)
+ * Error out when seeing short options. (Closes: #548880)
+ * Add oldoldstable -> sid script symlink. (Closes: #792734)
+ * Add buster -> sid and bullseye -> sid script symlinks.
+ * Only unpack and configure the base system when there are actually
+ packages to install. (Closes: #825034)
+ * debootstrap.8: Use stretch instead of wheezy in examples.
+
+ [ Marco d'Itri ]
+ * Enable merged-/usr by default. (Closes: #839046)
+
+ -- Julien Cristau Fri, 21 Oct 2016 20:22:49 +0200
+
+debootstrap (1.0.84) unstable; urgency=medium
+
+ [ Ansgar Burchardt ]
+ * Add support for xz-compressed Packages indices. (Closes: #837649)
+
+ -- Christian Perrier Thu, 06 Oct 2016 06:59:38 +0200
+
+debootstrap (1.0.83) unstable; urgency=medium
+
+ [ Ansgar Burchardt ]
+ * functions: Validate that the requested suite is listed in the
+ Release file's Suite or Codename field. (Closes: #837075)
+ * Add support for merged-/usr, enabled by a new --merged-usr option.
+ (Closes: #810301)
+ * Feign install of dpkg in second stage. This avoids problems when
+ using dpkg-deb together with busybox' tar. (Closes: #837185)
+ * README: Use https://.
+
+ [ Steve McIntyre ]
+ * Update Standards-Version to 3.9.8 (no changes needed)
+
+ -- Steve McIntyre <93sam@debian.org> Tue, 13 Sep 2016 13:16:41 +0100
+
+debootstrap (1.0.82) unstable; urgency=medium
+
+ [ Alex Bennée ]
+ * Excise all devices.tar.gz code. Closes: #830869
+
+ -- Christian Perrier Thu, 08 Sep 2016 07:09:56 +0200
+
+debootstrap (1.0.81) unstable; urgency=medium
+
+ [ Luca Falavigna ]
+ * Add (Ubuntu) yakkety as a symlink to gutsy.
+
+ -- Christian Perrier Tue, 03 May 2016 06:51:57 +0200
+
+debootstrap (1.0.80-1+devuan1) unstable; urgency=medium
+
+ * sync with debian upstream package.
+
+ -- Franco (nextime) Lanza Sun, 24 Apr 2016 06:16:29 +0200
+
+debootstrap (1.0.80) unstable; urgency=medium
+
+ [ Jon Boden ]
+ * scripts/gutsy: Support kfreebsd & hurd arches on Ubuntu targets
+ (closes: #818748)
+
+ -- Christian Perrier Tue, 22 Mar 2016 19:27:45 +0100
+
+debootstrap (1.0.79) unstable; urgency=medium
+
+ [ Samuel Thibault ]
+ * hurd: move setting up dev and servers firmlink to setup_proc stage. Also
+ firmlink proc there. Thanks Gabriele Giacone for all the investigation!
+ (Closes: #768102)
+
+ -- Christian Perrier Fri, 19 Feb 2016 07:23:59 +0100
+
+debootstrap (1.0.78+nmu1) unstable; urgency=medium
+
+ * Non-maintainer upload.
+ * Split setup_devices in setup_devices (which now only deals with static
+ device nodes) and setup_dynamic_devices, and move the calls to
+ setup_devices from the beginning of the second stage to the end of the
+ first stage.
+ setup_dynamic_devices mounts the appropriate filesystems which provide
+ dynamic device nodes for the architectures which need one in
+ debootstrap (kfreebsd and hurd).
+ This fixes a bug in --second-stage introduced in 1.0.34 and exposed
+ by the devices-related changes of 1.0.76: the second stage debootstrap
+ runs "dpkg --print-architecture >/dev/null" at the very beginning of
+ the program when /dev is still empty, so it creates an empty regular
+ file in place of /dev/null and this will cause mknod to fail later.
+ (Closes: #813232)
+
+ -- Marco d'Itri Wed, 17 Feb 2016 01:23:23 +0100
+
+debootstrap (1.0.78) unstable; urgency=high
+
+ * Use HTTPS for Vcs-* URLs, and link to cgit rather than gitweb.
+ * Don't call mknod with the --mode option, it's not supported in
+ busybox. Use -m instead - fixes the broken fix for #812811.
+ Closes: #813124. Urgency high to get this fix propagated quickly -
+ it's breaking d-i installs right now. Adding myself to uploaders and
+ uploading.
+
+ -- Steve McIntyre <93sam@debian.org> Fri, 29 Jan 2016 16:36:00 +0000
+
+debootstrap (1.0.77) unstable; urgency=medium
+
+ [ Marco d'Itri ]
+ * Fix permissions on device nodes (Closes: #812811).
+
+ -- Cyril Brulebois Wed, 27 Jan 2016 20:22:05 +0100
+
+debootstrap (1.0.76) unstable; urgency=medium
+
+ [ Marco d'Itri ]
+ * Stop creating useless device nodes (Closes: #571136).
+
+ -- Cyril Brulebois Sun, 24 Jan 2016 08:55:18 +0100
+
+debootstrap (1.0.75-1+devuan1) unstable; urgency=medium
+
+ * sync with debian upstream package
+
+ -- Franco (nextime) Lanza Wed, 02 Dec 2015 04:05:36 +0100
+
+debootstrap (1.0.75) unstable; urgency=medium
+
+ * Stop cleaning KEEP_DEBOOTSTRAP_DIR twice, as spotted by Chris Lamb
+ (Closes: #804415).
+ * Add Tanglu support (Closes: #771687), thanks to Matthias Klumpp. At
+ the moment, the following extra suites are recognized:
+ - aequorea
+ - bartholomea
+ - chromodoris
+ - dasyatis
+
+ -- Cyril Brulebois Wed, 11 Nov 2015 18:49:28 +0100
+
+debootstrap (1.0.74) unstable; urgency=medium
+
+ [ Colin Watson ]
+ * Add (Ubuntu) xenial as a symlink to gutsy.
+
+ -- Christian Perrier Tue, 03 Nov 2015 07:09:23 +0100
+
+debootstrap (1.0.73) unstable; urgency=medium
+
+ * Generate a deburis file with (package, version, uri) tuples, similar
+ to the existing debpaths.
+
+ -- Cyril Brulebois Thu, 22 Oct 2015 12:43:35 +0200
+
+debootstrap (1.0.72-1+devuan1) unstable; urgency=medium
+
+ * Rebase on debian 1.0.70 debootstrap version
+ * Added Daniel Reurich in Uploaders
+ * Integrating Daniel Reurich patches for d-i
+ * Updated manpage with Daniel Reurich changes
+
+ -- Franco (nextime) Lanza Thu, 21 May 2015 05:45:36 +0200
+
+debootstrap (1.0.72) unstable; urgency=medium
+
+ [ Iain Lane ]
+ * Add (Ubuntu) wily as a symlink to gutsy (closes: #787117).
+
+ [ Colin Watson ]
+ * Fix resolve_deps and setup_available to work in the --foreign case
+ (closes: #757819, LP: #1450980).
+
+ -- Colin Watson Tue, 28 Jul 2015 14:32:19 +0100
+
+debootstrap (1.0.71-1+devuan1) unstable; urgency=medium
+
+ * make devuan-baseconf and devuan-keyring requireds packages
+ * make sure we have sysvinit-core and not systemd in the chroot
+
+ -- Franco (nextime) Lanza Fri, 01 May 2015 02:13:04 +0200
+
+debootstrap (1.0.71) unstable; urgency=medium
+
+ * Adjust sed call to render it more portable (missing ';'), making it
+ work with FreeBSD sed. Thanks to Nikolai Lifanov for the report and
+ the patch (Closes: #791802).
+
+ -- Cyril Brulebois Fri, 10 Jul 2015 01:29:52 +0200
+
+debootstrap (1.0.70-1+devuan1) unstable; urgency=medium
+
+ * Debianization of debootstrap.
+ * added ceres script and link jessie and ascii to it
+
+ -- Franco (nextime) Lanza Sat, 11 Apr 2015 08:03:36 +0200
+
+debootstrap (1.0.70) unstable; urgency=medium
+
+ * Use tr instead of (missing in d-i) xargs (Closes: #785693). Thanks,
+ Julian Schauder!
+
+ -- Cyril Brulebois Tue, 19 May 2015 11:38:27 +0200
+
+debootstrap (1.0.69-1+devuan1) unstable; urgency=medium
+
+ * Fix package description.
+
+ -- Franco (nextime) Lanza Sat, 07 Mar 2015 21:31:07 +0100
+
+debootstrap (1.0.69) unstable; urgency=medium
+
+ [ Cyril Brulebois ]
+ * Make sure to deduplicate package list in download_release to avoid
+ issues while counting downloaded packages. The failure path could lead
+ to printing some strange integer (Closes: #709751, #768445, #785276,
+ #774752).
+ This was reported to mostly happen whenever --no-resolve-deps is used.
+ * Add support for --force-check-gpg so that one can programmatically
+ make sure keyring checks are used and that no fallback to an https
+ mirror happens (Closes: #661501, #733179, #775454).
+ * Switch default mirror from ftp.us.debian.org to the new, official
+ http redirector service: httpredir.debian.org
+ * Make it possible to override the MAKEDEV variable (Closes: #734743).
+ Thanks, Wookey!
+
+ [ Christian Perrier ]
+ * Update Standards to 3.9.6 (checked)
+
+ -- Christian Perrier Mon, 18 May 2015 14:07:43 +0200
+
+debootstrap (1.0.68-2+devuan1) unstable; urgency=medium
+
+ * Added missing symlink.
+
+ -- Franco (nextime) Lanza Sat, 07 Mar 2015 21:18:26 +0100
+
+debootstrap (1.0.68-1+devuan1) unstable; urgency=medium
+
+ * Added script for ascii.
+
+ -- Franco (nextime) Lanza Sat, 07 Mar 2015 11:47:02 +0100
+debootstrap (1.0.68) unstable; urgency=medium
+
+ [ Steven Chamberlain ]
+ * Support the jessie-kfreebsd suite, by using the same script as
+ jessie (a symlink to sid) (Closes: #784927).
+
+ -- Christian Perrier Mon, 11 May 2015 07:46:19 +0200
+
+debootstrap (1.0.67-1+devuan2) unstable; urgency=medium
+
+ * Switch to quilt format
+
+ -- Franco (nextime) Lanza Tue, 03 Mar 2015 07:44:11 +0100
+
+debootstrap (1.0.67+devuan1) unstable; urgency=medium
+
+ * Applied init freedom patch (debian bug 668001)
+ * moved to devuan
+
+ -- Franco (nextime) Lanza Tue, 03 Mar 2015 07:09:36 +0100
+
+debootstrap (1.0.67) unstable; urgency=medium
+
+ [ Cyril Brulebois ]
+ * Apply patch by Jérémy Bobbio to support reproducible builds: specify
+ a modification time on the tar side, and add the -n option to gzip
+ (Closes: #774069). Thanks, Jérémy!
+ * Update setup_apt_sources to look at USE_COMPONENTS if COMPONENTS is
+ empty, fixing the empty sources.list bug with foreign architectures
+ (Closes: #732255, #773867).
+
+ -- Christian Perrier Wed, 14 Jan 2015 07:03:17 +0100
+
+debootstrap (1.0.66) unstable; urgency=low
+
+ [ Cyril Brulebois ]
+ * Specify gzip compression in debian/source/options to allow for better
+ portability on other platforms (Closes: #770214). Thanks, Joey Hess!
+ * Specify gzip compression for debootstrap, and xz for debootstrap-udeb,
+ to mitigate the need for xz on non-Debian platforms (see: #770217).
+
+ -- Christian Perrier Mon, 24 Nov 2014 09:15:50 +0100
+
+debootstrap (1.0.65) unstable; urgency=medium
+
+ [ Julien Cristau ]
+ * Add support for stretch.
+
+ -- Christian Perrier Mon, 10 Nov 2014 09:24:56 +0100
+
+debootstrap (1.0.64) unstable; urgency=medium
+
+ * Add (Ubuntu) vivid as a symlink to gutsy.
+
+ -- Colin Watson Mon, 20 Oct 2014 16:48:49 +0100
+
+debootstrap (1.0.63) unstable; urgency=medium
+
+ [ Joey Hess ]
+ * Move set -e out of shebang line. Closes: #762713
+
+ -- Christian Perrier Thu, 25 Sep 2014 06:44:16 +0200
+
+debootstrap (1.0.62) unstable; urgency=medium
+
+ [ Cyril Brulebois ]
+ * Fix reporting of package version in retrieval and validation steps
+ to cope with epochs.
+
+ -- Christian Perrier Mon, 15 Sep 2014 11:40:54 +0200
+
+debootstrap (1.0.61) unstable; urgency=medium
+
+ * Fix "possibly the package $pkg is at fault" warnings to account for
+ changed error output in dpkg 1.17.2.
+
+ -- Colin Watson Sun, 31 Aug 2014 22:07:49 +0100
+
+debootstrap (1.0.60) unstable; urgency=medium
+
+ [ Adam Conrad ]
+ * Add (Ubuntu) utopic as a symlink to gutsy.
+
+ [ Guillem Jover ]
+ * Sync deb support with latest dpkg-deb (closes: #739136):
+ - Add uncompressed data.tar deb member support.
+ - Add uncompressed and xz control.tar deb member support.
+
+ -- Colin Watson Tue, 06 May 2014 09:37:34 +0100
+
+debootstrap (1.0.59) unstable; urgency=medium
+
+ * Install ca-certificates as well as apt-transport-https for HTTPS
+ installations. This makes it possible to copy certificates that were
+ built into the installer to /usr/local/share/ca-certificates/ and thus
+ have them continue to be trusted after installation.
+
+ -- Colin Watson Thu, 13 Feb 2014 13:42:54 +0000
+
+debootstrap (1.0.58) unstable; urgency=medium
+
+ * Policy version 3.9.5: no changes required.
+ * Install apt-transport-https if installing from an HTTPS mirror
+ (LP: #1135163). It may still be necessary to copy certificates into
+ place, but there's at least a reasonable chance that somebody installing
+ from HTTPS may want to keep using it, and we have to install
+ apt-transport-https at this point otherwise they won't be able to do
+ that end-to-end.
+
+ -- Colin Watson Tue, 11 Feb 2014 17:46:41 +0000
+
+debootstrap (1.0.57) unstable; urgency=medium
+
+ * pkgdetails_perl: Only interpret percentages following whitespace, to
+ cope with GNU wget outputting the local file name (which may contain "%"
+ due to URL-encoding) after it finishes the download (LP: #1172101).
+
+ -- Colin Watson Fri, 07 Feb 2014 16:12:23 +0000
+
+debootstrap (1.0.56) unstable; urgency=low
+
+ [ Tollef Fog Heen ]
+ * Install base-passwd and base-files in two calls rather than one to
+ avoid problems with home-built media with different ordering in
+ Packages. Thanks to Jo Shields for pointing this out and providing
+ the workaround. Closes: #601670. LP: #1001131.
+
+ [ Joey Hess ]
+ * When deboostrapping Debian, and the debian-archive-keyring is not
+ available, switch the default mirror to a https url. This way at
+ least the CA level of security is available even for users who
+ have no way to check gpg keys in the WoT. The https mirror is
+ currently https://mirrors.kernel.org/debian.
+ * Avoid writing https urls into sources.list, as apt does not support https.
+
+ -- Christian Perrier Mon, 30 Dec 2013 08:00:41 +0100
+
+debootstrap (1.0.55) unstable; urgency=low
+
+ [ Matthias Klose ]
+ * Add (Ubuntu) trusty as a symlink to gutsy.
+
+ -- Christian Perrier Tue, 22 Oct 2013 13:43:23 +0200
+
+debootstrap (1.0.53) unstable; urgency=low
+
+ [ Dmitrijs Ledkovs ]
+ * Set debian source format to '3.0 (native)'.
+ * Bump debhelper compat level to 9.
+ * Set Vcs-* to canonical format.
+
+ [ Christian Perrier ]
+ * Update Standards to 3.9.4 (checked)
+
+ -- Christian Perrier Sun, 14 Jul 2013 13:06:33 +0200
+
+debootstrap (1.0.52) unstable; urgency=low
+
+ * scripts/gutsy: Make the fake initctl pass through "initctl version"
+ calls, used by such things as invoke-rc.d to figure out whether it's
+ running under Upstart (LP: #1182540).
+ * scripts/sid, scripts/gutsy: Add a policy-rc.d, matching that in
+ debian-installer-utils. This is the primary way to disable daemon
+ startup.
+
+ -- Colin Watson Wed, 22 May 2013 16:55:59 +0100
+
+debootstrap (1.0.51) unstable; urgency=low
+
+ [ Scott Kitterman ]
+ * Add (Ubuntu) saucy as a symlink to gutsy (closes: #706989).
+
+ [ Colin Watson ]
+ * Clarify location of pkgdetails.c in error message (closes: #708771).
+ * Resolve mount point symlinks relative to the target chroot before
+ unmounting them (closes: #702861, #703037, #704744).
+
+ -- Colin Watson Sat, 18 May 2013 23:18:08 +0100
+
+debootstrap (1.0.50) unstable; urgency=low
+
+ [ Hector Oron ]
+ * Report package version information on package retrieve and validation.
+ Closes: #697675
+
+ -- Christian Perrier Fri, 17 May 2013 13:34:34 +0200
+
+debootstrap (1.0.49) unstable; urgency=medium
+
+ * Add support for jessie. Closes: #706788
+
+ -- Joey Hess Sat, 04 May 2013 23:37:52 -0400
+
+debootstrap (1.0.48) unstable; urgency=low
+
+ * Team upload
+
+ [ Julien Cristau ]
+ * Disable InRelease support. gpgv won't give us back the signed data, and
+ full gpg is not available inside d-i (closes: #703889).
+ * Move extract_release_components to after signature verification.
+ Suggested by Ansgar Burchardt.
+
+ -- Didier Raboud Thu, 04 Apr 2013 16:17:57 +0200
+
+debootstrap (1.0.47) unstable; urgency=low
+
+ * Team upload
+ * Properly decrypt the InRelease file when downloading from an archive
+ where InRelease is used. This longstanding bug was masked by former
+ APT behaviour and was revealed only with recent APT versions
+ Closes: #703146
+ Thanks to Michael Vogt for the analysis and patch
+ * Add a dependency on gpg because of the above change.
+
+ -- Christian Perrier Wed, 20 Mar 2013 21:34:29 +0100
+
+debootstrap (1.0.46) unstable; urgency=low
+
+ * Team upload.
+ * Use `which` to find out sh only if /bin/sh does not exist.
+
+ -- Samuel Thibault Thu, 27 Dec 2012 15:47:16 +0100
+
+debootstrap (1.0.45) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Better support use on Android by not hardcoding /bin/sh
+ in a test file that's created, and instead putting in the
+ actual path to sh. Closes: #694310 Thanks, Shawn Landden
+
+ -- Christian Perrier Sat, 22 Dec 2012 12:56:32 +0100
+
+debootstrap (1.0.44) unstable; urgency=low
+
+ * Remove double quotes to fix for loop on GNU/kFreeBSD, thanks to
+ Oleg Ginzburg (Closes: #693718).
+
+ -- Cyril Brulebois Tue, 20 Nov 2012 23:55:53 +0100
+
+debootstrap (1.0.43) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Fix "arc" typo. Closes: #686680
+
+ [ Colin Watson ]
+ * Add (Ubuntu) raring as a symlink to gutsy.
+
+ [ Christian Perrier ]
+ * Add myself to Uploaders and drop Anthony Towns who is no
+ longer active in debootstrap maintenance for a few years. Thanks
+ for your work, Anthony.
+ * Bump Standards to 3.9.3 (checked)
+ * Replace XC-Package-Type by Package-Type in debian/control
+
+ -- Christian Perrier Sat, 27 Oct 2012 12:46:46 +0200
+
+debootstrap (1.0.42) unstable; urgency=low
+
+ * Downgrade the absence of an InRelease file from a warning to an info
+ message. For now, debootstrap can cope fine without, and it's possible
+ there are Debian mirrors that don't have InRelease; Ubuntu doesn't quite
+ have InRelease support yet either (LP: #1017398).
+
+ -- Colin Watson Tue, 03 Jul 2012 15:34:57 +0100
+
+debootstrap (1.0.41) unstable; urgency=low
+
+ [ Mehdi Dogguy ]
+ * Add support for InRelease files (Closes: #638682)
+
+ -- Joey Hess Thu, 21 Jun 2012 13:16:22 -0400
+
+debootstrap (1.0.40) unstable; urgency=low
+
+ [ Joey Hess ]
+ * When installation or configuration of a package fails, output a message
+ that points the user to the log file. Attempt to grep out the first
+ package that dpkg failed on and show its name too. Closes: #472704
+
+ [ Colin Watson ]
+ * Add (Ubuntu) quantal as a symlink to gutsy.
+
+ -- Colin Watson Thu, 26 Apr 2012 17:44:44 +0100
+
+debootstrap (1.0.39) unstable; urgency=low
+
+ * Retry corrupted downloads rather than carrying on almost regardless.
+ Patch mostly due to Michael Gilbert, rearranged somewhat by me (closes:
+ #618920).
+ * Stop at the end of the retrieval phase if any packages failed to
+ download.
+
+ -- Colin Watson Tue, 13 Mar 2012 17:21:13 +0000
+
+debootstrap (1.0.38) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Improve error message when a decompressor is not available,
+ to indicate which package has been built with bzip today.
+ Closes: #644719
+
+ [ Otavio Salvador ]
+ * Fix --print-debs support when using --foreign param. Closes:
+ #551837.
+
+ [ Colin Watson ]
+ * pkgdetails_perl: Use the last of a sequence of stanzas for the same
+ package name, rather than the first (closes: #649319).
+
+ -- Colin Watson Mon, 21 Nov 2011 13:20:53 +0000
+
+debootstrap (1.0.37) unstable; urgency=low
+
+ * Add (Ubuntu) precise as a symlink to gutsy.
+
+ -- Colin Watson Wed, 05 Oct 2011 21:58:37 +0100
+
+debootstrap (1.0.36) unstable; urgency=low
+
+ * Guess host OS based on uname for non-Debian systems. Closes: #637363
+ * Clarify "target" in usage message.
+ * Fix support for running debootstrap on a FreeBSD host to create a kFreeBSD
+ chroot or jail. Thanks, Arno Toell.
+ * Search PATH for programs, rather than checking hardcoded locations.
+ * Support using md5 and shaN programs, as found on FreeBSD, in addition
+ to md5sum and shaNsum.
+ * When FreeBSD (not kfreebsd) is the host, don't chroot to mount special
+ filesystems.
+ * When debootstrapping on FreeBSD, warn if necessary modules are not
+ loaded. Thanks, Arno Toell.
+ * Workaround for umount bug #634107, which broke pbuilder and "debootstrap ."
+ Closes: #631087
+
+ -- Joey Hess Sun, 21 Aug 2011 18:39:26 -0400
+
+debootstrap (1.0.35) unstable; urgency=low
+
+ [ Robert Millan ]
+ * Don't build devices.tar.gz if building on GNU/kFreeBSD (closes:
+ #637297).
+ * Don't use --arch when we specifically care about the host architecture
+ (closes: #637298).
+
+ -- Colin Watson Wed, 10 Aug 2011 13:04:41 +0100
+
+debootstrap (1.0.34) unstable; urgency=low
+
+ * Add more information regarding the version and architecture in case
+ a download fails. Closes: #633625.
+ * add /usr/sbin and /sbin to PATH for fakechroot variant. Closes:
+ #588773
+ * Move setup_devices to second stage of bootstrap. Closes: #498731,
+ #531316
+
+ -- Otavio Salvador Thu, 28 Jul 2011 19:13:10 +0200
+
+debootstrap (1.0.33) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Mention minbase variant in --help. Closes: #632418
+ * Use md5sums for sarge, which did not consistently have sha1sums
+ everywhere. Closes: #633158
+
+ [ Colin Watson ]
+ * Improve text of error message when decompression command is not
+ available.
+
+ -- Otavio Salvador Sun, 24 Jul 2011 10:33:56 +0200
+
+debootstrap (1.0.32) unstable; urgency=low
+
+ * Use md5sums for woody and potato, which only had those checksums
+ in the Packages files. Closes: #627365
+
+ -- Joey Hess Mon, 30 May 2011 13:57:46 -0400
+
+debootstrap (1.0.31) unstable; urgency=low
+
+ [ Mark Hymers ]
+ * Don't use the Build-Essential: yes field in Debian, use the
+ build-essential package. Closes: #619700.
+
+ [ Colin Watson ]
+ * If ubuntu-keyring is installed, check Release signatures against it when
+ bootstrapping Ubuntu gutsy and later.
+ * Recommend ubuntu-keyring rather than debian-archive-keyring on
+ Ubuntu-derived systems.
+
+ -- Colin Watson Fri, 20 May 2011 09:45:48 +0100
+
+debootstrap (1.0.30) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Recommend debian-archive-keyring, and if it is installed,
+ default to checking gpg signatures of the Release file against it
+ when bootstrapping sid, squeeze, wheezy, etch, and lenny.
+ Closes: #560038
+ * Add --no-check-gpg option that can be used to disable release file
+ verification. Closes: #624229
+ * Needs base-installer 1.117.
+ * Add a warning message if the keyring file is not available, and
+ --no-check-gpg is not specified.
+ * Clear all global variables used for options, so that unclean
+ environment doesn't break debootstrap. Closes: #621657
+ * Removed the --boot-floppies switch and mode. Assuming this has
+ not been used in 10 years.
+
+ [ Colin Watson ]
+ * Resolve dependencies from all requested components (LP: #740167).
+
+ -- Joey Hess Tue, 26 Apr 2011 17:10:00 -0400
+
+debootstrap (1.0.29) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Support bootstrapping oldstable. (Lenny could already be bootstrapped
+ using that suite name.)
+
+ [ Colin Watson ]
+ * Add (Ubuntu) oneiric as a symlink to gutsy.
+
+ -- Colin Watson Tue, 22 Mar 2011 10:58:49 +0000
+
+debootstrap (1.0.28) unstable; urgency=low
+
+ [ Miguel Figueiredo ]
+ * Fix for ar usage, thanks to Guillem Jover. Closes: #598729
+
+ [ Joey Hess ]
+ * Remove 5 second sleeps when debootstrap finds additional required
+ dependencies. d-i just got that much faster.
+ * Use SHA checksums. Defaulting to SHA256, and configurable by
+ SHA_SIZE environment variable. Closes: #614315
+ * If a sha256sum program is not available, fall back to sha1sum.
+ This is to support debootstrap use on embedded systems, which are more
+ likely to have the latter.
+ * Avoid new(?) warning from dpkg about missing Maintainer field when
+ feigning install of a package.
+
+ -- Joey Hess Mon, 21 Feb 2011 20:48:46 -0400
+
+debootstrap (1.0.27) unstable; urgency=low
+
+ [ Miguel Figueiredo ]
+ * Fix bug and typo on --private-key
+ Patch by Jonathan Klee.
+
+ [ Jeremie Koenig ]
+ * Hurd support:
+ - Use the newer setup-translators script and firmlink
+ $TARGET/{dev,servers} in setup_devices_hurd;
+ - Don't attempt to build devices.tar.gz, which is not needed.
+
+ -- Otavio Salvador Mon, 07 Feb 2011 19:40:24 -0200
+
+debootstrap (1.0.26) unstable; urgency=low
+
+ [ Christian Perrier ]
+ * Consistently use tab indenting in scripts/gutsy and scripts/sid
+ Patch by Karl Goetz. Closes: #601821
+ * Fix a typo in the debootstrap script
+ Patch by Karl Goetz. Closes: #601822
+
+ [ Joey Hess ]
+ * sid: Remove old workaround for etch era coreutils/textutils md5sum
+ diversion problem. (#329394)
+
+ -- Otavio Salvador Fri, 12 Nov 2010 10:07:41 -0200
+
+debootstrap (1.0.25) unstable; urgency=low
+
+ * Remove debug statement that slipped in.
+ * Add test to guard against devices.tar.gz being empty.
+ * /dev/MAKEDEV cannot be relied on (udev likes to make it a symlink to
+ true). Always use /sbin/MAKEDEV. Closes: #598080
+
+ -- Joey Hess Sun, 26 Sep 2010 13:18:31 -0400
+
+debootstrap (1.0.24) unstable; urgency=low
+
+ [ Miguel Figueiredo ]
+ * Apply patches from by Jonathan Klee and Guillaume Chauvel
+ to add support to https (closes: #521196).
+
+ [ Colin Watson ]
+ * Add (Ubuntu) natty as a symlink to gutsy.
+
+ [ Joey Hess ]
+ * Add support for wheezy. Closes: #597461
+
+ -- Joey Hess Sun, 19 Sep 2010 21:40:00 -0400
+
+debootstrap (1.0.23) unstable; urgency=low
+
+ * Add (Ubuntu) maverick as a symlink to gutsy.
+ * Add ${misc:Depends}.
+
+ -- Colin Watson Wed, 19 May 2010 13:35:34 +0100
+
+debootstrap (1.0.22) unstable; urgency=low
+
+ * Redo release since it ended up with testing directory in tar.gz.
+
+ -- Otavio Salvador Mon, 22 Feb 2010 16:52:49 -0300
+
+debootstrap (1.0.21) unstable; urgency=low
+
+ [ Otavio Salvador ]
+ * Apply patch from Clint Adams to add support for
+ gz/bz2/xz data.tar (closes: #458663).
+
+ [ Guillem Jover ]
+ * Refactor deb extractors into two new functions.
+ * Use dpkg-deb if available instead of ar (closes: #557296).
+ * Add an --extractor option to override the automatic extractor selection.
+
+ [ Otavio Salvador ]
+ * Document new --extractor option in manpage.
+ * Apply patch from Vagrant Cascadian not
+ fail if resolv.conf is a broken symlink (closes: #390647).
+
+ [ Frans Pop ]
+ * Use tab indentation in scripts/debian/sid to reduce its size (relevant
+ for Debian Installer).
+ * Add apt to base packages for the buildd variant as it is no longer marked
+ Build-Essential.
+
+ [ Otavio Salvador ]
+ * Apply patch from Andres Salomon to honor
+ --components when using mirror_style 'main' (closes: #561283).
+ * Apply patch from Andres Salomon to fix
+ iteration through components in download_main (closes: #561298).
+
+ [ Joey Hess ]
+ * Allow the suite to be stable, testing, or unstable when debootstrapping
+ Debian. Closes: #288109
+ * Make scripts directory in source tree look like installed directory,
+ and add a section to README explaining an easy way to run
+ debootstrap w/o installing it. Closes: #345762
+ * Convert rules file to use dh with overrides.
+ * Remove binary-basedebs target from debian/rules.
+ This target has been broken in multiple ways since 2007. While I
+ accidentially partially fixed it with the above changes, this is evidence
+ it's dead code that can be safely removed.
+
+ -- Otavio Salvador Sun, 21 Feb 2010 23:11:06 -0300
+
+debootstrap (1.0.20) unstable; urgency=low
+
+ * For recent Ubuntu versions, move $TARGET/sbin/initctl aside in the same
+ way we do start-stop-daemon, so that attempts to control Upstart jobs
+ won't inadvertently affect jobs in the host system.
+ * Rename EXAMPLE section in debootstrap(8) to EXAMPLES (closes: #548458).
+
+ -- Colin Watson Sun, 04 Oct 2009 21:23:07 +0100
+
+debootstrap (1.0.19) unstable; urgency=low
+
+ * Ignore failures from dpkg --predep-package. It exits 1 if there are no
+ suitable packages available, which isn't an error for us, but in_target
+ complains anyway, so just use in_target_nofail; the termination
+ condition is handled immediately afterwards anyway.
+
+ -- Colin Watson Thu, 24 Sep 2009 19:57:05 +0100
+
+debootstrap (1.0.18) unstable; urgency=low
+
+ * Only use dpkg from the chroot, as there is no guarantee dpkg is
+ available outside of the chroot (d-i installation for example).
+
+ -- Aurelien Jarno Wed, 23 Sep 2009 11:37:01 +0200
+
+debootstrap (1.0.17) unstable; urgency=low
+
+ * Remove boneheaded use of sudo left over from testing (closes: #547949).
+
+ -- Colin Watson Tue, 22 Sep 2009 20:10:19 +0100
+
+debootstrap (1.0.16) unstable; urgency=low
+
+ [ Colin Watson ]
+ * Cope with pre-dependencies of included packages that aren't in Priority:
+ required (closes: #487908).
+ * Upgrade to debhelper v7. (Override rules get pretty hairy for this
+ package, so I haven't switched to dh(1).)
+ * Use ports.ubuntu.com as default mirror on sparc for Ubuntu hardy and
+ beyond (LP: #431145).
+ * Add (Ubuntu) lucid as a symlink to gutsy.
+
+ [ Frans Pop ]
+ * Makefile: remove unused ARCH variable.
+
+ -- Colin Watson Mon, 21 Sep 2009 16:28:40 +0100
+
+debootstrap (1.0.15) unstable; urgency=low
+
+ * On Linux, clear out /etc/mtab on exit if it's not a symlink. Should fix
+ problems Wouter Verhelst and Martin Michlmayr are seeing with
+ initramfs-tools MODULES=dep, although it probably isn't a perfect
+ solution.
+
+ -- Colin Watson Thu, 23 Jul 2009 16:45:00 +0100
+
+debootstrap (1.0.14) unstable; urgency=low
+
+ * Apply patch from Felix Zielcke to use "dpkg
+ --print-architecture" to avoid deprecation warning. Closes: #531680.
+ * Reference squeeze instead of sarge in manpage. Based on a patch from
+ Geoff Simmons . Closes: #534575.
+ * Apply patch from Riku Voipio to add support for
+ scratchbox variant. Closes: #536820.
+
+ -- Otavio Salvador Wed, 22 Jul 2009 12:34:54 -0300
+
+debootstrap (1.0.13) unstable; urgency=low
+
+ [ Otavio Salvador ]
+ * Apply patch from Luca Favatella to improve
+ coding style.
+
+ [ Colin Watson ]
+ * Add (Ubuntu) karmic as a symlink to gutsy.
+
+ -- Colin Watson Fri, 24 Apr 2009 20:08:24 +0100
+
+debootstrap (1.0.12) unstable; urgency=low
+
+ [ Otavio Salvador ]
+ * Improve code to choose between libc packages. Thanks to Luca Favatella
+ for first version of the patch.
+
+ [ Colin Watson ]
+ * Remove partial support for emitting translated progress messages with
+ gettext. Don't panic; d-i still has all the support necessary for this.
+ debootstrap's own support for doing this outside d-i with gettext's
+ shell bindings has been completely broken ever since it was added in
+ 2003, though, and nobody has complained. Fixing it would require a big
+ pile of infrastructure and some non-trivial patches, plus arranging to
+ copy all the translations over from base-installer, and it just doesn't
+ seem worth it, so lose the cruft (LP: #188690).
+ * Export PATH, just to make sure. It isn't necessarily exported by shells
+ running from init=/bin/sh or similar, and the upstream bash maintainer
+ is unwilling to export it by default; it's easy enough to do so here
+ (LP: #320188).
+
+ -- Colin Watson Tue, 17 Mar 2009 16:38:46 +0000
+
+debootstrap (1.0.11) unstable; urgency=low
+
+ * Add (Ubuntu) jaunty as a symlink to gutsy.
+ * Clarify that --second-stage is needed to complete the bootstrapping
+ process after --foreign.
+ * Fix --make-tarball= option (closes: #484869).
+ * Fix old Debian scripts and all Ubuntu scripts to cope with Anthony's
+ change in 1.0.8 to make --second-stage not bother recalculating required
+ and base.
+ * Rename 'repeat' to 'repeatn', since 'repeat' is a reserved word in zsh;
+ although strictly speaking this seems like an incompatibility in zsh
+ when linked to /bin/sh (closes: #340058).
+ * Fix --unpack-tarball= option (thanks, Torsten Landschoff; closes:
+ #500759).
+ * Fix handling of relative DEBOOTSTRAP_DIR (thanks, Mikhail Gusarov;
+ closes: #503460).
+ * Cope with ancient versions of chroot(8) that don't call chdir() (thanks,
+ Patrik Arvhult; closes: #350635).
+ * Recommend gnupg for --keyring option (thanks, Robert Millan; closes:
+ #467571).
+ * Note that you can't --include packages with non-required Pre-Depends
+ (see #487908).
+ * Mention /sys in EXAMPLE section of manual page, and use "defaults"
+ rather than "none" as the mount options for /proc (thanks, Raúl Sánchez
+ Siles; closes: #410787).
+ * Add /dev/console to devices.tar.gz (after all, MAKEDEV's 'consoleonly'
+ was added for boot-floppies in the first place; see
+ https://lists.ubuntu.com/archives/ubuntu-devel/2009-January/027230.html).
+ * Add support for squeeze (closes: #513488).
+
+ -- Colin Watson Wed, 18 Feb 2009 23:46:12 +0000
+
+debootstrap (1.0.10) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Avoid "broken pipe" errors in bootstrap.log from the the smallyes function.
+ The errors themselves are inherent to how the function is used, so just
+ suppress them. Closes: #480560.
+
+ [ Frans Pop ]
+ * Do not cache Release and Release.gpg files. Closes: #488424.
+ * Abort if a Packages file failed to verify.
+ * Update standards version to 3.8.0; no other changes needed.
+
+ -- Frans Pop Wed, 02 Jul 2008 17:44:25 +0200
+
+debootstrap (1.0.9) unstable; urgency=low
+
+ [ Frans Pop ]
+ * Error out on unrecognized options to avoid invalid options to be
+ recognized as arguments.
+
+ [ Colin Watson ]
+ * Use 'chown 0:0' in all scripts rather than deprecated 'chown 0.0'
+ (thanks, Evan Klitzke).
+ * Add (Ubuntu) intrepid as a symlink to gutsy.
+
+ -- Colin Watson Tue, 29 Apr 2008 19:36:19 +0100
+
+debootstrap (1.0.8) unstable; urgency=low
+
+ [ Frans Pop ]
+ * Change Priority for the udeb to extra in line with overrides file.
+
+ [ Colin Watson ]
+ * Partially revert r50134; there are people who depend on being able to
+ use the "upstream" Makefile on non-Debian systems. Create necessary
+ directories in the Makefile rather than relying on dh_installdirs to do
+ it (LP: #172645).
+ * Use ftp.us.debian.org rather than ftp.debian.org
+ (http://lists.debian.org/debian-devel-announce/2007/12/msg00002.html).
+
+ [ Anthony Towns ]
+ * Add minbase variant for the sid script that only install apt (and
+ its dependencies) instead of all of base. (Closes: Bug#351912,
+ Bug#452654)
+ * Make --second-stage not bother recalculating required and base as
+ it's not needed.
+ * Make --arch and other arguments accept both "--arch i386" and
+ "--arch=i386" forms of specifying a parameter to avoid the
+ inconsistency.
+
+ [ Stephen R. Marenka ]
+ * Allow installation of etch-m68k. (Closes: Bug#458965)
+
+ [ Colin Watson ]
+ * Add minbase variant for Ubuntu gutsy/hardy; see Anthony's change above.
+ * Minor manual page formatting improvements.
+
+ -- Colin Watson Tue, 15 Jan 2008 11:19:34 +0000
+
+debootstrap (1.0.7) unstable; urgency=low
+
+ * No longer include full devices tarball in udeb.
+ * Also try 'udpkg --print-architecture' when determining the target
+ architecture.
+ * Utility pkgdetails moved from debootstrap-udeb to bootstrap-base so that
+ the udeb can become 'Architecture: all'.
+ * Change /usr/lib/debootstrap to /usr/share/debootstrap. Closes: #430615.
+ * Use tab indentation in debootstrap and functions saving 3kB (relevant for
+ Debian Installer).
+ * Fix various inconsistencies in build scripts.
+ * Fix dpkg-genchanges warning 'missing Priority for source files'.
+ * Update Standards-Version to 3.7.2. No changes needed.
+ * Changes in udeb require base-installer 1.85.
+
+ -- Frans Pop Wed, 14 Nov 2007 12:15:45 +0100
+
+debootstrap (1.0.6) unstable; urgency=low
+
+ * Ensure that the target directory exists in check_sane_mount.
+ * Don't ignore 'make clean' errors. (The Makefile is always present.)
+
+ -- Colin Watson Sun, 21 Oct 2007 10:50:59 +0100
+
+debootstrap (1.0.5) unstable; urgency=low
+
+ [ Colin Watson ]
+ * Don't rely on GNU sed's s///I extension (closes: #350583).
+
+ [ Joey Hess ]
+ * Skip the noexec/nodev test when running --print-debs or other operations
+ that do not involve building systems.
+
+ -- Joey Hess Sat, 20 Oct 2007 23:10:34 -0400
+
+debootstrap (1.0.4) unstable; urgency=low
+
+ [ Neil Williams ]
+ * Add --second-stage-target option that allows embedded to test for
+ installations in a chroot on the device (closes: #445157).
+
+ [ Colin Watson ]
+ * Add (Ubuntu) hardy as a symlink to gutsy.
+ * Unmount /lib/init/rw on exit (closes: #391604).
+ * Cope if uncompressed Packages is missing from Release (closes: #402380).
+ * Don't rely on XSI test(1) extensions.
+ * Add support for ssh:/// URLs (thanks, Steffen Joeris; closes: #434893).
+ * Fix Ubuntu hoary and breezy scripts to unmount /dev etc. on exit
+ (closes: #327708).
+ * Emit an error if we cannot create working devices or executables on the
+ target (based on work by Bastian Kleineidam; closes: #233798).
+
+ -- Colin Watson Fri, 19 Oct 2007 14:57:37 +0100
+
+debootstrap (1.0.3) unstable; urgency=low
+
+ * Ignore errors when unmounting filesystems, to avoid stopping at the
+ first one with problems.
+
+ -- Colin Watson Tue, 21 Aug 2007 12:32:37 +0100
+
+debootstrap (1.0.2) unstable; urgency=low
+
+ [ Joey Hess ]
+ * Document --components in man page.
+ * Update man page, as packages listed in --include should now be auto
+ dep-resolved by default.
+
+ [ Colin Watson ]
+ * Extensive quoting fixes, allowing installation to a target containing
+ spaces (closes: #387673).
+ * scripts/debian/sid: Handle libc0.3 on hurd-i386 (thanks, Michael Banck;
+ closes: #314304).
+ * functions: Stub out /proc setup and add device setup for the Hurd
+ (thanks, Michael Banck; closes: #314311).
+ * Add --version option (closes: #294484).
+
+ [ Otavio Salvador ]
+ * Fix bunzip2 path. Thanks Martín Ferrari by
+ the patch (closes: #436218).
+
+ -- Otavio Salvador Tue, 07 Aug 2007 20:12:55 -0300
+
+debootstrap (1.0.1) unstable; urgency=low
+
+ * scripts/ubuntu/gutsy: Determine buildd variant dynamically using
+ Build-Essential: yes.
+ * scripts/ubuntu/gutsy.fakechroot: Remove devmapper postinst hack, no
+ longer needed.
+ * scripts/ubuntu/*.fakechroot: Merge into the corresponding main scripts
+ as variants.
+
+ -- Colin Watson Fri, 20 Jul 2007 11:55:22 +0100
+
+debootstrap (1.0.0) unstable; urgency=low
+
+ [ Anthony Towns ]
+ * Make debootstrap team maintained under the d-i banner.
+ * Add Joey, Frans and Junichi as uploaders, remove JHM (not in the
+ d-i group).
+ * Make pkgdetails.c not need C99 extensions. (Closes: Bug#398977)
+ * Fix am_doing_phase implementation in debootstrap script. Thanks to
+ Tero Janka for spotting the problem and the fix. (Closes: Bug#409881)
+
+ [ Joey Hess ]
+ * Drop support for sarge from the udeb.
+ * Update README.Debian:
+ - One todo item is done. (I think cross-strap is too, but unsure.)
+ - Reword NMU policy to note that it's team-maintained now.
+ * ACK my prior NMU. Closes: #418600
+ * If /dev/MAKEDEV DNE, as on certain s390 machines, use /sbin/MAKEDEV.
+ Closes: #420908
+ Note that /dev/MAKEDEV is still the correct location, and is still tried
+ first so that building works on all FHS systems, as noted in #190239.
+
+ [ Colin Watson ]
+ * Add support for Ubuntu dapper (Closes: #342838), edgy, feisty, and
+ gutsy. Exclude everything but gutsy from the udeb.
+ * Fix "deboostrap" typo in debootstrap(8) (thanks, Adam Conrad).
+ * Fix "htp" typo in temporary /etc/apt/sources.list.
+ * Drop support for woody from the udeb too.
+ * When removing $TARGET/debootstrap, debootstrap.log is still open as
+ stdout/stderr and needs to remain so, but after unlinking it some NFS
+ servers implement this by a temporary file in the same directory, which
+ makes it impossible to rmdir that directory. Moving it instead works
+ around the problem (thanks, Steven McCoy;
+ https://launchpad.net/bugs/65003).
+ * Fix formatting error in debootstrap(8) (.R is not a macro).
+ * Reorganise scripts into scripts/debian/ and scripts/ubuntu/ directories
+ in the source tree to declutter the top level.
+ * Add default_mirror function; reorganise the debootstrap script a little
+ so that it works. Set the default mirror for Ubuntu suites to
+ http://archive.ubuntu.com/ubuntu, and the default mirror for Debian
+ etch/lenny/sid architectures other than amd64 and i386 to
+ http://ftp.us.debian.org/debian (per ajt; see bug #363049).
+ * Add devices created by fd to devices-std.tar.gz, so that
+ /dev/std{in,out,err} is available conveniently in chroots with /proc and
+ /dev/pts mounted (thanks, Matthias Klose).
+ * Document --keyring and --make-tarball. (Closes: #368988)
+ * Update Ubuntu mirrors: warty/hoary/breezy => old-releases.ubuntu.com,
+ unsupported architectures => ports.ubuntu.com.
+ * Add myself to Uploaders.
+ * Bump to 1.0.0. Nobody uses debootstrap in production, do they?
+
+ [ Joey Hess ]
+ * Remove the extended package description (aka bloat) from the udeb.
+
+ -- Colin Watson Sat, 23 Jun 2007 02:19:27 +0100
+
+debootstrap (0.3.3.3) unstable; urgency=low
+
+ * NMU
+ * Add support for lenny.
+
+ -- Joey Hess Tue, 10 Apr 2007 15:24:15 -0400
+
+debootstrap (0.3.3.2) unstable; urgency=low
+
+ * NMU with maintainer approval
+ * Remove --force-auto-select option for 'sid' script as it is no longer
+ supported by dpkg. Closes: #409527.
+
+ -- Frans Pop Fri, 16 Feb 2007 20:43:36 +0100
+
+debootstrap (0.3.3.1) unstable; urgency=low
+
+ * NMU with maintainer approval
+ * functions/get_debs: build list of available packages from all specified
+ sources; this allows debootstrap to also use e.g. custom versions of base
+ packages from a source of local packages included on an installation CD.
+ Closes: #398762.
+
+ -- Frans Pop Thu, 16 Nov 2006 05:30:43 +0100
+
+debootstrap (0.3.3) unstable; urgency=low
+
+ * Include kFreeBSD and fakechroot support from 0.3.2.1 and 0.3.2.2 NMUs,
+ thanks to Otavio Salvador and Piotr Roszatycki. (Closes: Bug#319100,
+ Bug#328446, Bug#204652, Bug#315044, Bug#Bug#319799)
+
+ * Require target to be specified in all cases; document usage of target
+ for --print-debs. (Closes: Bug#335922, Bug#337230)
+
+ * Use ln -sf when symlinking awk for woody and sarge. (Closes: Bug#299048)
+
+ -- Anthony Towns Sun, 6 Nov 2005 04:12:39 +1000
+
+debootstrap (0.3.2.2) unstable; urgency=low
+
+ * NMU
+ * Added relicensed fakechroot variant. Closes: #204652.
+
+ -- Piotr Roszatycki Sat, 29 Oct 2005 11:29:00 +0200
+
+debootstrap (0.3.2.1) unstable; urgency=low
+
+ * NMU with maintainer approval
+ * Applied patch from Robert Millan to add support to
+ Debian GNU/kFreeBSD. Closes: #319799
+
+ -- Otavio Salvador Fri, 28 Oct 2005 16:14:57 -0200
+
+debootstrap (0.3.2) unstable; urgency=low
+
+ * Revert fakechroot NMUs (0.3.1.1, 0.3.1.3, 0.3.1.7) due to incompatible
+ license requirements (GPL) (Reopens: Bug#204652)
+
+ * Changes from 0.3.1.2 NMU, thanks to Joey Hess: (Closes: Bug#314810)
+ + Fix incorrect use of "$@" in local. Closes: #314157, #314547
+ + Fix fd redirection in download progress code. See #314373
+ + Remove md5sums file from udeb. Closes: #314378
+ + Fix debian-installer mode warning code. Closes: #314340
+
+ * Changes from 0.3.1.4 NMU, thanks to Joey Hess:
+ + Wrap eval statement in exit_function in parens, working around
+ bug #315444 in busybox sh. Closes: #314373
+
+ * Changes from 0.3.1.5 NMU, thanks to Anibal Monsalve Salazar:
+ + Fixed "--variant=buildd option does not work" for pbuilder,
+ closes: #314858. Patch by Matt Kraai .
+
+ * Changes from 0.3.1.6 NMU, thanks to Joey Hess:
+ + Patch from Colin to redirect status messages to stderr when running
+ --print-debs. Closes: #315875
+ + Restore logging to stderr in debian-installer mode. Closes: #314160
+
+ * Changes from 0.3.1.8 NMU, thanks to Petter Reinholdtsen:
+ + [functions] Mount /sys if it exist and is supported by the kernel.
+ Patch from Cajus Pollmeier, Colin Watson and Ubuntu. (Closes: #289105)
+ + [debootstrap] Document --resolve-deps in usage info. (Closes: #328161)
+ + [etch] Replace libsigc++-1.2-5c102 with libsigc++-1.2-5c2. (Closes: #334506)
+ + [etch] Remove pppoe from base, and only install
+ ipchains on m68k. Patch from Sven Luther. (Closes: #239390)
+ + [sarge] Remove duplicate entries for m68k and amd64. Patch from
+ Frans Pop. (Workaround for bug #319777)
+ + [etch] Add support for ppc64. The patch for 'sid' did no longer
+ apply. Patch from Andreas Jochens. (Closes: #313353)
+ + [sarge,etch,sid] Set DEBCONF_NONINTERACTIVE_SEEN=true during build, to
+ avoid questions during upgrade. (Closes: #238301)
+ + Add script for breezy. Patch from Colin Watson. (Closes: #315940)
+
+ * Changes from 0.3.1.9 NMU, thanks to Joey Hess:
+ + Replace the etch script with a copy of the sid script, which pulls in
+ gnupg, so the installed etch system has a usable apt. Closes: #334521
+
+ * Create /dev/ptmx in minimal devices tarball. (Closes: Bug#317072)
+
+ * Don't create empty available files, since old dpkg and new kernels can't
+ deal with them. (Closes: Bug#308169, Bug#329468)
+
+ * Bump Standards-Version. Bump debhelper compatability level to 4.
+ * Cleanup debian/rules, thanks to Joey Hess. (Closes: Bug#314863)
+
+ * Emit error message if no pkgdetails is available. (Closes: Bug#326831)
+
+ * Turn on --resolve-deps by default. Add --no-resolve-deps as an option.
+ Combined with the previous changes to make the etch script dynamically
+ determine base, this should resolve all the "can't install "
+ bugs. (Closes: Bug#280210, Bug#308361, Bug#318281, Bug#323362,
+ Bug#318254, Bug#313292, Bug#334683, Bug#248578, Bug#289635)
+
+ * md5sum doesn't exist when coreutils is unpacked but not configured;
+ cp it across so it's available for --second-stage. (Closes: Bug#329394)
+
+ * Catch failures in "dpkg --status-fd" (Closes: Bug#317447, Bug#323661)
+
+ * Make "without" work right for duplicates (Closes: Bug#316884,
+ Bug#319777)
+
+ * Simplify and correct file descriptor handling and debootstrap.log
+ behaviour.
+
+ * Delete $TARGET with --print-debs and --make-tarball. (Closes: Bug#328369)
+
+ * Add a --make-tarball option. (Closes: Bug#152845)
+
+ * Create a default sources.list for apt. (Closes: Bug#283234, Bug#315225)
+
+ * Update manpage to talk about woody instead of sarge. (Closes: Bug#315862)
+
+ * Use partial/ directory when downloading. (Closes: Bug#109176)
+
+ -- Anthony Towns Sun, 23 Oct 2005 14:49:08 +1000
+
+debootstrap (0.3.1) unstable; urgency=low
+
+ * sid script updated:
+ - Determine base dynamically (Priority: required for required packages,
+ Priority: important for base packages, Build-Essential: yes for buildd
+ variant base). (Closes: Bug#88984, Bug#193134)
+ - Use fine grained dpkg progress display, thanks again to Colin Watson.
+ (Closes: Bug#229314, Bug#231109, Bug#244563)
+
+ * dpkg output (etc) goes to /var/log/bootstrap.log in the target, rather
+ than stdout. This is probably difficult for frontends to capture
+ at present.
+
+ * Parsing of Packages file sped up. (Yay!)
+
+ * debootstrap.deb now arch: all (Closes: Bug#122465, Bug#131552)
+ - perl implementation of pkgdetails used by preference
+ - devices.tar.gz reduced to minimal set of devices; frontends should
+ setup udev or supply their own devices or similar in future
+ - /usr/lib/debootstrap/arch not shipped
+ - none of the above applies to udebs yet; though the devices.tar.gz
+ change will eventually
+
+ * Support for verifying based on Release.gpg files (--keyring). Thanks
+ to Colin Watson. (Closes: Bug#313383)
+
+ -- Anthony Towns Tue, 14 Jun 2005 00:22:55 +1000
+
+debootstrap (0.3.0) unstable; urgency=low
+
+ * The Gernot Heiser release, dedicated to everyone who drinks enough to
+ lose their better judgement, and those of us who didn't have any in
+ the first place.
+
+ * Major update. New features:
+ + Use $TARGET/debootstrap directory for state info
+ (--keep-debootstrap-dir)
+ + Support for cross-strapping (--foreign / --second-stage)
+ (Closes: Bug#202529)
+ + Support for resolving dependencies (--resolve-deps)
+ + Support for Debian etch, and Ubuntu warty and hoary (Closes: Bug#312417)
+ + Support for handling variants within the main suite script
+ + Support for other versions of base packages in /v/c/apt/archives
+ + Initial support for fine-grained dpkg progress display, thanks to
+ Colin Watson (currently only for warty and hoary)
+ + Initial support for determining base system dynamically.
+ + No longer display "debootstrap.invalid" when working with
+ Release/Packages files. (Closes: Bug#241795, Bug#256255)
+ + Ignores failures for on_exit cleanup commands. (Closes: Bug#253387,
+ Bug#253468, Bug#308774)
+ + Early reporting of unavailable packages.
+ + More efficient parsing of Packages files.
+ + Generalised additions and exclusions. (Closes: Bug#191793)
+ + Handles symlinked configuration files in /etc a little better.
+ (Closes: Bug#161987, Bug#252907, Bug#272257)
+
+ * Dropped support for slink.
+
+ * Use ln -fs for mawk/awk link. (Closes: Bug#248398, Bug#258524)
+
+ * Dropped mail-transport-agent, and hence mailx and at from sid/etch base.
+ (Closes: Bug#168473)
+ * Dropped ipchains for i386 (Closes: Bug#266119)
+ * Other minor changes to meet dependencies, also. (Closes: Bug#312701)
+
+ * Minor manpage fixes. (Closes: Bug#285777)
+ * Add check for specifying no components (CloseS: Bug#283810)
+
+ * Include 0.2.45 NMUs, thanks to Steve Langasek.
+ (Closes: Bug#295571, Bug#283752, Bug#278158)
+
+ -- Anthony Towns Sun, 12 Jun 2005 23:49:58 +1000
+
+debootstrap (0.2.45-0.2) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * [sarge, sid] Replace libparted1.6-0 with libparted1.6-12 for ia64,
+ to keep up with the ABI changes for that package. (Closes: #295571)
+ * [sarge, sid] include pciutils on hppa as well, per request of the
+ hppa folks. (Closes: #283752)
+
+ -- Steve Langasek Fri, 25 Feb 2005 22:23:30 -0800
+
+debootstrap (0.2.45-0.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * [sarge, sid] Drop libgnutls10 and libgcrypt7, since they are no
+ longer needed by exim4. (Closes: #278158).
+
+ -- Steve Langasek Thu, 20 Jan 2005 21:20:22 -0800
+
+debootstrap (0.2.45) unstable; urgency=high
+
+ * Acknowledge NMUs. (Closes: #270135)
+ * [woody.buildd] Corrected ia64 special cases. Patch by Brett Johnson
+ . (Closes: #271894)
+
+ -- J.H.M. Dassen (Ray) Sat, 18 Sep 2004 13:49:23 +0200
+
+debootstrap (0.2.44.2) unstable; urgency=low
+
+ * NMU again, this time using the makedev in unstable instead of the
+ experimental so devices.tar.gz isn't empty on ia64... oops... /o\
+
+ -- Bdale Garbee Tue, 14 Sep 2004 20:03:56 -0600
+
+debootstrap (0.2.44.1) unstable; urgency=low
+
+ * NMU to resolve d-i inability to install sid on ia64
+ * add pciutils to the base package list for ia64, to avoid having to regress
+ efibootmgr in unstable, closes: #270315, #268490
+
+ -- Bdale Garbee Mon, 13 Sep 2004 15:11:11 -0500
+
+debootstrap (0.2.44) unstable; urgency=high
+
+ * [sarge] Removed "gcc-3.0-base" and "libstdc++3" for HPPA as they have been
+ removed from sarge as well on that arch. (Closes: #268917)
+
+ -- J.H.M. Dassen (Ray) Mon, 30 Aug 2004 08:53:30 +0200
+
+debootstrap (0.2.43) unstable; urgency=high
+
+ * [sarge] Added back libgnutls10 in order not to break d-i testing.
+ (Closes: #268578, #268663).
+
+ -- J.H.M. Dassen (Ray) Sun, 29 Aug 2004 09:08:48 +0200
+
+debootstrap (0.2.42) unstable; urgency=high
+
+ * Acknowledge NMUs. (Closes: #262137, #262165, #262178, #262375)
+ * [sarge] Switch to libgnutls11 so exim4 can switch. (Closes: #268325)
+ * [sid] Removed "gcc-3.0-base" and "libstdc++3" for HPPA as they have been
+ removed from sid. (Closes: #268049)
+ * [Makefile] Make the regular video devices on all archs. (Closes: #265081)
+ * [Makefile,debootstrap] Switched away from deprecated chown syntax;
+ switched away from XSIisms '-a' and '-o'. (Closes: #256098)
+ * [debootstrap.8] Use '\-' rather than '-' in options. (Closes: #263955)
+ Confirmed that the "exlude" typo has already been fixed. (Closes: #254108)
+ Applied patch by Javier Fernández-Sanguino Peña
+ for "file" URL documentation and a more complete example. (Closes: #226662)
+
+ -- J.H.M. Dassen (Ray) Fri, 27 Aug 2004 15:40:02 +0200
+
+debootstrap (0.2.41-0.2) unstable; urgency=low
+
+ * Non-maintainer upload
+ * [sarge, sid] Add missing libgcrypt11 to base, needed by libgnutls11
+ in sid and needed in sarge for opencdk8 to be rebuilt against it
+ (closes: #262375, #262178).
+
+ -- Steve Langasek Fri, 30 Jul 2004 20:26:57 -0700
+
+debootstrap (0.2.41-0.1) unstable; urgency=low
+
+ * Non-maintainer upload with consent of JHM.
+ * Pull libfribidi0 back out of base, it's opportunistically installed
+ by d-i now for the locales that need it (closes: #262137).
+ * Re-add bootloaders on ia64, sparc, mips, hppa, and m68k to base,
+ because debian-installer isn't ready for this change (closes: #262165).
+
+ -- Steve Langasek Thu, 29 Jul 2004 14:14:33 -0700
+
+debootstrap (0.2.41) unstable; urgency=high
+
+ * High urgency upload as per tbm's request.
+ * [sarge, sid] No longer install setserial, as it causes problems on some
+ systems (e.g. #212646) and there is a consensus it is no longer needed in
+ a base environment.
+ * [sarge, sid] Removed aboot, aboot-base, elilo, efibootmgr, silo, dvhtool,
+ delo, palo, vmelilo. As per the consensus reached in the thread starting
+ with http://lists.debian.org/debian-boot/2004/04/msg00634.html, the
+ installation of boot loaders is now debian-installer's responsibility.
+ (Closes: #247906)
+ * [sarge, sid] Added libfribidi0 to base to make debconf localisation into
+ right to left languages possible. (Closes: #253229)
+ * [sarge.buildd] Drop libdb4.0 for libdb4.2 as needed by perl.
+ * [sid] Added libgnutls11 as libgnutls10 is being phased out.
+ * [Makefile] Include /dev/ida on ia64. (Closes: #258055)
+
+ -- J.H.M. Dassen (Ray) Thu, 29 Jul 2004 20:37:37 +0200
+
+debootstrap (0.2.40) unstable; urgency=medium
+
+ * [woody.buildd] Ensure the on_exit umounting of /dev/pts doesn't mess up
+ an otherwise OK exit status. (Closes: #260699)
+ * Acknowledge NMUs. (Closes: #258350, #260253)
+
+ -- J.H.M. Dassen (Ray) Thu, 22 Jul 2004 21:53:20 +0200
+
+debootstrap (0.2.39.2) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * [sarge, sid] Drop quik from powerpc, as debian-installer handles this
+ now (closes: #260253).
+
+ -- Colin Watson Thu, 22 Jul 2004 16:56:19 +0100
+
+debootstrap (0.2.39.1) unstable; urgency=low
+
+ * NMU
+ * add passwd to sid.buildd,sarge.buildd as bash depends on them
+
+ -- Junichi Uekawa Fri, 9 Jul 2004 09:07:28 +0900
+
+debootstrap (0.2.39) unstable; urgency=medium
+
+ * [sarge,sid] Dropped libdb2. Thanks Matt Zimmerman. (Closes: #250813)
+ * [sarge,sid] Dropped libident. Thanks LaMont Jones. (Closes: #251320)
+ * [sarge,sid] Dropped slang1. Thanks LaMont Jones. (Closes: #251328)
+ * [woody.buildd] Install libperl5.6. Thanks Rene Engelhard. (Closes: #251702)
+ * [sarge.buildd] Install libc6.1 rather than libc6 on alpha. Thanks Rene
+ Engelhard. (Closes: #251703)
+
+ Goswin von Brederlow
+ * Copy script for sarge to sid
+ * Add handling for amd64 to sarge/sid scripts
+ * Dropped gcc-3.2-base. (Closes: #250836)
+
+ -- J.H.M. Dassen (Ray) Sat, 5 Jun 2004 10:02:50 +0200
+
+debootstrap (0.2.38.1) unstable; urgency=low
+
+ * NMU.
+ * [sarge] Add libdb4.2 since apt-utils (0.5.25) depends on this.
+
+ -- Otavio Salvador Thu, 20 May 2004 22:18:41 -0300
+
+debootstrap (0.2.38) unstable; urgency=medium
+
+ * [woody.buildd] Readd libgdbmg1 (for perl-modules).
+
+ -- J.H.M. Dassen (Ray) Fri, 7 May 2004 10:55:13 +0200
+
+debootstrap (0.2.37) unstable; urgency=medium
+
+ * [debian/control] Bumped makedev build dependency so as not to get pty
+ permissions problems. (Closes: #246709)
+ * [sid, sid.buildd] Add/switch to libdb4.2 for the new perl packages.
+ * Acknowledge NMU 0.2.36.1. (Closes: #246368)
+
+ -- J.H.M. Dassen (Ray) Tue, 4 May 2004 07:58:02 +0200
+
+debootstrap (0.2.36.1) unstable; urgency=low
+
+ * Non-maintainer upload with maintainer permission.
+ * [sarge, sid] Drop yaboot from powerpc, as debian-installer handles this
+ now (closes: #246368).
+
+ -- Colin Watson Fri, 30 Apr 2004 00:05:02 +0100
+
+debootstrap (0.2.36) unstable; urgency=high
+
+ Joey Hess :
+ * [sid, sarge] Add a subst_package function, and use it to replace libc6
+ with libc6.1 on alpha and ia64, to avoid reordering libc in the required
+ list and work around bug #238963. (Closes: #245680)
+
+ -- J.H.M. Dassen (Ray) Sun, 25 Apr 2004 18:37:42 +0200
+
+debootstrap (0.2.35) unstable; urgency=high
+
+ * [sarge, sid] Dropped syslinux. (Closes: #205379)
+ * [woody, woody.buildd] Removed libgdbmg1. (Closes: #244447)
+ * [debootstrap, functions] Sync at the end of debootstrap. (Closes: #225742)
+
+ -- J.H.M. Dassen (Ray) Thu, 22 Apr 2004 16:51:49 +0200
+
+debootstrap (0.2.34) unstable; urgency=high
+
+ * [sid] Dropped libpci1 and libpci2 as the pciutils dependency change has
+ been reverted. (Closes: #244344)
+
+ -- J.H.M. Dassen (Ray) Thu, 22 Apr 2004 08:14:28 +0200
+
+debootstrap (0.2.33) unstable; urgency=high
+
+ * [sid] Added libpci1 and libpci2 for all archs where pciutils is installed,
+ as pciutils now depends on them. (Closes: #244344)
+
+ -- J.H.M. Dassen (Ray) Sun, 18 Apr 2004 09:41:23 +0200
+
+debootstrap (0.2.32) unstable; urgency=high
+
+ * [sarge, sid] No longer try to filter out console-tools on s390. While
+ console-tools is basically useless on s390, base-config depends on it.
+ (Closes: #241727)
+
+ -- J.H.M. Dassen (Ray) Fri, 9 Apr 2004 16:26:23 +0200
+
+debootstrap (0.2.31) unstable; urgency=medium
+
+ * [sarge] Exim has changed GnuTLS dependencies. Added libgnutls10,
+ libgcrypt7, libgpg-error0, libopencdk8, libtasn1-2; dropped libgnutls7,
+ libgcrypt1, libtasn1-0.
+ * [sarge] Removed libgnutls7, libgcrypt1, libtasn1-0.
+
+ -- J.H.M. Dassen (Ray) Tue, 23 Mar 2004 22:47:28 +0100
+
+debootstrap (0.2.30) unstable; urgency=medium
+
+ * [sarge, sid] aboot needs aboot-base. (Closes: #236368, #239302)
+
+ -- J.H.M. Dassen (Ray) Mon, 22 Mar 2004 21:10:31 +0100
+
+debootstrap (0.2.29) unstable; urgency=low
+
+ * NMU with permission of maintainer.
+ * Added {woody,sarge,sid}.buildd scripts to create build chroots.
+ Closes: #236418.
+ * Added --variant=buildd option for convenient access to these scripts.
+
+ -- Daniel Schepler Wed, 10 Mar 2004 02:29:27 -0800
+
+debootstrap (0.2.28) unstable; urgency=medium
+
+ * [sid] Exim has changed GnuTLS dependencies. Added libgnutls10, libgcrypt7,
+ libgpg-error0, libopencdk8, libtasn1-2; dropped libgnutls7, libgcrypt1,
+ libtasn1-0.
+ * [sarge,sid] Dropped lilo, mbr, modconf, libdevmapper1.00 as
+ debian-installer handles the bootloader installation and modules
+ configuration. (Closes: #232667, #232672, #232673)
+
+ -- J.H.M. Dassen (Ray) Tue, 24 Feb 2004 09:57:35 +0100
+
+debootstrap (0.2.27) unstable; urgency=medium
+
+ * [sarge] Lilo now needs libdevmapper1.00; Removed libopencdk8, libgcrypt7,
+ libgpg-error0.
+
+ -- J.H.M. Dassen (Ray) Sat, 14 Feb 2004 01:19:48 +0100
+
+debootstrap (0.2.26) unstable; urgency=medium
+
+ * [sarge] Removed gcc-3.2-base. (Closes: #230697)
+ * [sid] Lilo now needs libdevmapper1.00 .
+
+ -- J.H.M. Dassen (Ray) Tue, 3 Feb 2004 08:27:54 +0100
+
+debootstrap (0.2.25) unstable; urgency=high
+
+ * [functions] Unmount proc/bus/usb, not proc/usb. (Closes: #229122)
+
+ -- J.H.M. Dassen (Ray) Fri, 30 Jan 2004 18:01:29 +0100
+
+debootstrap (0.2.24) unstable; urgency=high
+
+ * [functions, sarge, sid] Try to unmount proc/usb, dev/shm, dev/pts on exit;
+ don't fail when there's nothing to unmount.
+ (Closes: #229122, #229901, #229907)
+ * [woody] Don't fail when there's no dev/pts to unmount.
+ * [sarge, sid] Don't install pcmcia-cs as debian-installer takes care of
+ that where needed. (Closes: #221907)
+ * [sid] Removed libopencdk8, libgcrypt7, libgpg-error0.
+ * [sarge] libopencdk8 (needed for exim4-daemon-light via libgnutls7)
+ Depends: libgcrypt7, libgpg-error0. (Closes: #229989)
+
+ -- J.H.M. Dassen (Ray) Wed, 28 Jan 2004 18:48:02 +0100
+
+debootstrap (0.2.23) unstable; urgency=high
+
+ * [sarge] Dropped libopencdk4 in favour of libopencdk8 as gnutls has switched.
+
+ -- J.H.M. Dassen (Ray) Thu, 1 Jan 2004 01:30:02 +0100
+
+debootstrap (0.2.22) unstable; urgency=high
+
+ * [sid] libopencdk8 Depends: libgcrypt7, libgpg-error0.
+
+ -- J.H.M. Dassen (Ray) Wed, 31 Dec 2003 12:35:03 +0100
+
+debootstrap (0.2.21) unstable; urgency=high
+
+ * [sarge] Added coreutils' new predependencies libacl1 and libattr1; removed
+ libsasl2 as it is no longer needed.
+
+ -- J.H.M. Dassen (Ray) Sun, 28 Dec 2003 22:54:08 +0100
+
+debootstrap (0.2.20) unstable; urgency=high
+
+ * [sarge] base-config now Depends: aptitude; aptitude Depends:
+ libsigc++-1.2-5c102.
+
+ -- J.H.M. Dassen (Ray) Sun, 28 Dec 2003 15:11:31 +0100
+
+debootstrap (0.2.19) unstable; urgency=high
+
+ * [sid] base-config now Depends: aptitude; aptitude Depends:
+ libsigc++-1.2-5c102.
+
+ -- J.H.M. Dassen (Ray) Wed, 24 Dec 2003 09:03:44 +0100
+
+debootstrap (0.2.18) unstable; urgency=low
+
+ * Thanks to Steinar Gunderson and Matt Kraii for the NMU fixing some
+ d-i related problems. (Closes: Bug#220150)
+ * Acknowledge that the problems really are fixed now. (Closes:
+ Bug#213669, Bug#209273, Bug#210912)
+
+ * Fix downloading of Packages files to retry if bz2 or gz isn't available
+ on the mirror. (Closes: Bug#194592)
+
+ -- Anthony Towns Sat, 15 Nov 2003 00:13:13 +1000
+
+debootstrap (0.2.17.1) unstable; urgency=high
+
+ * NMU
+ * [sarge,sid] Display only the package name when retrieving packages.
+ (Closes: #213669, #209273)
+ * [sarge,sid] Added progress information for downloading package
+ details. (Closes: #210912)
+
+ -- Steinar H. Gunderson Mon, 10 Nov 2003 15:11:09 +0100
+
+debootstrap (0.2.17) unstable; urgency=high
+
+ * [sarge] Fixed typo: libreadlin4 -> libreadline4. (Closes: #219655)
+
+ -- J.H.M. Dassen (Ray) Sat, 8 Nov 2003 23:23:37 +0100
+
+debootstrap (0.2.16) unstable; urgency=high
+
+ * [sarge,sid] libreadline4 is required for amiga-fdisk on powerpc.
+ (Closes: #218533)
+ * [sarge,sid] Put libreadline4 in required rather than base for ia64.
+
+ -- J.H.M. Dassen (Ray) Wed, 5 Nov 2003 08:09:41 +0100
+
+debootstrap (0.2.15) unstable; urgency=high
+
+ * ia64 fixes by Richard Hirst : (Closes: #218533)
+ * [sarge, sid] Add libreadline4 to base for ia64 as parted needs it.
+ * [sarge, sid] Remove gcc-2.96-base from required for ia64.
+
+ -- J.H.M. Dassen (Ray) Sat, 1 Nov 2003 12:58:34 +0100
+
+debootstrap (0.2.14) unstable; urgency=high
+
+ * [sarge] Made exim4 the default MTA. (Closes: #217657)
+ * [sarge] Removed libstdc++2.10-glibc2.2, libldap2 .
+ * [sid] Dropped libopencdk4 in favour of libopencdk8 as gnutls has switched.
+
+ -- J.H.M. Dassen (Ray) Tue, 28 Oct 2003 09:56:27 +0100
+
+debootstrap (0.2.13) unstable; urgency=high
+
+ * [sarge] Added libtextwrap1 for tasksel.
+
+ -- J.H.M. Dassen (Ray) Wed, 22 Oct 2003 08:10:37 +0200
+
+debootstrap (0.2.12) unstable; urgency=high
+
+ * [sarge, sid] Add libreadline4 to required for m68k as amiga-fdisk needs
+ it. (Closes: #216617)
+
+ -- J.H.M. Dassen (Ray) Mon, 20 Oct 2003 10:05:09 +0200
+
+debootstrap (0.2.11) unstable; urgency=high
+
+ * [sid] Added libc6-sparc64 lib64gcc1 lib64ncurses5 to base for sparc.
+ (Closes: #215590)
+ * [sarge, sid] Dropped libreadline as bash no longer depends on it.
+ * [sid] Dropped libstdc++2.10-glibc2.2 and its associated special cases as
+ it is no longer needed.
+
+ -- J.H.M. Dassen (Ray) Wed, 15 Oct 2003 19:42:58 +0200
+
+debootstrap (0.2.10) unstable; urgency=high
+
+ * [sid] Fixed /usr/sbin/sendmail symlink to point to exim4. (Closes: #213734)
+
+ -- J.H.M. Dassen (Ray) Sat, 4 Oct 2003 15:47:31 +0200
+
+debootstrap (0.2.9) unstable; urgency=high
+
+ * [sarge] Added libgdbm3 for man-db.
+
+ -- J.H.M. Dassen (Ray) Thu, 2 Oct 2003 23:57:09 +0200
+
+debootstrap (0.2.8) unstable; urgency=high
+
+ * [sid] Added libtextwrap1 for tasksel; removed libsasl2 as it is no longer
+ needed.
+
+ -- J.H.M. Dassen (Ray) Thu, 2 Oct 2003 07:57:16 +0200
+
+debootstrap (0.2.7) unstable; urgency=high (fixes RC d-i bug)
+
+ * [sarge] Reinstated special-case for libperl5.8; it is still needed for
+ non-i386 until sarge has perl >= 5.8.0-20. (Closes: #213280)
+ * [debian/control] Updated Standards-Version; fixed removal of slink and
+ potato scripts from udeb.
+ * [debian/control] Updated priorities; debootstrap-udeb is required (for
+ debian-installer).
+ * [debian/rules] Fixed dpkg-distaddfile accordingly.
+
+ -- J.H.M. Dassen (Ray) Tue, 30 Sep 2003 14:31:57 +0200
+
+debootstrap (0.2.6) unstable; urgency=low
+
+ * [sarge] Added e2fslibs, libcomerr2, libss2, libuuid1 for e2fsprogs.
+
+ -- J.H.M. Dassen (Ray) Fri, 26 Sep 2003 13:50:58 +0200
+
+debootstrap (0.2.5) unstable; urgency=low
+
+ * [sid] Added libgdbm3 for man-db.
+ * [sarge, sid] Dropped special-case for libperl5.8 (Closes: #210425).
+ * [sid] Make exim4 the default MTA as it is configured through debconf.
+ (Closes: #208047)
+ * [sid] Removed libldap2 which is no longer needed.
+
+ -- J.H.M. Dassen (Ray) Sun, 21 Sep 2003 13:30:49 +0200
+
+debootstrap (0.2.4) unstable; urgency=low
+
+ * [sid] Added coreutils' new predependencies libacl1 and libattr1.
+ * [debian/README.Debian] Corrected example invocation. (Closes: #206142)
+ * [debian/README.Debian] Fixed a typo.
+
+ -- J.H.M. Dassen (Ray) Wed, 20 Aug 2003 10:28:49 +0200
+
+debootstrap (0.2.3) unstable; urgency=low
+
+ * [sarge] Add new dependencies of debconf: debconf-i18n
+ liblocale-gettext-perl libtext-wrapi18n-perl libtext-charwidth-perl.
+ * Acknowledge NMU. (Closes: #203370)
+
+ -- J.H.M. Dassen (Ray) Sat, 16 Aug 2003 20:15:40 +0200
+
+debootstrap (0.2.2-0.1) unstable; urgency=low
+
+ * NMU.
+ * Fix typo in woody script. (Closes: #203370)
+
+ -- Petter Reinholdtsen Tue, 29 Jul 2003 20:29:01 +0200
+
+debootstrap (0.2.2) unstable; urgency=low
+
+ * [debian/changelog] Included entries for NMUs 0.1.17.31 through .34 whose
+ changes were incorporated by aj already.
+ * [Makefile] Invoke MAKEDEV through its FHS location (noted by Matt
+ Zimmerman). (Closes: #190239)
+ * Acknowledge older NMUs whose changes have been incoporated.
+ (Closes: #135675, #161695, #191849)
+
+ -- J.H.M. Dassen (Ray) Tue, 29 Jul 2003 18:31:49 +0200
+
+debootstrap (0.2.1) unstable; urgency=low
+
+ * The Day of the Daffodils release.
+
+ * Accept NMUs up to 0.1.17.30. Thanks guys! (Closes: Bug#148377,
+ Bug#150161, Bug#150492, Bug#153962, Bug#154463, Bug#155906,
+ Bug#160879, Bug#161469, Bug#161469, Bug#161722, Bug#163860,
+ Bug#172118, Bug#176221, Bug#179504, Bug#179725, Bug#185397,
+ Bug#187893, Bug#188053, Bug#189472, Bug#189551, Bug#190108,
+ Bug#191288, Bug#193794, Bug#193806, Bug#195012, Bug#195742,
+ Bug#199333, Bug#201066)
+ * JHM added to Uploaders.
+
+ * Change the info/error/warning/progress calls to include a unique word
+ for each string, a printf format string, and any arguments to the
+ printf string.
+ * Add support for debian-installer interaction
+
+ * Add some support for l10n. Gettext is used if it's available; no
+ translations are included as of yet. This support doesn't
+ affect debian-installer, which has its own stuff for i18n, nor
+ boot-floppies. (Closes: Bug#125647)
+
+ * Some initial support for cross-bootstrapping in the sid script.
+
+ * Use dpkg --print-installation-architecture instead of
+ --print-architecture. (Closes: Bug#138526, Bug#159720)
+
+ * Add new dependencies of debconf: debconf-i18n liblocale-gettext-perl
+ libtext-wrapi18n-perl libtext-charwidth-perl. (Closes: Bug#201066)
+ * Add new dependencies of libldap2: libgnutls7 libgcrypt1 liblzo1
+ libopencdk4 libtasn1-0 zlib1g. (Closes: Bug#201663)
+ * Remove libgdbmg1. (Closes: Bug#202304)
+ * Add new dependecies of e2fsprogs: e2fslibs libcomerr2 libss2 libuuid1.
+ (Closes: Bug#203033)
+ * Add wget to base. (Closes: Bug#145635)
+ * Switch from netkit-ping to iputils-ping.
+
+ * Changed the manpage a little. (Closes: Bug#126864)
+ * Updated README.Debian.
+
+ -- Anthony Towns Tue, 29 Jul 2003 18:15:24 +1000
+
+debootstrap (0.1.17.34) unstable; urgency=medium
+
+ * [sid] Added e2fsprogs' new predependencies (e2fslibs, libcomerr2, libss2,
+ libuuid1).
+ * [sarge] Removed libgdbmg1 as it is no longer needed.
+
+ -- J.H.M. Dassen (Ray) Sun, 27 Jul 2003 09:20:49 +0200
+
+debootstrap (0.1.17.33) unstable; urgency=medium
+
+ * [sid] Removed libgdbmg1 as it is no longer needed.
+ * [sarge] libldap2 now Depends: libgnutls7, libsasl2; added those and their
+ dependencies (libgcrypt1 liblzo1 libopencdk4 libtasn1-0 zlib1g). Dropped
+ libsasl7 in favour of libsasl2.
+
+ -- J.H.M. Dassen (Ray)