├── .github └── FUNDING.yml ├── LICENSE ├── LICENSE2 ├── README.md └── puppet.pdf /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | --- 2 | github: [bastelfreak] 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /LICENSE2: -------------------------------------------------------------------------------- 1 | Attribution-NonCommercial-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 58 | Public License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-NonCommercial-ShareAlike 4.0 International Public License 63 | ("Public License"). To the extent this Public License may be 64 | interpreted as a contract, You are granted the Licensed Rights in 65 | consideration of Your acceptance of these terms and conditions, and the 66 | Licensor grants You such rights in consideration of benefits the 67 | Licensor receives from making the Licensed Material available under 68 | these terms and conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-NC-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution, NonCommercial, and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. NonCommercial means not primarily intended for or directed towards 126 | commercial advantage or monetary compensation. For purposes of 127 | this Public License, the exchange of the Licensed Material for 128 | other material subject to Copyright and Similar Rights by digital 129 | file-sharing or similar means is NonCommercial provided there is 130 | no payment of monetary compensation in connection with the 131 | exchange. 132 | 133 | l. Share means to provide material to the public by any means or 134 | process that requires permission under the Licensed Rights, such 135 | as reproduction, public display, public performance, distribution, 136 | dissemination, communication, or importation, and to make material 137 | available to the public including in ways that members of the 138 | public may access the material from a place and at a time 139 | individually chosen by them. 140 | 141 | m. Sui Generis Database Rights means rights other than copyright 142 | resulting from Directive 96/9/EC of the European Parliament and of 143 | the Council of 11 March 1996 on the legal protection of databases, 144 | as amended and/or succeeded, as well as other essentially 145 | equivalent rights anywhere in the world. 146 | 147 | n. You means the individual or entity exercising the Licensed Rights 148 | under this Public License. Your has a corresponding meaning. 149 | 150 | 151 | Section 2 -- Scope. 152 | 153 | a. License grant. 154 | 155 | 1. Subject to the terms and conditions of this Public License, 156 | the Licensor hereby grants You a worldwide, royalty-free, 157 | non-sublicensable, non-exclusive, irrevocable license to 158 | exercise the Licensed Rights in the Licensed Material to: 159 | 160 | a. reproduce and Share the Licensed Material, in whole or 161 | in part, for NonCommercial purposes only; and 162 | 163 | b. produce, reproduce, and Share Adapted Material for 164 | NonCommercial purposes only. 165 | 166 | 2. Exceptions and Limitations. For the avoidance of doubt, where 167 | Exceptions and Limitations apply to Your use, this Public 168 | License does not apply, and You do not need to comply with 169 | its terms and conditions. 170 | 171 | 3. Term. The term of this Public License is specified in Section 172 | 6(a). 173 | 174 | 4. Media and formats; technical modifications allowed. The 175 | Licensor authorizes You to exercise the Licensed Rights in 176 | all media and formats whether now known or hereafter created, 177 | and to make technical modifications necessary to do so. The 178 | Licensor waives and/or agrees not to assert any right or 179 | authority to forbid You from making technical modifications 180 | necessary to exercise the Licensed Rights, including 181 | technical modifications necessary to circumvent Effective 182 | Technological Measures. For purposes of this Public License, 183 | simply making modifications authorized by this Section 2(a) 184 | (4) never produces Adapted Material. 185 | 186 | 5. Downstream recipients. 187 | 188 | a. Offer from the Licensor -- Licensed Material. Every 189 | recipient of the Licensed Material automatically 190 | receives an offer from the Licensor to exercise the 191 | Licensed Rights under the terms and conditions of this 192 | Public License. 193 | 194 | b. Additional offer from the Licensor -- Adapted Material. 195 | Every recipient of Adapted Material from You 196 | automatically receives an offer from the Licensor to 197 | exercise the Licensed Rights in the Adapted Material 198 | under the conditions of the Adapter's License You apply. 199 | 200 | c. No downstream restrictions. You may not offer or impose 201 | any additional or different terms or conditions on, or 202 | apply any Effective Technological Measures to, the 203 | Licensed Material if doing so restricts exercise of the 204 | Licensed Rights by any recipient of the Licensed 205 | Material. 206 | 207 | 6. No endorsement. Nothing in this Public License constitutes or 208 | may be construed as permission to assert or imply that You 209 | are, or that Your use of the Licensed Material is, connected 210 | with, or sponsored, endorsed, or granted official status by, 211 | the Licensor or others designated to receive attribution as 212 | provided in Section 3(a)(1)(A)(i). 213 | 214 | b. Other rights. 215 | 216 | 1. Moral rights, such as the right of integrity, are not 217 | licensed under this Public License, nor are publicity, 218 | privacy, and/or other similar personality rights; however, to 219 | the extent possible, the Licensor waives and/or agrees not to 220 | assert any such rights held by the Licensor to the limited 221 | extent necessary to allow You to exercise the Licensed 222 | Rights, but not otherwise. 223 | 224 | 2. Patent and trademark rights are not licensed under this 225 | Public License. 226 | 227 | 3. To the extent possible, the Licensor waives any right to 228 | collect royalties from You for the exercise of the Licensed 229 | Rights, whether directly or through a collecting society 230 | under any voluntary or waivable statutory or compulsory 231 | licensing scheme. In all other cases the Licensor expressly 232 | reserves any right to collect such royalties, including when 233 | the Licensed Material is used other than for NonCommercial 234 | purposes. 235 | 236 | 237 | Section 3 -- License Conditions. 238 | 239 | Your exercise of the Licensed Rights is expressly made subject to the 240 | following conditions. 241 | 242 | a. Attribution. 243 | 244 | 1. If You Share the Licensed Material (including in modified 245 | form), You must: 246 | 247 | a. retain the following if it is supplied by the Licensor 248 | with the Licensed Material: 249 | 250 | i. identification of the creator(s) of the Licensed 251 | Material and any others designated to receive 252 | attribution, in any reasonable manner requested by 253 | the Licensor (including by pseudonym if 254 | designated); 255 | 256 | ii. a copyright notice; 257 | 258 | iii. a notice that refers to this Public License; 259 | 260 | iv. a notice that refers to the disclaimer of 261 | warranties; 262 | 263 | v. a URI or hyperlink to the Licensed Material to the 264 | extent reasonably practicable; 265 | 266 | b. indicate if You modified the Licensed Material and 267 | retain an indication of any previous modifications; and 268 | 269 | c. indicate the Licensed Material is licensed under this 270 | Public License, and include the text of, or the URI or 271 | hyperlink to, this Public License. 272 | 273 | 2. You may satisfy the conditions in Section 3(a)(1) in any 274 | reasonable manner based on the medium, means, and context in 275 | which You Share the Licensed Material. For example, it may be 276 | reasonable to satisfy the conditions by providing a URI or 277 | hyperlink to a resource that includes the required 278 | information. 279 | 3. If requested by the Licensor, You must remove any of the 280 | information required by Section 3(a)(1)(A) to the extent 281 | reasonably practicable. 282 | 283 | b. ShareAlike. 284 | 285 | In addition to the conditions in Section 3(a), if You Share 286 | Adapted Material You produce, the following conditions also apply. 287 | 288 | 1. The Adapter's License You apply must be a Creative Commons 289 | license with the same License Elements, this version or 290 | later, or a BY-NC-SA Compatible License. 291 | 292 | 2. You must include the text of, or the URI or hyperlink to, the 293 | Adapter's License You apply. You may satisfy this condition 294 | in any reasonable manner based on the medium, means, and 295 | context in which You Share Adapted Material. 296 | 297 | 3. You may not offer or impose any additional or different terms 298 | or conditions on, or apply any Effective Technological 299 | Measures to, Adapted Material that restrict exercise of the 300 | rights granted under the Adapter's License You apply. 301 | 302 | 303 | Section 4 -- Sui Generis Database Rights. 304 | 305 | Where the Licensed Rights include Sui Generis Database Rights that 306 | apply to Your use of the Licensed Material: 307 | 308 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 309 | to extract, reuse, reproduce, and Share all or a substantial 310 | portion of the contents of the database for NonCommercial purposes 311 | only; 312 | 313 | b. if You include all or a substantial portion of the database 314 | contents in a database in which You have Sui Generis Database 315 | Rights, then the database in which You have Sui Generis Database 316 | Rights (but not its individual contents) is Adapted Material, 317 | including for purposes of Section 3(b); and 318 | 319 | c. You must comply with the conditions in Section 3(a) if You Share 320 | all or a substantial portion of the contents of the database. 321 | 322 | For the avoidance of doubt, this Section 4 supplements and does not 323 | replace Your obligations under this Public License where the Licensed 324 | Rights include other Copyright and Similar Rights. 325 | 326 | 327 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 328 | 329 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 330 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 331 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 332 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 333 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 334 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 335 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 336 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 337 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 338 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 339 | 340 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 341 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 342 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 343 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 344 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 345 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 346 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 347 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 348 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 349 | 350 | c. The disclaimer of warranties and limitation of liability provided 351 | above shall be interpreted in a manner that, to the extent 352 | possible, most closely approximates an absolute disclaimer and 353 | waiver of all liability. 354 | 355 | 356 | Section 6 -- Term and Termination. 357 | 358 | a. This Public License applies for the term of the Copyright and 359 | Similar Rights licensed here. However, if You fail to comply with 360 | this Public License, then Your rights under this Public License 361 | terminate automatically. 362 | 363 | b. Where Your right to use the Licensed Material has terminated under 364 | Section 6(a), it reinstates: 365 | 366 | 1. automatically as of the date the violation is cured, provided 367 | it is cured within 30 days of Your discovery of the 368 | violation; or 369 | 370 | 2. upon express reinstatement by the Licensor. 371 | 372 | For the avoidance of doubt, this Section 6(b) does not affect any 373 | right the Licensor may have to seek remedies for Your violations 374 | of this Public License. 375 | 376 | c. For the avoidance of doubt, the Licensor may also offer the 377 | Licensed Material under separate terms or conditions or stop 378 | distributing the Licensed Material at any time; however, doing so 379 | will not terminate this Public License. 380 | 381 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 382 | License. 383 | 384 | 385 | Section 7 -- Other Terms and Conditions. 386 | 387 | a. The Licensor shall not be bound by any additional or different 388 | terms or conditions communicated by You unless expressly agreed. 389 | 390 | b. Any arrangements, understandings, or agreements regarding the 391 | Licensed Material not stated herein are separate from and 392 | independent of the terms and conditions of this Public License. 393 | 394 | 395 | Section 8 -- Interpretation. 396 | 397 | a. For the avoidance of doubt, this Public License does not, and 398 | shall not be interpreted to, reduce, limit, restrict, or impose 399 | conditions on any use of the Licensed Material that could lawfully 400 | be made without permission under this Public License. 401 | 402 | b. To the extent possible, if any provision of this Public License is 403 | deemed unenforceable, it shall be automatically reformed to the 404 | minimum extent necessary to make it enforceable. If the provision 405 | cannot be reformed, it shall be severed from this Public License 406 | without affecting the enforceability of the remaining terms and 407 | conditions. 408 | 409 | c. No term or condition of this Public License will be waived and no 410 | failure to comply consented to unless expressly agreed to by the 411 | Licensor. 412 | 413 | d. Nothing in this Public License constitutes or may be interpreted 414 | as a limitation upon, or waiver of, any privileges and immunities 415 | that apply to the Licensor or You, including from the legal 416 | processes of any jurisdiction or authority. 417 | 418 | ======================================================================= 419 | 420 | Creative Commons is not a party to its public licenses. 421 | Notwithstanding, Creative Commons may elect to apply one of its public 422 | licenses to material it publishes and in those instances will be 423 | considered the "Licensor." Except for the limited purpose of indicating 424 | that material is shared under a Creative Commons public license or as 425 | otherwise permitted by the Creative Commons policies published at 426 | creativecommons.org/policies, Creative Commons does not authorize the 427 | use of the trademark "Creative Commons" or any other trademark or logo 428 | of Creative Commons without its prior written consent including, 429 | without limitation, in connection with any unauthorized modifications 430 | to any of its public licenses or any other arrangements, 431 | understandings, or agreements concerning use of licensed material. For 432 | the avoidance of doubt, this paragraph does not form part of the public 433 | licenses. 434 | 435 | Creative Commons may be contacted at creativecommons.org. 436 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Puppet walkthrough 2 | 3 | ## Inhaltsverzeichnis 4 | 5 | * [Best Practices für das Testen von Komponenten](#best-practices-für-das-testen-von-komponenten) 6 | * [Was ist ein Puppet Modul](#was-ist-ein-puppet-modul) 7 | * [Warum will man Linter?](#warum-will-man-linter) 8 | * [rspec](#rspec) 9 | * [rspec-puppet-facts](#rspec-puppet-facts) 10 | * [facterdb](#facterdb) 11 | * [beaker](#beaker) 12 | * [puppet-lint](#puppet-lint) 13 | * [puppet-syntax](#puppet-syntax) 14 | * [RuboCop](#rubocop) 15 | * [puppetlabs_spec_helper](#puppetlabs_spec_helper) 16 | * [Wie veröffentlicht man erfolgreich Module und welchen Mehrwert bietet es?](#wie-veröffentlicht-man-erfolgreich-module-und-welchen-mehrwert-bietet-es) 17 | * [Wie strukturiert man in der Firma seinen Code sinnvoll?](#wie-strukturiert-man-in-der-firma-seinen-code-sinnvoll) 18 | * [Wie sieht ein gutes Komponentenmodul aus](#Wie-sieht-ein-gutes-komponentenmodul-aus) 19 | * [Mehrwert durch die Veröffentlichung von Komponentenmodulen](#Mehrwert-durch-die-veröffentlichung-von-komponentenmodulen) 20 | * [Mehrwert durch Communities](#mehrwert-durch-communities) 21 | * [modulesync](#modulesync) 22 | * [Weiterführende Dokumentation](#weiterführende-dokumentation) 23 | * [Grundlagen für Continuous Integration](#grundlagen-für-continuous-integration) 24 | * [Grundlagen für interne CI](#grundlagen-für-interne-ci) 25 | * [Vorteile einer CI Pipeline](#vorteile-einer-ci-pipeline) 26 | * [Anforderungen an eine lokale CI/CD/CD Platform](#anforderungen-an-eine-lokale-cicdcd-platform) 27 | * [CI Dokumentation](#ci-dokumentation) 28 | * [Grundlagen Continuous Delivery und Continuous Deployment](#grundlagen-continuous-delivery-und-continuous-deployment) 29 | * [Continuous Delivery](#continuous-delivery) 30 | * [Continuous Delivery für Puppet Module](#continuous-delivery-für-puppet-module) 31 | * [Continuous Deployment](#continuous-deployment) 32 | * [Review der Puppetumgebung](#review-der-puppetumgebung) 33 | * [Grundsätzliches zum Tuning](#grundsätzliches-zum-tuning) 34 | * [PuppetDB](#puppetdb) 35 | * [PostgreSQL](#postgresql) 36 | * [Foreman](#foreman) 37 | * [Puppetserver](#puppetserver) 38 | * [Upgrades und kompatible Versionen](#upgrades-und-kompatible-versionen) 39 | * [Puppet 6 zu 7 Upgrade](#puppet-6-zu-7-upgrade) 40 | * [Puppet 7 Bugs](#Puppet-7-Bugs) 41 | * [Puppet Tipps und Tricks](#puppet-tipps-und-tricks) 42 | * [crl_refresh_interval aktivieren](#crl_refresh_interval-aktivieren) 43 | * [ReservedCodeCacheSize erhöhen](#reservedcodecachesize-erhöhen) 44 | * [Code Cache Nutzung protokollieren](#code-cache-nutzung-protokollieren) 45 | * [Garbage Collection Logging aktivieren](#garbage-collection-logging-aktivieren) 46 | * [JVM Heap Abbilder schreiben](#jvm-heap-abbilder-schreiben) 47 | * [dns_alt_names beim initialen Puppet run setzen](#dns_alt_names-beim-initialen-puppet-run-setzen) 48 | * [Java 11 und nicht Java 8 nutzen](#Java-11-und-nicht-java-8-nutzen) 49 | * [trusted_external_command nutzen um Inventarsysteme einzubinden](#trusted_external_command-nutzen-um-inventarsysteme-einzubinden) 50 | * [server_max_open_files erhöhen](#server_max_open_files-erhöhen) 51 | * [digest_algorithm von md5 auf sha256 ändern](#digest_algorithm-von-md5-auf-sha256-ändern) 52 | * [key_type von rsa auf ec wechseln](#key_type-von-rsa-auf-ec-wechseln) 53 | * [graph Option aktivieren](#graph-option-aktivieren) 54 | * [show_diff aktivieren](#show_diff-aktivieren) 55 | * [resubmit_facts aktivieren](#resubmit_facts-aktivieren) 56 | * [PDF](#pdf) 57 | * [Lizenz](#lizenz) 58 | * [Anmerkungen](#anmerkungen) 59 | 60 | ## Best Practices für das Testen von Komponenten 61 | 62 | ### Was ist ein Puppet Modul 63 | 64 | * Ein normales Puppet Modul kann man auch als Komponentenmodul bezeichnen 65 | * Es bündelt Puppet Klassen, welche eine einzelne Komponente verwalten (z.B. nginx oder Apache oder HAProxy) 66 | * Eine Klasse bündelt Puppet Ressourcen in einem Namespace. Dies hat wenig Klassen aus einem OOP Kontext zu sein 67 | * Man sollte eine Klasse in Puppet nicht mit einer Klasse in Java oder C# vergleichen 68 | * Jedes Komponentenmodul sollte ein eigenes Git Repository haben 69 | * Jedes Komponentenmodul ist nicht nur ein Puppet Projekt, sondern auch ein Ruby Projekt (weil `puppet` in Ruby geschrieben ist) 70 | * Ruby Projekte haben immer ein Gemfile, dies listet Ruby Abhängigkeiten für die Laufzeit, für Tests und für die Entwicklung 71 | * Ruby Projekte haben meistens ein Rakefile, dort sind Tasks definiert (ähnlich einem Makefile) 72 | * Ruby Projekte testet man (unter anderem) mit Ruby Tools 73 | 74 | Näheres dazu unter [puppetlabs_spec_helper](#puppetlabs_spec_helper). 75 | 76 | ### Warum will man Linter 77 | 78 | * In Programmiersprachen, egal ob Puppet DSL, Ruby, Rspec DSL oder andere, gibt es viele Schreibweisen für das selbe Ergebniss 79 | * Onboarding neuer Entwickler ist einfacher, wenn Code einheitlich ist 80 | * Updates sind mit einheitlichem Code einfacher 81 | * Code auf eine neue Ruby Version portieren 82 | * Code auf eine neue Puppet Version portieren 83 | * In jedem Ökosystem gibt es eine Community welche sich Style Guides ausdenkt, diesen kann man mit Lintern anwenden/erzwingen 84 | * In einer [CI Pipeline]((#grundlagen-für-continuous-integration)) sind Linter gut, da sie sehr schnell arbeiten und direkt Feedback liefern 85 | * Optional auch als pre-commit Hook lokal ausführen 86 | * Ein Linter prüft nicht zwingend den Code auf Syntax Fehler 87 | 88 | ### rspec 89 | 90 | * rspec ist ein unit testing framework in Ruby. Es bringt eine eigene [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) mit 91 | * rspec-puppet ist eine Erweiterung für rpsec, um Puppet code testen zu können 92 | * `Unit Tests` sind Tests, welche einzelne Funktionen / minimale Codeblöcke testen 93 | * `rspec-puppet` validiert, ob bestimmte Puppet Resourcen so im Katalog sind, wie man sie erwartet 94 | * korrekte Parameter, Reihenfolge der Resourcen, Prüfen ob der Katalog kompiliert 95 | 96 | ### rspec Beispiele 97 | 98 | Minimales Beispiel 99 | 100 | ```ruby 101 | # import a helper 102 | require 'spec_helper' 103 | 104 | # class we want to test 105 | describe 'borg' do 106 | # mock an FQDN 107 | let :node do 108 | 'rspec.puppet.com' 109 | end 110 | 111 | let :facts do 112 | { 113 | "operatingsystem": "CentOS", 114 | "operatingsystemmajversion": 7 115 | } 116 | end 117 | 118 | # mock class params if required 119 | # bad practice, a module should work with default data 120 | let :params do 121 | { 122 | backupserver: 'localhost' 123 | } 124 | end 125 | 126 | context 'with all defaults' do 127 | it { is_expected.to compile.with_all_deps } 128 | end 129 | end 130 | ``` 131 | 132 | * Gefühlt 80% der Probleme kann man damit lösen. Die meisten Fehler führen dazu, dass der Code nichtmal kompiliert 133 | 134 | Prüfen der einzelnen Resources: 135 | 136 | ```ruby 137 | require 'spec_helper' 138 | 139 | describe 'borg' do 140 | let :node do 141 | 'rspec.puppet.com' 142 | end 143 | 144 | on_supported_os.each do |os, facts| 145 | context "on #{os} " do 146 | let :facts do 147 | facts 148 | end 149 | 150 | let :params do 151 | { 152 | backupserver: 'localhost' 153 | } 154 | end 155 | 156 | context 'with all defaults' do 157 | it { is_expected.to compile.with_all_deps } 158 | 159 | it { is_expected.to contain_file('/etc/backup-sh-conf.sh') } 160 | it { is_expected.to contain_file('/etc/borg') } 161 | it { is_expected.to contain_file('/etc/profile.d/borg.sh') } 162 | it { is_expected.to contain_file('/usr/local/bin/borg-backup') } 163 | it { is_expected.to contain_file('/usr/local/bin/borg_exporter') } 164 | it { is_expected.to contain_file('/etc/borg-restore.cfg') } 165 | it { is_expected.to contain_class('borg::install') } 166 | it { is_expected.to contain_class('borg::config') } 167 | it { is_expected.to contain_class('borg::service') } 168 | it { is_expected.to contain_ssh__client__config__user('root') } 169 | it { is_expected.to contain_borg__ssh_keygen('root_borg') } 170 | it { is_expected.to contain_exec('ssh_keygen-root_borg') } 171 | end 172 | 173 | case facts[:os]['name'] 174 | when 'Archlinux' 175 | context 'on Archlinux' do 176 | it { is_expected.to contain_package('borg') } 177 | it { is_expected.to contain_package('perl-app-borgrestore') } 178 | end 179 | when 'Ubuntu' 180 | context 'on Ubuntu' do 181 | it { is_expected.to contain_package('borgbackup') } 182 | it { is_expected.to contain_package('borgbackup-doc') } 183 | it { is_expected.to contain_package('gcc') } 184 | it { is_expected.to contain_package('make') } 185 | it { is_expected.to contain_package('cpanminus') } 186 | it { is_expected.to contain_package('libdbd-sqlite3-perl') } 187 | if facts[:os]['release']['major'] == '16.04' 188 | it { is_expected.to contain_apt__ppa('ppa:costamagnagianfranco/borgbackup') } 189 | end 190 | end 191 | when 'RedHat', 'CentOS' 192 | context 'on osfamily Redhat' do 193 | it { is_expected.to contain_package('perl-local-lib') } 194 | it { is_expected.to contain_package('perl-Test-Simple') } 195 | it { is_expected.to contain_package('perl-App-cpanminus') } 196 | it { is_expected.to contain_package('gcc') } 197 | it { is_expected.to contain_exec('install_borg_restore') } 198 | it { is_expected.to contain_file('/opt/BorgRestore') } 199 | it { is_expected.to contain_file('/usr/local/bin/borg-restore.pl') } 200 | end 201 | when 'Gentoo' 202 | context 'on osfamily Gentoo' do 203 | it { is_expected.to contain_package('App-cpanminus') } 204 | end 205 | when 'Fedora' 206 | context 'on osfamily Fedora' do 207 | it { is_expected.to contain_package('perl-Path-Tiny') } 208 | it { is_expected.to contain_package('perl-Test-MockObject') } 209 | it { is_expected.to contain_package('perl-Test') } 210 | it { is_expected.to contain_package('perl-autodie') } 211 | end 212 | end 213 | end 214 | end 215 | end 216 | ``` 217 | 218 | Quelle ist das [puppet-borg](https://raw.githubusercontent.com/voxpupuli/puppet-borg/master/spec/classes/init_spec.rb) modul 219 | 220 | * [rspec Homepage](https://rspec.info/) 221 | * [rspec-puppet Homepage](https://rspec-puppet.com/) 222 | 223 | ## rspec-puppet-facts 224 | 225 | * Puppet Module nutzen fast immer den `$facts` Hash 226 | * In Tests muss man die Daten also mocken 227 | * Das ganze sollte konsistent (z.B. `CentOS` vs `centos`) in allen Modulen sein 228 | * Am liebsten automatisiert durch alle Betriebssysteme in der [metadata.json](https://github.com/voxpupuli/puppet-zabbix/blob/master/metadata.json#L62) iterieren und für jedes OS die Facts mocken 229 | 230 | rspec-puppet-facts macht genau das! 231 | 232 | ```ruby 233 | require 'spec_helper' 234 | 235 | describe 'borg' do 236 | let :node do 237 | 'rspec.puppet.com' 238 | end 239 | 240 | on_supported_os.each do |os, facts| 241 | context "on #{os} " do 242 | let :facts do 243 | facts 244 | end 245 | 246 | let :params do 247 | { 248 | backupserver: 'localhost' 249 | } 250 | end 251 | 252 | context 'with all defaults' do 253 | it { is_expected.to compile.with_all_deps } 254 | end 255 | end 256 | end 257 | end 258 | ``` 259 | 260 | Es ist wichtig das alle Betriebssysteme, auf denen ein Modul genutzt wird, auch in der metadata.json stehen! 261 | 262 | * [rspec-puppet-facts Homepage](https://github.com/mcanevet/rspec-puppet-facts#rspec-puppet-facts) 263 | 264 | ### facterdb 265 | 266 | * rspec-puppet-facts ermöglicht das iterieren über die metadata.json in rspec tests 267 | * die gemockten factsets kommen aus dme facterdb Projekt 268 | * Sammlung an Scripten + Vagrant configs um VMs zu starten und darin facter Versionen zu installieren 269 | * Gesammelten Daten werden als Ruby gem released 270 | 271 | Für alle genutzten Betriebssysteme sollten in dem Projekt factsets sein! 272 | 273 | * [FacterDB Homepage](https://github.com/camptocamp/facterdb#facterdb) 274 | * [Facter documentation](https://puppet.com/docs/facter/3.11/index.html) 275 | * Bugreport: [Facter 3.14 docs are broken](https://tickets.puppetlabs.com/browse/DOCUMENT-1076) 276 | 277 | ### Beaker 278 | 279 | * Acceptance testing framework für Puppet 280 | * Startet Virtualbox/Docker Instanz, führt darin das Puppet Modul aus 281 | * Idempotenz kann getestet werden 282 | * Puppet Modul zwei mal ausführen, zweiter run darf keine Änderungen zeigen 283 | * Mit rspec/serverspec kann das System inspiziert werden 284 | * Prüfen ob Packete installiert sind 285 | * Ob Services gestartet sind und laufen 286 | * Ob TCP ports offen sind 287 | * Und vieles mehr 288 | 289 | ```ruby 290 | require 'spec_helper_acceptance' 291 | 292 | describe 'zabbix::server class' do 293 | context 'default parameters' do 294 | # Using puppet_apply as a helper 295 | it 'works idempotently with no errors' do 296 | # this will actually deploy apache + postgres + zabbix-server + zabbix-web 297 | pp = <<-EOS 298 | class { 'postgresql::server': } -> 299 | class { 'zabbix::database': } -> 300 | class { 'zabbix::server': } 301 | EOS 302 | 303 | shell('yum clean metadata') if fact('os.family') == 'RedHat' 304 | 305 | # Run it twice and test for idempotency 306 | apply_manifest(pp, catch_failures: true) 307 | apply_manifest(pp, catch_changes: true) 308 | end 309 | 310 | # do some basic checks 311 | describe package('zabbix-server-pgsql') do 312 | it { is_expected.to be_installed } 313 | end 314 | 315 | describe service('zabbix-server') do 316 | it { is_expected.to be_running } 317 | it { is_expected.to be_enabled } 318 | end 319 | end 320 | end 321 | ``` 322 | 323 | [Quelle der Tests](https://github.com/voxpupuli/puppet-zabbix/blob/master/spec/acceptance/server_spec.rb) ist das voxpupuli/zabbix Modul. 324 | 325 | * Langfristig wird [OnyxPoint](https://www.onyxpoint.com/) die Entwicklung von beaker übernehmen 326 | * Puppet Inc. arbeitet an Litmus, einer Ruby Bibliothek um VMs/Container zu starten 327 | * Tests sollen hier mit Bolt ausgeführt werden 328 | 329 | * [Beaker Homepage](https://github.com/puppetlabs/beaker#beaker) 330 | * [Serverspec Homepage](https://serverspec.org/) 331 | * [Beaker-Puppet Homepage](https://github.com/puppetlabs/beaker-puppet#beaker-puppet-the-puppet-specific-beaker-library) 332 | * [Beaker-Docker Homepage](https://github.com/puppetlabs/beaker-docker#beaker-docker) 333 | * [Bolt Dokumentation](https://puppet.com/open-source/bolt/) 334 | 335 | ### puppet-lint 336 | 337 | * Ruby Projekt um verschiedene Styles in der Puppet DSL zu checken / erzwingen 338 | * Bietet ein Plugin-System 339 | * Jeder Check ist ein Plugin / eigenständiges Ruby gem 340 | * Die meisten Plugins haben eine Autokorrekturfunktion 341 | 342 | Liste der aktuell empfohlenen plugins: 343 | 344 | Gemfile: 345 | 346 | ```ruby 347 | gem 'puppet-lint-leading_zero-check', :require => false 348 | gem 'puppet-lint-trailing_comma-check', :require => false 349 | gem 'puppet-lint-version_comparison-check', :require => false 350 | gem 'puppet-lint-classes_and_types_beginning_with_digits-check', :require => false 351 | gem 'puppet-lint-unquoted_string-check', :require => false 352 | gem 'puppet-lint-variable_contains_upcase', :require => false 353 | gem 'puppet-lint-absolute_classname-check', '>= 2.0.0', :require => false 354 | gem 'puppet-lint-topscope-variable-check', :require => false 355 | gem 'puppet-lint-legacy_facts-check', :require => false 356 | gem 'puppet-lint-anchor-check', :require => false 357 | ``` 358 | 359 | man kann in der Puppet DSL gezielt einzelne Linter deaktivieren, sofern sie ein False/Positive liefern: 360 | 361 | ``` 362 | # lint:ignore:case_without_default 363 | ``` 364 | 365 | Für Fehlermeldungen in einem sinnvollen Format kann man folgendes in seinem `Rakefile` eintragen: 366 | 367 | ```ruby 368 | PuppetLint.configuration.log_format = '%{path}:%{line}:%{check}:%{KIND}:%{message}' 369 | ``` 370 | 371 | Für neue Komponentenmodule sollte man auch [puppet-lint-param-docs](https://github.com/voxpupuli/puppet-lint-param-docs#puppet-lint-parameter-documentation-check) nutzen. Dies erzwingt Dokumentation für jeden Parameter. 372 | 373 | 374 | Ausgabe mit Fehler: 375 | 376 | ``` 377 | $ bundle exec rake lint 378 | manifests/init.pp:106:arrow_on_right_operand_line:WARNING:arrow should be on the right operand's line 379 | ``` 380 | 381 | Ausgabe mit Autokorrektur: 382 | 383 | ``` 384 | $ bundle exec rake lint:auto_correct 385 | manifests/init.pp:106:arrow_on_right_operand_line:FIXED:arrow should be on the right operand's line 386 | ``` 387 | 388 | * [puppet-lint Webseite](http://puppet-lint.com/) 389 | * [Liste bekannter Community Plugins](http://puppet-lint.com/plugins/) 390 | * [Liste der Vox Pupuli Plugins](https://github.com/voxpupuli?utf8=%E2%9C%93&q=puppet-lint&type=&language=) 391 | * [Vox Pupuli hat weitere Style Guides, wofür es noch keine linter gibt](https://voxpupuli.org/docs/reviewing_pr/) 392 | 393 | ### puppet-syntax 394 | 395 | * Checkt die Syntax der Puppet DSL mit `puppet parser` 396 | * Checkt die Syntax von erb Templates mit Ruby 397 | * Checkt die Syntax von EPP Templates mit `puppet` 398 | * Checkt die Syntax von Hiera YAML Datein 399 | * Prüft auf valides YAML 400 | * Prüft auf korrekte Syntax der Keys, damit Puppet damit umgehen kann 401 | 402 | Beispielhafte Ausgabe vom Rake Task wenn es keine Fehler gibt: 403 | 404 | ``` 405 | $ bundle exec rake syntax 406 | ---> syntax:manifests 407 | ---> syntax:templates 408 | ---> syntax:hiera:yaml 409 | ``` 410 | 411 | Ausgabe mit Syntaxfehlern: 412 | 413 | ``` 414 | $ bundle exec rake syntax 415 | ---> syntax:manifests 416 | rake aborted! 417 | Could not parse for environment production: Syntax error at end of file at demo.pp:2 418 | Tasks: TOP => syntax => syntax:manifests 419 | (See full trace by running task with --trace) 420 | ``` 421 | 422 | * [puppet-syntax Homepage](https://github.com/voxpupuli/puppet-syntax#puppetsyntax) 423 | * [`puppet-parser` Dokumentation](https://puppet.com/docs/puppet/6.10/man/parser.html) 424 | * [Dokumentation über ERB Templates in Puppet](https://puppet.com/docs/puppet/6.10/lang_template_erb.html) 425 | 426 | ### RuboCop 427 | 428 | * RuboCop ist ein Linter für Ruby Datein 429 | * Er lintet keinen Puppet DSL Code, aber eigenes Types und Provider 430 | * Er lintet alle Datein mit Tests 431 | * RuboCop ist sehr schmerzhaft... 432 | * Hat aber eine autofix Option die relativ gut funktioniert 433 | 434 | Ausgabe mit Fehlern: 435 | 436 | ``` 437 | $ bundle exec rake rubocop 438 | Running RuboCop... 439 | Inspecting 4 files 440 | ..C. 441 | 442 | Offenses: 443 | 444 | spec/spec_helper.rb:8:1: C: Layout/EmptyLines: Extra blank line detected. (https://github.com/bbatsov/ruby-style-guide#two-or-more-empty-lines) 445 | 446 | 4 files inspected, 1 offense detected 447 | RuboCop failed! 448 | ``` 449 | 450 | Mit Autokorrektur: 451 | 452 | ``` 453 | bundle exec rake rubocop:auto_correct 454 | Running RuboCop... 455 | Inspecting 4 files 456 | Parser::Source::Rewriter is deprecated. 457 | Please update your code to use Parser::Source::TreeRewriter instead 458 | ..C. 459 | 460 | Offenses: 461 | 462 | spec/spec_helper.rb:8:1: C: [Corrected] Layout/EmptyLines: Extra blank line detected. (https://github.com/bbatsov/ruby-style-guide#two-or-more-empty-lines) 463 | 464 | 4 files inspected, 1 offense detected, 1 offense corrected 465 | ``` 466 | 467 | * [RuboCop Documentation](https://github.com/rubocop-hq/rubocop/blob/master/README.md) 468 | 469 | ### puppetlabs_spec_helper 470 | 471 | * gem von Puppet Inc. 472 | * Hat sehr viele der oben genannten Tools als Abhängigkeit 473 | * Puppet kümmert sich um korrekte Versionen die untereinander kompatibel sind. Man muss nur noch `puppetlabs_spec_helper` einbinden 474 | * Viele Rake Tasks sind bereits mit dabei 475 | 476 | Gemfile: 477 | ```ruby 478 | source ENV['GEM_SOURCE'] || "https://rubygems.org" 479 | gem 'puppetlabs_spec_helper' 480 | ``` 481 | 482 | Rakefile: 483 | 484 | ```ruby 485 | require 'puppetlabs_spec_helper/rake_tasks' 486 | ``` 487 | 488 | Alle Rake Tasks ausgeben: 489 | 490 | ```sh 491 | bundle exec rake -T 492 | ``` 493 | 494 | ``` 495 | rake beaker # Run beaker acceptance tests 496 | rake beaker:sets # List available beaker nodesets 497 | rake beaker:ssh[set,node] # Try to use vagrant to login to the Beaker node 498 | rake build # Build puppet module package 499 | rake build:pdk # Build Puppet module with PDK 500 | rake build:pmt # Build Puppet module package with PMT (Puppet < 6.0.0 only) 501 | rake check:dot_underscore # Fails if any ._ files are present in directory 502 | rake check:git_ignore # Fails if directories contain the files specified in .gitignore 503 | rake check:symlinks # Fails if symlinks are present in directory 504 | rake check:test_file # Fails if .pp files present in tests folder 505 | rake clean # Clean a built module package 506 | rake compute_dev_version # Print development version of module 507 | rake help # Display the list of available rake tasks 508 | rake lint # Run puppet-lint 509 | rake lint_fix # Run puppet-lint 510 | rake parallel_spec # Run spec tests in parallel and clean the fixtures directory if successful 511 | rake parallel_spec_standalone # Parallel spec tests 512 | rake release_checks # Runs all necessary checks on a module in preparation for a release 513 | rake rubocop # rubocop is not available in this installation 514 | rake spec # Run spec tests and clean the fixtures directory if successful 515 | rake spec:simplecov # Run spec tests with ruby simplecov code coverage 516 | rake spec_clean # Clean up the fixtures directory 517 | rake spec_clean_symlinks # Clean up any fixture symlinks 518 | rake spec_list_json # List spec tests in a JSON document 519 | rake spec_prep # Create the fixtures directory 520 | rake spec_standalone # Run RSpec code examples 521 | rake syntax # Syntax check Puppet manifests and templates 522 | rake syntax:hiera # Syntax check Hiera config files 523 | rake syntax:manifests # Syntax check Puppet manifests 524 | rake syntax:templates # Syntax check Puppet templates 525 | rake validate # Check syntax of Ruby files and call :syntax and :metadata_lint 526 | ``` 527 | 528 | ## Wie veröffentlicht man erfolgreich Module und welchen Mehrwert bietet es? 529 | 530 | ### Wie strukturiert man in der Firma seinen Code sinnvoll? 531 | 532 | Anforderungen: 533 | 534 | * Irgendwie muss man die ganzen [Komponentenmodule](#was-ist-ein-puppet-module-eigentlich) seinen Systemen zuweisen 535 | * Man möchte öffentliche Komponentenmodule parallel zu selbst entwickelten nutzen 536 | * Einige Systeme sind sehr ähnlich, aber doch anders 537 | * Jeder server hat SSH Passwort Authentifizierung deaktiviert, nur einer nicht 538 | * Leute möchten Daten schreiben, aber sollen keinen Puppet Code modifizieren müssen/dürfen 539 | * Z.b. festlegen welche Version von interner Software wo läuft 540 | 541 | Dies lässt sich mit dem Roles and Profiles Pattern lösen 542 | 543 | * Ein Komponentenmodul kapselt Funktionalität um eine einzige Komponente zu verwalten 544 | * Ein Profil enthält "Business-Logik" 545 | * Es kann die Reihenfolge von Komponentenmodulen setzen 546 | * z.B. epel Komponentenmodul vor Bird Komponentenmodul ausführen 547 | * Es holt sich Business Daten via Hiera 548 | * explizite `lookup()` Aufrufe oder [Automatic Class Parameter Lookup Pattern](https://puppet.com/docs/puppet/latest/hiera_automatic.html#class_parameters) 549 | * Mehrere solche Profile werden in einer Rolle gekapselt 550 | * Ein Profil kann in mehreren Rollen sein 551 | * Einem System wird immer nur eine Rolle zugewiesen 552 | * Profile und Rollen sind jeweils eigene Klassen 553 | 554 | ![roles-and-profiles-and-hiera](https://p.bastelfreak.de/daRFU/) 555 | 556 | (Copyright Craig Dunn) 557 | 558 | ### Wie sieht ein gutes Komponentenmodul aus 559 | 560 | * `include modul` funktioniert und installiert mir eine Komponente mit sinnvollen und sicheren Standardwerten 561 | * Es gibt eine README.md 562 | * Es gibt eine Lizenz 563 | * Es enthält keine Business-Logik 564 | * Irgendetwas, was firmenspezifisch ist 565 | * Das Modul sollte in jeder Umgebung funktionieren 566 | * Ansonsten wird das [Roles and Profiles Pattern]((#wie-strukturiert-man-in-der-firma-seinen-code-sinnvoll)) nicht eingehalten 567 | * Es gibt Unit- und Acceptance Tests 568 | * Aktuelle [Style Guidelines](#warum-will-man-linter) werden eingehalten 569 | * Parameter mit `puppet-strings` dokumentiert 570 | 571 | ### Mehrwert durch die Veröffentlichung von Komponentenmodulen 572 | 573 | * Ein internes Modul nachträglich veröffentlichen kann Security Probleme mitbringen 574 | * Es kann potentiell Business-Daten enthalten (Passwörter, IP-Adressen...) 575 | * Ist an Modul von Anfang an öffentlich: 576 | * achtet man auf eine sichere Implementierung 577 | * Enthält es nie Business-Logik. Diese wird dann im Profil implementiert. Dadurch is das Modul wiederverwendbar 578 | * Sofern Dokumentation vorhanden ist, wird das Modul von anderen benutzt 579 | * Man bekommt plötzlich Bug Reports und Feature Requests, die potentiell mehr / unvorgergesehene Arbeit erzeugen 580 | * Man bekommt auch Pull Requests mit neuen Features und auch Bug Fixes 581 | 582 | Es kommt vor, dass man ein öffentliches Modul patchen muss. Man muss versuchen 583 | diese Patches Upstream gemerged zu bekommen. Andernfalls difft der Fork immer 584 | mehr von Upstream ab und man landet in der Abhängigkeitshölle. Bei Modulen von 585 | Vox Pupuli / Puppet wird tendenziell schneller reagiert als bei Modulen mit 586 | einzelnen Maintainern. Puppet hat viele Mitarbeiter mit Commit Rechten für Ihre 587 | Module, Vox Pupuli hat > 140 (unregelmäßige) Maintainer. Außerdem gibt es hier 588 | Esakalationsmöglichkeiten. 589 | 590 | ### Mehrwert durch Communities 591 | 592 | * Vox Pupuli, Foreman, CERN, CamptoCamp, Puppet Inc und weitere Gruppen / Organisationen / Firmen pflegen viele Komponentenmodule 593 | * Ein Team kümmert sich um alle generischen Datein in den Modulen 594 | * Einheitliche Testmatrix 595 | * Einheitliches Testsetup 596 | * Einheitliches Gemfile 597 | * Die ganze Community hilft beim beantworten von Issues / Pull Requests 598 | * Oftmals findet man hier schon ein fertiges Modul für seinen Usecase 599 | 600 | ### modulesync 601 | 602 | * modulesync wurde von Puppet Angestellten entwickelt 603 | * Von Anfang an Open Source, mittlerweile von Vox Pupuli betreut 604 | * In einem Git Repository liegen Templates, diese werden auf alle verwalteten Module angewand 605 | * Änderungen kann man auf Modul Ebene überschreiben 606 | * Eine Hand voll Leute können damit >120 Module verwalten 607 | * Modulesync definiert auch die komplette Testmatrix für alle Module 608 | * Viele Firmen nutzen die Vox Pupuli Konfigurationen für interne Module / man kann modulesync aber auch unabhängig benutzen 609 | 610 | ### Weiterführende Dokumentation 611 | 612 | * [Erfindung des Roles and Profiles Pattern (Craig Dunn)](https://www.craigdunn.org/2012/05/239/) 613 | * [Deepdive von Gary Larizza](http://garylarizza.com/blog/2014/02/17/puppet-workflow-part-2/) 614 | * [Roles and Profiles Dokumentation (Puppet Inc.)](https://puppet.com/docs/pe/2019.2/designing_system_configs_roles_and_profiles.html) 615 | * [puppet-strings Dokumentation](https://puppet.com/docs/puppet/latest/puppet_strings.html) 616 | * [Vox Pupuli Module auf forge.puppet.com](https://forge.puppet.com/puppet?page_size=25&sort=downloads) 617 | * [Modulesync Dokumentation](https://github.com/voxpupuli/modulesync#modulesync) 618 | * [Modulesync Konfiguration für Vox Pupuli](https://github.com/voxpupuli/modulesync_config#modulesync-configs) 619 | 620 | ## Grundlagen für Continuous Integration 621 | 622 | * Jede Änderung sollte getestet werden 623 | * Testergebnisse sollten möglichst schnell sichbar sein 624 | * Tests müssen reproduzierbar sein 625 | * Tests müssen in einer sauberen Umgebung ausgeführt werden, z.B. nspawn/Docker Container oder einer VM 626 | * Tests müssen auf einer zentralen Platform ausgeführt werden 627 | * Jenkins 628 | * Gitlab-CI 629 | * Travis 630 | * Je mehr öffentliche Module man nutzt, desto weniger muss man lokal testen 631 | * Die einzelnen Communities haben eine eigene Testinfrastruktur mit passender testmatrix 632 | * Acceptance Tests für Controlrepos sind komplex zu bauen. [Onceover](https://github.com/dylanratcliffe/onceover#onceover) hilft dabei 633 | * Ordentliche Tests in allen Komponentenmodulen ist wesentlich einfacher 634 | * Acceptance Tests in jedem Komponentenmodul sollte Daten aus den eigenen Profilen enthalten 635 | * Prüft jede metadata.json: 636 | * Alle benötigten Module müssen als Dependencies gelistet sein 637 | * Alle Betriebssysteme müssen dort gelistet sein 638 | * Spec Tests müssen rspec-puppet-facts nutzen 639 | * Alle genutzten Betriebsysteme müssen in facterdb sein 640 | * Irgendwo muss noch ein Peer Review vorkommen 641 | 642 | ### Grundlagen für interne CI 643 | 644 | * Man benötigt eine Testmatrix. Für Unit Tests (im Optimalfall): 645 | * Gegen alle Ruby Versionen die man nutzt 646 | * Gegen alle Puppet Versionen die man nutzt 647 | * Gegen alle Betriebssysteme die man nutzt 648 | * Automatische Lizenzprüfung aller Abhängigkeiten 649 | * CPU Leistung: Viel hilft viel! 650 | * Wenn genug Leistung zur Verfügung steht, kann man für jeden Test eine Dockerinstanz parallel starten 651 | * Abhängigkeiten: Fehler früh erkennen 652 | * In der Regel nutzt man für Unit Tests die Master Branches der Abhängigkeiten, um noch nicht releaste Inkompatibilitäten früh zu erkennen 653 | * Für Acceptance Tests nutzt man die neusten Releases der Abhängigkeiten 654 | * Bei Neuen Modulversionen: 655 | * Die Abhängigkeiten in der ganzen Environment prüfen mit `puppet module list --environment production --tree` 656 | * In `/var/log/puppetlabs/puppetserver/puppetserver.log` nach Warnungen / Fehlern schauen 657 | 658 | ### Vorteile einer CI Pipeline 659 | 660 | * Steigerung der Codequalität 661 | * Erzwingen einer möglichst einheitlichen Codebasis 662 | * Potentielle Fehler/Bugs/unerwünschtes Verhalten erkennen bevor es passiert 663 | * Inkompatibilitäten in der Zukunft erkennen und vorbeugen, damit diese nicht eintreten 664 | * Gibt Mitarbeitern mehr Selbstbewusstsein Änderungen zu machen 665 | * Verringert auch die Einstiegshürde für andere Administratoren 666 | 667 | ### Anforderungen an eine lokale CI/CD/CD Platform 668 | 669 | * Ergebnisse müssen schnell und einfach ersichtlich sein 670 | * Testumgebungen müssen schnell verfügbar sein 671 | * R10k nutzen zum ausrollen von Environments 672 | * tar.gz Artefakte oder git tags/commits deployen, keine branches 673 | * Git Server Webhooks nehmen und Testenvironments zu erstellen sobald Commits / Branches gepusht werden 674 | * Puppet Webhook Server + Choria / mcollective / Bolt zum ausrolen 675 | 676 | SSH Multiplexing aktivieren um `git clone`s zu beschleunigen: 677 | 678 | ```puppet 679 | class profiles::ssh2git { 680 | # /root/.ssh/config entry to access git.internal 681 | ssh::client::config::user { 'gitaccess': 682 | ensure => present, 683 | user => 'root', 684 | user_home_dir => '/root', 685 | options => { 686 | 'Host git.internal' => { 687 | 'User' => 'git', 688 | 'IdentityFile' => '~/.ssh/id_ed25519...', 689 | 'ControlMaster' => 'auto', 690 | 'ControlPath' => '~/.ssh/ssh-%r@%h:%p', 691 | 'ControlPersist' => '10m' 692 | }, 693 | }, 694 | } 695 | sshkey { 'git.internal': 696 | ensure => 'present', 697 | target => '/root/.ssh/known_hosts', 698 | type => 'ecdsa-sha2-nistp256', 699 | key => 'DATA', 700 | } 701 | } 702 | ``` 703 | 704 | r10k mit mehreren Workern starten: 705 | 706 | ```puppet 707 | # puppet/r10k from Vox Pupuli 708 | class { 'r10k': 709 | version => '3.5.0', 710 | pool_size => 10, 711 | } 712 | ``` 713 | 714 | ### CI Dokumentation 715 | 716 | * [Puppet Catalog Diff Viewer von CamptoCamp](https://github.com/camptocamp/puppet-catalog-diff-viewer#puppet-catalog-diff-viewer) 717 | * [octocatalog-diff Homepage](https://github.com/github/octocatalog-diff#octocatalog-diff-) 718 | * [Installation von octocatalog-dif (Example42)](https://www.example42.com/2018/03/05/catalog-diff-on-refactoring/) 719 | * [Onceover Dokumentation](https://github.com/dylanratcliffe/onceover#onceover) 720 | * [Puppet Webhook Server Dokumentation](https://github.com/voxpupuli/puppet_webhook#puppet-webhook-server) 721 | * [Choria Webseite](https://choria.io/) 722 | * [Vortrag von Kevin Paulisse (GitHub Inc.) über CI](https://www.youtube.com/watch?v=TkzrUT-ZPQ8) 723 | 724 | ## Grundlagen Continuous Delivery und Continuous Deployment 725 | 726 | ### Continuous Delivery 727 | 728 | * Continuous Delivery - nach einem erfolgreichen CI Durchlauf Buildartefakte bauen und in einem Repository speichern 729 | * Artefakte können verschiedenste Formen haben 730 | * Ruby gem / Python Package 731 | * Docker Image 732 | * rpm / deb Paket 733 | * Puppet Modul 734 | * Ein generisches .tar.gz Archiv 735 | 736 | ### Continuous Delivery für Puppet Module 737 | 738 | Es gibt viele Möglichkeiten Puppet Module zu speichern. 739 | 740 | Folgende Projekte unterstützen Puppet Modul Releases(.tar.gz Archive): 741 | 742 | * Artifactory 743 | * Pulp 744 | * Sonatype Nexus 745 | * [kindredgroup/puppet-forge-server)](https://github.com/kindredgroup/puppet-forge-server) 746 | 747 | Alternativ kann man mit git tags / commit ids im Puppetfile arbeiten. 748 | 749 | ### Continuous Deployment 750 | 751 | * Continuous Deployment - Build Artefakte möglichst automatisiert in die Produktivumgebung bringen 752 | 753 | Mit Puppet eine große Menge an Scripten als File Resources verteilen ist ein 754 | Antipattern. Diese sollte man als Artefakte Paketieren. Puppet richtet dann das 755 | Repository auf den Zielsystemen ein. Dies gillt für alle Artefakte, welche 756 | Puppet deployen soll. 757 | 758 | Bei vielen Projekten bietet sich ein [gitflow-workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) an: 759 | 760 | * Develop Umgebung läuft auf einem individuellen Dev Branch 761 | * Test Umgebung läuft auf dem Develop Branch 762 | * Staging/Integreation Umgebung läuft auf Master Branch 763 | * Git Tags basieren auf Master Branch. Diese werden nach Produktion deployed 764 | 765 | Dies funktioniert sehr gut für intern entwickelte Anwendungen die auf anderen 766 | internen Tools aufsetzen und wiederum von anderen Teams genutzt werden. Für 767 | jede Umgebung benötigt man eigene Repositories und Maschinen/Server/Docker 768 | Images. Puppet kann solche Umgebungen deployen. Puppet Code selbst mit so einem 769 | Workflow zu verwalten funktioniert in der Regel nicht / bringt viel zu viel 770 | Overhead mit sich. 771 | 772 | Für Puppet hat sich in den meisten Organisationen ein [Git Feature Branch Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) als beste Lösung etabliert. 773 | 774 | * Im Control-Repository ist der Standardbranch `production`. Dieser wird als Environment auf normalen Nodes genutzt 775 | * Zum testen / entwickeln erzeugt man einen Feature Branch im Control-Repository + ggf im entsprechenden Modul 776 | * Push eines Branches im Control-Repo erzeugt via hooks die Environment auf den Puppetservern 777 | * Bei Merges wird Production neu deployed 778 | 779 | ## Review der Puppetumgebung 780 | 781 | Dedizierter Vortrag über [Puppetserver Skalierung](https://github.com/bastelfreak/scalingpuppetserver#scaling-puppetserver) 782 | 783 | ### Grundsätzliches zum Tuning 784 | 785 | * PuppetDB / Puppetserver CA / Compile Puppetserver / Foreman / PostgreSQL / Choria haben verschiedene Anforderungen an Hardware und kann man gut auf einzelnen Systemen installieren 786 | * Ein verteiltes System ist immer nur so stark wie ihr schwächstes Glied 787 | * Tuning Optionen sind immer stark abhängig von der Anzahl der Resources pro Node / Runinterval / Funktionen 788 | * Die Werte sollten deshalb nicht blind übernommen werden 789 | * Es sollte immer nur ein Wert gleichzeitig geändert werden um die Auswirkungen besser zu verstehen 790 | 791 | ### PuppetDB 792 | 793 | Hiera Tuningoptionen für [puppetlabs/puppetdb](https://forge.puppet.com/puppetlabs/puppetdb): 794 | 795 | ```yaml 796 | --- 797 | puppetdb::server::java_args: 798 | '-Xmx': '8192m' 799 | '-Xms': '2048m' 800 | puppetdb::server::node_ttl: '14d', 801 | puppetdb::server::node_purge_ttl: '14d', 802 | puppetdb::server::report_ttl: '999d' 803 | # default is 50 804 | puppetdb::server::max_threads: 100 805 | # default is processorcount / 2 806 | puppetdb::server::command_threads: %{facts.processors.count} 807 | # default is 4, have your database in mind 808 | puppetdb::server::concurrent_writes: 8 809 | puppetdb::server::automatic_dlo_cleanup: true 810 | ``` 811 | 812 | ### PostgreSQL 813 | 814 | Optionen für [puppetlabs/postgresql](https://forge.puppet.com/puppetlabs/postgresql): 815 | 816 | Anzahl der Verbindungen erhöhen: 817 | 818 | ```puppet 819 | postgresql::server::config_entry{'max_connections': 820 | value => 400, 821 | } 822 | ``` 823 | 824 | Laufenden PostgreSQL Server analysieren und eine optimierte Konfiguration generieren: 825 | 826 | ```sh 827 | pgtune -i /var/lib/pgsql/10/data/postgresql.conf -o postgresql.conf 828 | ``` 829 | 830 | Für PostgreSQL empfiehlt sich deren eigenes Yum Repository. Die Upstream Pakete 831 | erlauben es beliebige Versionen parallel zu installieren. Außerdem bekommt das 832 | Yum Repository am schnellsten Sicherheitsupdates. PostgreSQL hat in jeder neuen 833 | Version viele Geschwindigkeitsoptimierungen. Es sollte immer geprüft werden mit 834 | welcher neusten PostgreSQL Version PuppetDB funktioniert und diese dann genutzt 835 | werden. PuppetDB 6 und 7 in Puppet Enterprise nutzen PostgreSQL 11. Nutzer von 836 | PuppetDB 7 haben auch berichtet, dass sie erfolgreich PostgreSQL 13 einsetzen. 837 | 838 | Neben dem autovacuum, welches als gelöscht markierte Tuples entfernt, bietet 839 | sich auch die Nutzung von [pg_repack](https://reorg.github.io/pg_repack/) an. 840 | Für Puppet Enterprise wird dies mit dem 841 | [pe_databases](https://github.com/puppetlabs/puppetlabs-pe_databases) Modul 842 | konfiguriert. `pg_repack` kann Tabellen und Indexe aufräumen sowie die 843 | PostgreSQL Daten im Dateisystem neu ordnen. Somit benötigen Queries weniger IO. 844 | 845 | Hier die 3 Timer + Services aus einer PE Umgebung extrahiert. 846 | 847 | ``` 848 | # /etc/systemd/system/pe_databases-catalogs.service 849 | [Unit] 850 | Description=Service to repack PE database tables 851 | Wants=pe_databases-catalogs.timer 852 | 853 | [Service] 854 | User=pe-postgres 855 | Group=pe-postgres 856 | Type=oneshot 857 | ExecStart=/opt/puppetlabs/server/apps/postgresql/11/bin/pg_repack -d pe-puppetdb --jobs 3 -t catalogs -t catalog_resources -t catalog_inputs -t edges -t certnames 858 | 859 | [Install] 860 | WantedBy=multi-user.target 861 | 862 | # /etc/systemd/system/pe_databases-catalogs.timer 863 | [Unit] 864 | Description=Timer to trigger repacking PE database tables 865 | 866 | [Timer] 867 | OnCalendar=Sun,Thu *-*-* 04:30:00 868 | Persistent=true 869 | 870 | [Install] 871 | WantedBy=timers.target 872 | 873 | # /etc/systemd/system/pe_databases-facts.service 874 | [Unit] 875 | Description=Service to repack PE database tables 876 | Wants=pe_databases-facts.timer 877 | 878 | [Service] 879 | User=pe-postgres 880 | Group=pe-postgres 881 | Type=oneshot 882 | ExecStart=/opt/puppetlabs/server/apps/postgresql/11/bin/pg_repack -d pe-puppetdb --jobs 3 -t factsets -t fact_paths 883 | 884 | [Install] 885 | WantedBy=multi-user.target 886 | 887 | # /etc/systemd/system/pe_databases-facts.timer 888 | [Unit] 889 | Description=Timer to trigger repacking PE database tables 890 | 891 | [Timer] 892 | OnCalendar=Tue,Sat *-*-* 04:30:00 893 | Persistent=true 894 | 895 | [Install] 896 | WantedBy=timers.target 897 | 898 | # /etc/systemd/system/pe_databases-other.service 899 | [Unit] 900 | Description=Service to repack PE database tables 901 | Wants=pe_databases-other.timer 902 | 903 | [Service] 904 | User=pe-postgres 905 | Group=pe-postgres 906 | Type=oneshot 907 | ExecStart=/opt/puppetlabs/server/apps/postgresql/11/bin/pg_repack -d pe-puppetdb --jobs 3 -t producers -t resource_params -t resource_params_cache 908 | 909 | [Install] 910 | WantedBy=multi-user.target 911 | 912 | # /etc/systemd/system/pe_databases-other.timer 913 | [Unit] 914 | Description=Timer to trigger repacking PE database tables 915 | 916 | [Timer] 917 | OnCalendar=*-*-20 05:30:00 918 | Persistent=true 919 | 920 | [Install] 921 | WantedBy=timers.target 922 | ``` 923 | 924 | ### Foreman 925 | 926 | Hiera Optionen für [theforeman/foreman](https://forge.puppet.com/theforeman/foreman): 927 | 928 | ```yaml 929 | --- 930 | # default is 5 931 | foreman::db_pool: 20 932 | foreman::keepalive: true 933 | foreman::max_keepalive_requests: 1000 934 | foreman::keepalive_timeout: 180 935 | ``` 936 | 937 | Foreman läuft via Passenger. Dieser wird mit 938 | [puppetlabs/apache](https://forge.puppet.com/puppetlabs/apache) aufgesetzt. 939 | Multithreading hochdrehen: 940 | 941 | ```yaml 942 | --- 943 | apache::mod::passenger::passenger_max_pool_size: %{facts.processors.count} 944 | apache::mod::passenger::passenger_min_instances: %{facts.processors.count} 945 | ``` 946 | 947 | Foreman kann memcached als Cache nutzen: 948 | 949 | Via Puppet installieren: 950 | 951 | ```puppet 952 | # https://forge.puppet.com/saz/memcached 953 | include memcached 954 | include foreman::plugin::memcache 955 | ``` 956 | 957 | Via Hiera einstellen: 958 | 959 | ```yaml 960 | --- 961 | # 50GB of cache 962 | memcached::max_memory: 51200 963 | foreman::plugin::memcache::hosts: 964 | - 127.0.0.1 965 | ``` 966 | 967 | ### Puppetserver 968 | 969 | Puppetlabs bietet im Modul 970 | [puppetlabs/puppet_metrics_dashboard](https://forge.puppet.com/puppetlabs/puppet_metrics_dashboard) 971 | einen Monitoring Stack für Puppetserver. Dieser bietet JVM Metriken via JMX und 972 | Puppetserver Metriken via Graphite. 973 | 974 | * Eine JVM Instanz pro (logischen) CPU Kern funktioniert gut 975 | * Auf modernen CPUs auch gern 2 Instanzen pro Kern 976 | * ~800-1500 Resources pro katalog vertragen 2GB Heap pro JVM Instanz (server_jvm_max_heap_size) 977 | * Puppetserver kann zum starten weniger Ram allokieren, dies verkürzt die Bootstrap Zeit 978 | * Puppetserver hat einen Class Cache, welchen man aktivieren kann 979 | * Jede JVM Instanz hat einen Cache, dieser wird besser je länger er läuft 980 | * Serverseitige Funktionen mit memory Leaks führen zu Problemen 981 | * Jeder Restart tötet den Cache 982 | * server_max_requests_per_instance auf unendlich setzen oder mindestens 500.000 983 | * Die Option startet die JVM Instanz neu nachdem die Anzahl der Requests bearbeitet wurde, dies resettet den Cache 984 | * Man sollte die Option also nur setzen wenn man irgendwo im Code Memory leaks einer Puppet Funktion vermutet 985 | * Mehrere Puppetserver kann man via DNS Round Robin skalieren 986 | * HAProxy/Nginx als Proxy davor funktioniert besser als Round Robin 987 | * Während eines Agent runs sollte der Agent immer mit dem gleichen Backend sprechen, der Loadbalancer/Proxy muss dies beachten 988 | * nginx wurde gern zum terminieren von TLS Verbindungen direkt auf Puppetservern genutzt 989 | * Puppetserver kann dies seit 6 selbst gut 990 | * Legacy Vortrag: [bastelfreak.de/scalingpuppetserver](https://bastelfreak.de/scalingpuppetserver) ([Repo](https://github.com/bastelfreak/scalingpuppetserver)) 991 | * `file` Reports sind unnötig und benötigen oft IO/s und Inodes (`grep ^reports /etc/puppetlabs/puppet/puppet.conf`) 992 | * Jede `file` Ressource mit einer Puppetserver URL (`puppet:///`) kann zu einem eigenen HTTP Request vom Agent zum Puppetserver führen 993 | * `source => puppet:///modules/...` durch `content => file(${module_name}/)` ersetzen 994 | * Damit liest der Puppetserver die Datei ein während der Katalog kompiliert wird und bindet diese dort ein 995 | * Nachteil: Katalog wird größer; Vorteil: Weniger HTTP Verbindungen. Gerade bei Textdatein lohnt sich dies 996 | * Große Binärdatein sollten damit nicht verteilt werden. Diese sollten immer anders übertragen werden (z.b. sauber paketiert) 997 | 998 | Hiera Optionen für [theforeman/puppet](https://forge.puppet.com/theforeman/puppet): 999 | 1000 | ```puppet 1001 | $cpu_count_twice = $facts['processors']['count'] * 2 1002 | $cpu_count = $facts['processors']['count'] * 1 1003 | class{'puppet': 1004 | server_jvm_min_heap_size => "${cpu_count}G", 1005 | server_jvm_max_heap_size => "${cpu_count_twice}G", 1006 | server_max_requests_per_instance => 500000, 1007 | server_max_queued_requests => $cpu_count, 1008 | server_environment_class_cache_enabled => true, 1009 | server_jvm_extra_args => ['-XX:ReservedCodeCacheSize=2G'], 1010 | } 1011 | ``` 1012 | 1013 | ## Upgrades und kompatible Versionen 1014 | 1015 | Folgende Puppet Komponenten sind untereinander Kompatibel 1016 | 1017 | Puppet Agent | Puppetserver | PuppetDB 1018 | ------------ | ------------ | -------- 1019 | 6.x | 6.x | 6.x 1020 | 5.x | 6.x | 6.x 1021 | 4.x | 6.x | 6.x 1022 | 7.0.0 | 6.14.1 | 6.13.1 1023 | 7.0.0 | 6.14.1 | 7.0.0 1024 | 6.19.1 | 6.14.1 | 7.0.0 1025 | 1026 | ### Puppet 6 zu 7 Upgrade 1027 | 1028 | * Puppet Agent 7 funktioniert mit Puppetserver 6 / PuppetDB 6 1029 | * Puppet Agent 7 funktioniert mit Puppetserver 6 / PuppetDB 7 1030 | 1031 | Es empfiehlt sich folgender Upgrade Pfad: 1032 | 1033 | * Puppet 7 zur CI Pipeline hinzufügen und sicherstellen, dass die Module mit Puppet 7 funktionieren 1034 | * Die einzelnen Agents auf die neusten Puppet 6 Version updaten 1035 | * Wenn dies erfolgreich war, die Agents auf Version 7 updaten 1036 | * PuppetDB von 6 auf 7 Updaten 1037 | * Während des Updates erfolgen Datenbank Migrationen. Je nach Anzahl der Reports kann dies mehrere Stunden dauern 1038 | * Während der Migration ist PuppetDB nicht nutzbar 1039 | * Man kann vor der Migration die [TTL für Reports heruntersetzen](https://puppet.com/docs/puppetdb/latest/configure.html#report-ttl) und diese damit löschen. Dies reduziert die Downtime 1040 | * Puppetserver können danach geupdated werden 1041 | 1042 | ### Puppet 7 Bugs 1043 | 1044 | Liste an bekannten Bugs, welche große Auswirkungen haben könnten bei einem Upgrade (Stand 2020-11-24): 1045 | 1046 | * https://tickets.puppetlabs.com/browse/PUP-10793 - Fact is undef with Puppet 6 but empty string with Puppet 7 1047 | * https://tickets.puppetlabs.com/browse/FACT-2880 - facter 4 differing output from facter 3 for service_provider fact 1048 | * https://tickets.puppetlabs.com/browse/PUP-10790 - user provider with uid/gid as Integer raises warning 1049 | 1050 | Seit Q2 2021 sind keine offenen Bugs bekannt die ein Upgrade von Puppet 6 zu Puppet 7 behindern 1051 | 1052 | ## Puppet Tipps und Tricks 1053 | 1054 | ### [crl_refresh_interval](https://puppet.com/docs/puppet/latest/configuration.html#crl_refresh_interval) aktivieren 1055 | 1056 | Auf sehr vielen System wird das Puppet Agent Zertifikat für einen lokalen 1057 | Webserver zweckentfremdet. Oft ebenfalls mit Klientzertifikatsvalidierung. Dies 1058 | funktioniert nur sinnvoll mit einer aktuellen CRL (Certificate Revocation List 1059 | - Liste der von der Puppetserver CA zurückgezogenen Zertifikaten). Beim 1060 | initialen Puppet Lauf wird die CRL vom Puppetserver heruntergeladen, danach 1061 | aber nie aktualisiert. Viele Leute nutzen dafür einen systemd timer um die 1062 | Datei periodisch herunterzuladen. Puppet kann dies seit Version 1063 | [6.5.0](https://puppet.com/docs/puppet/6/release_notes_puppet.html#new_features_puppet_x-5-0-sepcifyc-refresh-interval-crls) 1064 | selbst periodisch aktualisieren. 1065 | 1066 | ### ReservedCodeCacheSize erhöhen 1067 | 1068 | Es gibt viele Mythen über die korrekten Optionen für die JVM. Die Kurzfassung: 1069 | `-XX:ReservedCodeCacheSize=2G` sollte immer der Puppetserver JVM mitgegeben 1070 | werden. Details dazu gibt es unter [PUP-10225](https://tickets.puppetlabs.com/browse/PUP-10225) 1071 | sowie [SERVER-2771](https://tickets.puppetlabs.com/browse/SERVER-2771). Dies 1072 | behebt 99% der Performanceprobleme die Leute nach dem Upgrade von Puppetserver 1073 | 5 haben. Langfristig soll die Option standardmäßig im Puppetserver gesetzt 1074 | sein. Puppet Inc ist leider etwas träge was das updaten der Doku/Pakete angeht. 1075 | Nähere Informationen zu der Option gibt es in der 1076 | [offiziellen Java Dokumentation](https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE__GUID-3CFE74F1-EBAF-4FDA-8472-9C4D583D2723). 1077 | Außerdem hat Baeldung dazu [noch einen Artikel](https://www.baeldung.com/jvm-code-cache) 1078 | Der Blog ist eine sehr gute Anlaufstelle für Artikel über Java, JVM und Spring. 1079 | 1080 | Der Default Wert beträgt, je nach Java Version, 48MB. Dies ist für Java 1081 | Applikationen oftmals vollkommen ausreichend. Für Jruby wird allerdings 1082 | wesentlich mehr benötigt. 1083 | 1084 | ### Code Cache Nutzung protokollieren 1085 | 1086 | Um die Ramnutzung etwas transparenter zu gestalten kann man die JVM Option 1087 | `-XX:+PrintCodeCache` setzen. Damit loggt diese die Nutzung/Auslastung des 1088 | Code Caches. 1089 | 1090 | ### Garbage Collection Logging aktivieren 1091 | 1092 | Puppetserver und PuppetDB werden innerhalb der JVM ausgeführt. Diese führt 1093 | regelmäßig eine Garbage Collection durch. Hierbei werden nicht mehr benötigte 1094 | Objekte aus dem Arbeitspeicher entfernt. Je mehr Aktivit innerhalb der JVM 1095 | existiert und je näher der genutzte Ram an der Heap Grenze ist, desto 1096 | agressiver und öfter arbeitet der Garbage Collector. In der Regel läuft dieser 1097 | periodisch zum Puppetserver/PuppetDB. Sollte er Ram nicht freigeben können kann 1098 | es vorkommen, dass er die Applikation kurzzeitiig pausiert. All diese 1099 | Informationen kann die JVM in eine Logdatei schreiben. Dies ist nützlich um 1100 | die Arbeitspeichernutzung zu prüfen und ggf den Heap zu vergrößern/verringern. 1101 | Aktiviert wird es mit folgender Option: 1102 | `-Xlog:gc*:file=/gc.log::filecount=16,filesize=20m` 1103 | Dies aktiviert das Logging in die Datei gc.log. Sobald die Datei 20MB Größe 1104 | erreicht wird die rotiert. Es werden 16 Datein vorgehalten. Für Puppetserver 1105 | empfiehlt sich der Pfad `/var/log/puppetlabs/puppetserver/puppetserver_gc.log`, 1106 | für PuppetDB `/var/log/puppetlabs/puppetdb/puppetdb_gc.log`. 1107 | 1108 | Es gibt verschiedene Tools, welche die Logs auswerten können. Eine simple 1109 | Version ist der Upload auf https://gceasy.io/. 1110 | 1111 | ### JVM Heap Abbilder schreiben 1112 | 1113 | Sobald die JVM versucht mehr Arbeitsspeicher zu nutzen als verfügbar/Heap 1114 | erlaubt, läuft die JVM in einen Out of Memory Fehler und wird beendet. Sofern 1115 | dies passiert kann die JVM ein Abbild des Heaps auf das Dateisystem schreiben. 1116 | Out of Memory Fehler werden provoziert wenn Heap massiv zu klein konfiguriert 1117 | ist oder ein Puppet Modul irgendeine Funktion bereitstellt die Memory Leaks 1118 | verursacht. Wenn `max_requests_per_instance` im Puppetserver gesetzt ist werden 1119 | Memory Leaks eventuell verschleiert weil die einzelnen JVM Instanzen regelmäßig 1120 | neugestartet werden. Die erzeugten Abbilder können mit verschiedenen Tools 1121 | analysiert und visualisiert werden. 1122 | 1123 | ### dns_alt_names beim initialen Puppet run setzen 1124 | 1125 | Damit mindestens Webbrowser TLS Zertifikate als valide empfinden muss ein FQDN 1126 | als Subject Alternative Name im Zertifikat gesetzt werden. Chrome erfordert 1127 | dies [seit Version 58](https://www.chromestatus.com/feature/4981025180483584). 1128 | Puppet setzt bis Puppetserver 6.15.3 ausschließlich den alten Common Name. Als 1129 | Workaround kann man den initialen Puppet run starten mit: 1130 | `puppet agent -t --dns_alt_names=$(hostname -f)`. Sofern ein Server mehrere FQDNs 1131 | hat die auf ihn zeigen kann man der Option auch eine Kommaseparierte Liste 1132 | mitgeben. [Seit Puppetserver 6.15.3 bzw. 7.1.0](https://tickets.puppetlabs.com/browse/SERVER-2338) 1133 | setzt die Puppetserver CA den Common Name ebenfalls als Subject Alternative 1134 | Name. 1135 | 1136 | ### Java 11 und nicht Java 8 nutzen 1137 | 1138 | Je nach Version vom Puppetserver und PuppetDB werden diese mit Java 8 1139 | ausgeführt. Diese Version ist sehr sehr alte. Puppetserver 6 und PuppetDB 6 1140 | unterstützen diese auch Java 11. Dies sollte unbedingt genutzt werden. Es 1141 | empfiehlt sich regelmäßig die Release Notes zu prüfen. Sobald eine neuere Java 1142 | Version unterstützt wird sollte auf diese gewechselt werden. Beide Dienste 1143 | funktionieren sehr gut mit OpenJDK/AdoptJDK. Es wird kein Java von Oracle 1144 | benötigt. 1145 | 1146 | ### `$trusted['certname']` und nicht `$facts['networking']['fqdn']` nutzen 1147 | 1148 | Oftmals wird innerhalb der Puppet DSL der FQDN vom Agent benötigt. Hierzu gibt 1149 | es viele Optionen. Veraltet sind: 1150 | 1151 | * `$fqdn` 1152 | * `$::fqdn` 1153 | * `$facts['fqdn']` 1154 | 1155 | Diese drei optionen sind veraltet. Alternativ soll `$facts['networking']['fqdn']` 1156 | genutzt werden. Dies liefert den FQDN zurück. Dieser kann aber auf dem Quellsystem 1157 | sehr einfach geändert und manipuliert werden. In den meisten Fällen ist 1158 | `$trusted['certname']` die bessere Option. Dies ist der Common Name aus dem 1159 | Zertifikat des Agents. In der Regel entspricht dies dem FQDN des Agents 1160 | *während des ersten* Puppet runs. 1161 | 1162 | ### trusted_external_command nutzen um Inventarsysteme einzubinden 1163 | 1164 | Oft hat man Innerhalb einer Firma ein zentrales Inventarsystem. Leider meistens 1165 | sogar mehrere. Oft enthalten diese Informationen die man auch innerhalb einer 1166 | Puppet Umgebung nutzen möchte. Oft werden z.b. die Teamzugehörigkeit oder 1167 | offene Problemtickets in der motd eines Servers verlinkt. Mit der 1168 | [trusted_external_command](https://puppet.com/docs/puppet/latest/configuration.html#trusted_external_command) 1169 | Option kann man auf dem Puppetserver ein Script hinterlegen. Diesem wird als 1170 | erster Parameter der Common Name des anfragenden Agents übergeben. Das Script 1171 | kann sich dann zu externen Systemen verbinden und dort die Informationen 1172 | ermitteln. Puppet erwartet als Antwort einen JSON Hash. Dieser wird 1173 | in den Hash `$trusted['externa']` eingefügt und ist innerhalb des Puppet Codes 1174 | verfügbar. Puppet Code kann `$trusted` nicht überschreiben, nur lesen. 1175 | 1176 | Ein gutes Beispiel hierfür ist das servicenow Modul von Puppet Inc. ServiceNow 1177 | ist ein cloudbasiertes Inventarsystem. Das Script für den 1178 | `trusted_external_command` gibt es 1179 | [hier](https://github.com/puppetlabs/puppetlabs-servicenow_cmdb_integration/blob/main/files/servicenow.rb). 1180 | 1181 | Achtung: Die Lizenz erlaubt nur eine Nutzung mit Puppet Enterprise. 1182 | 1183 | ### server_max_open_files erhöhen 1184 | 1185 | Jeder Prozess darf unter Linux eine bestimmte Anzahl offener Dateideskriptoren 1186 | haben. Dies sind zum großen Teil geöffnete Datein und TCP Sockets. Das Limit 1187 | lässt sich mit `ulimit -Sn` auslesen und beträgt auf den meisten Systemen 1024 1188 | für normale Benutzer (Soft Limit). Diese können es manuell auf den Wert von 1189 | `ulimit -Hn` erhöhen (Hard Limit). Ein Puppetserver mit vielen JVM Instanzen, 1190 | der eventuell mit mehreren externen Diensten (Report Prozessor, 1191 | trusted_external_command...) kommuniziert, benötigt oftmals mehr offene 1192 | Dateideskriptoren. Die aktuell offenne Dateideskriptoren lassen sich wie folgt 1193 | ermitteln: 1194 | `find /proc/$(pgrep -f puppetserver)/fd | wc -l` 1195 | Mit dem puppetserver Puppet Modul lässt sich das limit erhöhen: 1196 | 1197 | ```yaml 1198 | puppet::server_max_open_files: 16384 1199 | ``` 1200 | 1201 | Es gibt noch ein globales Limit welches der Linux Kernel vorgibt. Dies erhält 1202 | man mit `sysctl fs.file-max`. Es kann ebenfalls über Puppet erhöht werden: 1203 | 1204 | 1205 | ```puppet 1206 | sysctl { 'fs.file-max': 1207 | ensure => 'present', 1208 | value => '9923372036854775807', 1209 | target => '/etc/sysctl.d/99-puppet.conf', 1210 | ``` 1211 | 1212 | Sofern dies nötig ist deuted es immer auf ein Problem auf dem Server hin! 1213 | Weitere Informationen findet man in der 1214 | [Linux Kernel Dokumentation](https://www.kernel.org/doc/Documentation/sysctl/fs.txt). 1215 | 1216 | ### digest_algorithm von md5 auf sha256 ändern 1217 | 1218 | [digest_algorithm](https://puppet.com/docs/puppet/latest/configuration.html#digest_algorithm) 1219 | bestimmt das Hashverfahren mit dem Datein vergleichen werden. Puppetserver 1220 | erzeugt Prüfsummen für Datein auf dem Puppetserver. Der Agent führt das gleiche 1221 | lokal durch und geänderte Datein zu erkennen. Bis einschließlich Puppet 6 wird 1222 | hier das veraltete md5 genutzt. Seit Puppet 7 ist der Standardwert sha256. 1223 | Ältere Puppet 4/5/6 Umgebungen sollten ebenfalls auf sha256 geändert werden. 1224 | Sofern benötigt, kann man dies auch auf sha512 ändern. Dies ist eventuell für 1225 | einige Zertifizierungen/Audits notwendig. Die Option wird in der puppet.conf 1226 | gesetzt. 1227 | 1228 | ### key_type von rsa auf ec wechseln 1229 | 1230 | Standardmäßig nutzt Puppet Agent veraltete Zertifikate mit dem RSA Verfahren. 1231 | [Seit Puppet 6.5.0](https://puppet.com/docs/puppet/6/release_notes_puppet.html#new_features_puppet_x-5-0-elliptic-curve-cyptography-support) 1232 | kann man aber aber Zertifikate auf Basis von Elliptischen Kurven nutzen. Dafür 1233 | muss in der puppet.conf vor dem ersten Puppet Run (Bevor ein Zertifikat 1234 | vorhanden ist) die Option `key_type` auf `ec` gesetzt werden. Zertifikate auf 1235 | Basis Elliptischer Kurven gelten als Zukunftssicher und benötigen weniger 1236 | Speicherplatz. 1237 | 1238 | ### graph Option aktivieren 1239 | 1240 | Der Puppet agent wendet bei jedem Lauf einen Katalog an, den zuvor der 1241 | Puppetserver kompiliert hat. Dieser besteht aus einem gerichteten Graphen. 1242 | Alle Ressources die angewendet werden sollen werden untereinander auf implizite 1243 | und explizite Abhängigkeiten geprüft und in eine Reihenfolge gebracht. Manchmal 1244 | gibt es Probleme den Katalog auf einem Node anzuwenden. Dazu kann der Agent den 1245 | Graph lokal speichern in verschiedenen Formaten. Die Option ist standardmäßig 1246 | deaktiviert, sollte aber aktiviert sein um auch einmalig aufgetretene Fehler im 1247 | nachhinein noch zu analysieren. 1248 | 1249 | [Directed acyclic Graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) bei Wikipedia 1250 | 1251 | ### show_diff aktivieren 1252 | 1253 | Wenn Puppet eine Datei ändern, sei es mit der Concat Resource oder weil die 1254 | ganze Datei vom Puppetserver kommt oder aus einem Template generiert wird, kann 1255 | Puppet einen diff anzeigen, wenn show_diff=true gesetzt ist. In dem Fall wird 1256 | der diff aber auch im Report gespeichert und damit zum Puppetserver 1257 | zurückgeschickt. Wenn man Reports verarbeitet, z.b. mit Foreman, kann man sich 1258 | hier die diffs anzeigen lassen. ist show_diff nicht gesetzt oder `false` kann 1259 | man im Report nur erkennen das eine Datei geändert wurde, aber nicht wie. Es 1260 | empfiehlt sich daher die Option zu aktivieren. Reports sollten dann allerdings 1261 | nicht unverschlüsselt übertragen werden da diffs potentiell sensitive 1262 | Informationen enthalten können. 1263 | 1264 | ### resubmit_facts aktivieren 1265 | 1266 | In einer Agent/Server Umgebung werden Facts auf dem Agent ermittelt und zum 1267 | Server geschickt. Im Gegenzug bekommt der Agent den kompilierten Katalog zurück 1268 | und wendet ihn an. Am Ende wird ein Report zum Server geschickt. Es ist 1269 | möglich, dass der Katalog Einfluss auf Werte irgendwelcher Facts hat (z.B. die 1270 | Anzahl offener Updates wenn der Katalog Updates bestimmter Pakete erzwingt). 1271 | Somit sind Facts in der PuppetDB eventuell nicht aktuell nachdem ein Katalog 1272 | angewand wurde. Sofern man viel mit PuppetDB Queries innerhalb der Puppet 1273 | Codebasis agiert und Facts anderer Node ausliest, oder sich viele Reports mit 1274 | eigenen PuppetDB Queries erzeugt ist es sinnvoll dem Agent mitzuteilen, dass 1275 | er Facts nach dem anwenden des Katalogs nochmal zum Server schicken soll. 1276 | Dies kann man mit der Option 1277 | [resubmit_facts](https://puppet.com/docs/puppet/latest/configuration.html#resubmit_facts) 1278 | aktivieren. Somit verdoppelt sich allerdings die Last durch Facts auf der 1279 | Puppetdb. 1280 | 1281 | ### summarize aktivieren 1282 | 1283 | Damit wird am Ende eines Agent runs eine Zusammenfassung ausgegeben 1284 | 1285 | ``` 1286 | Application: 1287 | Initial environment: function 1288 | Converged environment: function 1289 | Run mode: user 1290 | Changes: 1291 | Total: 1 1292 | Events: 1293 | Success: 1 1294 | Total: 1 1295 | Resources: 1296 | Changed: 1 1297 | Out of sync: 1 1298 | Total: 826 1299 | Time: 1300 | Concat file: 0.00 1301 | Concat fragment: 0.00 1302 | Schedule: 0.00 1303 | User: 0.00 1304 | Mount: 0.00 1305 | Ssh authorized key: 0.00 1306 | Notify: 0.00 1307 | Exec: 0.00 1308 | Cron: 0.00 1309 | Pam: 0.00 1310 | Ini setting: 0.01 1311 | Shellvar: 0.06 1312 | Sysctl: 0.09 1313 | File: 0.20 1314 | Package: 0.27 1315 | Service: 0.32 1316 | Config retrieval: 1.21 1317 | Vcsrepo: 1.47 1318 | Last run: 1649238895 1319 | Transaction evaluation: 3.93 1320 | Catalog application: 4.01 1321 | Filebucket: 0.00 1322 | Total: 4.05 1323 | Version: 1324 | Config: 4d3c463 - Tim Meusel, Fri Apr 1 14:42:05 2022 +0200 : Add test foo 1325 | Puppet: 7.14.0 1326 | ``` 1327 | 1328 | ### write-catalog-summary aktivieren 1329 | 1330 | Damit legt Puppet 1331 | `/opt/puppetlabs/puppet/cache/state/{last_run_report,last_run_summary}.yaml` 1332 | an. Beide Datein enthalten Informationen über den letzten Puppet Run, die 1333 | Laufzeit einzelner Ressourcen und vorhandene Tags. 1334 | 1335 | ### strict_variables 1336 | 1337 | Wenn die Option aktiv ist, wird ein Compile Error bei der Verwendung nicht 1338 | initialisierter Puppet Variablen erzeugt. [Upstream Doku](https://puppet.com/docs/puppet/7/configuration.html#strict-variables) 1339 | 1340 | ### strict auf error setzen 1341 | 1342 | Damit wird Puppet Code validiert und ein Compile Error erzeugt, sofern es 1343 | Fehler gibt. [Upstream Doku](https://puppet.com/docs/puppet/7/configuration.html#strict) 1344 | 1345 | ### trace 1346 | 1347 | Sollte es irgendwelche Ruby Fehler geben, wird ein Trace davon ausgegeben. 1348 | 1349 | ### Puppet Agent via Timer steuern 1350 | 1351 | Standardmäßig läuft Puppet als Agent, in einem 30 Minuten Interval. Mit der 1352 | splay Option lassen sich die Agents auch etwas verteilen, es kommt aber 1353 | trotzdem oft zu einem Schwarmverhalten. Dem kann man entgegen wirken, in dem 1354 | man den Puppet Agent nicht als Daemon, sondern mit System Timern laufen lässt. 1355 | 1356 | ``` 1357 | $puppet_timer_runinterval = 30 # run interval in minutes 1358 | $puppet_timer_command = '/opt/puppetlabs/bin/puppet agent --onetime --summarize --no-splay --verbose --no-daemonize --detailed-exitcode --show-diff' 1359 | $first_run = fqdn_rand($puppet_timer_runinterval) 1360 | $second_run = $first_run + $puppet_timer_runinterval 1361 | # lint:ignore:strict_indent 1362 | $_timer = @("EOT") 1363 | # THIS FILE IS MANAGED BY PUPPET 1364 | [Unit] 1365 | Description=Systemd Timer for Puppet Agent 1366 | 1367 | [Timer] 1368 | Persistent=true 1369 | OnCalendar=*-*-* *:${first_run},${second_run}:00 1370 | 1371 | [Install] 1372 | WantedBy=timers.target 1373 | | EOT 1374 | 1375 | $_service = @("EOT") 1376 | # THIS FILE IS MANAGED BY PUPPET 1377 | [Unit] 1378 | Description=Systemd Timer Service for Puppet Agent 1379 | Wants=network-online.target 1380 | After=network-online.target 1381 | 1382 | [Service] 1383 | Type=oneshot 1384 | ExecStart=${puppet_timer_command} 1385 | SuccessExitStatus=2 1386 | User=root 1387 | Group=root 1388 | | EOT 1389 | # lint:endignore:strict_indent 1390 | 1391 | # we should not use the name puppet or puppet-agent. That .service might already exist 1392 | systemd::timer { 'puppet-timer.timer': 1393 | timer_content => $_timer, 1394 | service_content => $_service, 1395 | active => true, 1396 | enable => true, 1397 | } 1398 | ``` 1399 | ## PDF 1400 | 1401 | `pandoc` ermöglicht es aus dieser markdown Datei eine pdf zu generieren. Die 1402 | gängigen Linux Distributionen haben pandoc in ihren Repositories. Der simpelste 1403 | Aufruf lautet wie folgt: 1404 | 1405 | ```sh 1406 | pandoc --from markdown README.md --output puppet.pdf 1407 | ``` 1408 | 1409 | Und für die puppet.pdf hier im Repo: 1410 | 1411 | ```sh 1412 | pandoc README.md --output puppet.pdf "-fmarkdown-implicit_figures -o" --from=markdown -V geometry:margin=.4in --toc --highlight-style=espresso 1413 | ``` 1414 | 1415 | ## Lizenz 1416 | 1417 | Dieses Dokument steht unter der 1418 | [CC BY-NC-SA 4.0 Lizenz](https://creativecommons.org/licenses/by-nc-sa/4.0/). 1419 | Codebeispiele sind unter der [GNU Affero General Public License v3.0](LICENSE) 1420 | lizensiert. Für kommerzielle Anfragen, Nachfragen zu Consulting oder Feedback 1421 | kontaktieren sie bitte [tim@bastelfreak.de](mailto:tim@bastelfreak.de). 1422 | 1423 | ## Anmerkungen 1424 | 1425 | * Dieses Dokument wurde ursprünglich als gist gepflegt: [https://gist.github.com/bastelfreak/33a9d1510448e31e7d8139a80d16e44a](https://gist.github.com/bastelfreak/33a9d1510448e31e7d8139a80d16e44a) 1426 | * Weitere Vorträge und Dokumente gibt es in meinem [Git Repository](https://github.com/bastelfreak/talks#collection-of-talks-proposals-and-related-stuff) 1427 | * Für Consulting Anfragen, schicken sie bitte eine Email an [tim@bastelfreak.de](mailto:tim@bastelfreak.de) 1428 | -------------------------------------------------------------------------------- /puppet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bastelfreak/puppetdocs/6f86d4f6bf4b1eb78d3c1e3afb8a671880af46c0/puppet.pdf --------------------------------------------------------------------------------