Merge commit 'metche_1.0' into upstream
intrigeri
13 years ago
0 | ,------------------------------------------------------------------------------- | |
1 | | INSTALLATION | |
2 | `------------------------------------------------------------------------------- | |
3 | ||
4 | 1. Have a look to the REQUIREMENTS section in the README file. | |
5 | 2. Copy the metche executable to /usr/local/sbin/ | |
6 | 3. As root, mkdir /var/lib/metche | |
7 | 4. Copy the manpage (metche.8) to /usr/local/man/man8/ | |
8 | 5. Read the README file and the manpage | |
9 |
0 | GNU GENERAL PUBLIC LICENSE | |
1 | Version 2, June 1991 | |
2 | ||
3 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |
4 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
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 licenses for most software are designed to take away your | |
11 | freedom to share and change it. By contrast, the GNU General Public | |
12 | License is intended to guarantee your freedom to share and change free | |
13 | software--to make sure the software is free for all its users. This | |
14 | General Public License applies to most of the Free Software | |
15 | Foundation's software and to any other program whose authors commit to | |
16 | using it. (Some other Free Software Foundation software is covered by | |
17 | the GNU Library General Public License instead.) You can apply it to | |
18 | your programs, too. | |
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 | this service if you wish), that you receive source code or can get it | |
24 | if you want it, that you can change the software or use pieces of it | |
25 | in new free programs; and that you know you can do these things. | |
26 | ||
27 | To protect your rights, we need to make restrictions that forbid | |
28 | anyone to deny you these rights or to ask you to surrender the rights. | |
29 | These restrictions translate to certain responsibilities for you if you | |
30 | distribute copies of the software, or if you modify it. | |
31 | ||
32 | For example, if you distribute copies of such a program, whether | |
33 | gratis or for a fee, you must give the recipients all the rights that | |
34 | you have. You must make sure that they, too, receive or can get the | |
35 | source code. And you must show them these terms so they know their | |
36 | rights. | |
37 | ||
38 | We protect your rights with two steps: (1) copyright the software, and | |
39 | (2) offer you this license which gives you legal permission to copy, | |
40 | distribute and/or modify the software. | |
41 | ||
42 | Also, for each author's protection and ours, we want to make certain | |
43 | that everyone understands that there is no warranty for this free | |
44 | software. If the software is modified by someone else and passed on, we | |
45 | want its recipients to know that what they have is not the original, so | |
46 | that any problems introduced by others will not reflect on the original | |
47 | authors' reputations. | |
48 | ||
49 | Finally, any free program is threatened constantly by software | |
50 | patents. We wish to avoid the danger that redistributors of a free | |
51 | program will individually obtain patent licenses, in effect making the | |
52 | program proprietary. To prevent this, we have made it clear that any | |
53 | patent must be licensed for everyone's free use or not licensed at all. | |
54 | ||
55 | The precise terms and conditions for copying, distribution and | |
56 | modification follow. | |
57 | ||
58 | GNU GENERAL PUBLIC LICENSE | |
59 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
60 | ||
61 | 0. This License applies to any program or other work which contains | |
62 | a notice placed by the copyright holder saying it may be distributed | |
63 | under the terms of this General Public License. The "Program", below, | |
64 | refers to any such program or work, and a "work based on the Program" | |
65 | means either the Program or any derivative work under copyright law: | |
66 | that is to say, a work containing the Program or a portion of it, | |
67 | either verbatim or with modifications and/or translated into another | |
68 | language. (Hereinafter, translation is included without limitation in | |
69 | the term "modification".) Each licensee is addressed as "you". | |
70 | ||
71 | Activities other than copying, distribution and modification are not | |
72 | covered by this License; they are outside its scope. The act of | |
73 | running the Program is not restricted, and the output from the Program | |
74 | is covered only if its contents constitute a work based on the | |
75 | Program (independent of having been made by running the Program). | |
76 | Whether that is true depends on what the Program does. | |
77 | ||
78 | 1. You may copy and distribute verbatim copies of the Program's | |
79 | source code as you receive it, in any medium, provided that you | |
80 | conspicuously and appropriately publish on each copy an appropriate | |
81 | copyright notice and disclaimer of warranty; keep intact all the | |
82 | notices that refer to this License and to the absence of any warranty; | |
83 | and give any other recipients of the Program a copy of this License | |
84 | along with the Program. | |
85 | ||
86 | You may charge a fee for the physical act of transferring a copy, and | |
87 | you may at your option offer warranty protection in exchange for a fee. | |
88 | ||
89 | 2. You may modify your copy or copies of the Program or any portion | |
90 | of it, thus forming a work based on the Program, and copy and | |
91 | distribute such modifications or work under the terms of Section 1 | |
92 | above, provided that you also meet all of these conditions: | |
93 | ||
94 | a) You must cause the modified files to carry prominent notices | |
95 | stating that you changed the files and the date of any change. | |
96 | ||
97 | b) You must cause any work that you distribute or publish, that in | |
98 | whole or in part contains or is derived from the Program or any | |
99 | part thereof, to be licensed as a whole at no charge to all third | |
100 | parties under the terms of this License. | |
101 | ||
102 | c) If the modified program normally reads commands interactively | |
103 | when run, you must cause it, when started running for such | |
104 | interactive use in the most ordinary way, to print or display an | |
105 | announcement including an appropriate copyright notice and a | |
106 | notice that there is no warranty (or else, saying that you provide | |
107 | a warranty) and that users may redistribute the program under | |
108 | these conditions, and telling the user how to view a copy of this | |
109 | License. (Exception: if the Program itself is interactive but | |
110 | does not normally print such an announcement, your work based on | |
111 | the Program is not required to print an announcement.) | |
112 | ||
113 | These requirements apply to the modified work as a whole. If | |
114 | identifiable sections of that work are not derived from the Program, | |
115 | and can be reasonably considered independent and separate works in | |
116 | themselves, then this License, and its terms, do not apply to those | |
117 | sections when you distribute them as separate works. But when you | |
118 | distribute the same sections as part of a whole which is a work based | |
119 | on the Program, the distribution of the whole must be on the terms of | |
120 | this License, whose permissions for other licensees extend to the | |
121 | entire whole, and thus to each and every part regardless of who wrote it. | |
122 | ||
123 | Thus, it is not the intent of this section to claim rights or contest | |
124 | your rights to work written entirely by you; rather, the intent is to | |
125 | exercise the right to control the distribution of derivative or | |
126 | collective works based on the Program. | |
127 | ||
128 | In addition, mere aggregation of another work not based on the Program | |
129 | with the Program (or with a work based on the Program) on a volume of | |
130 | a storage or distribution medium does not bring the other work under | |
131 | the scope of this License. | |
132 | ||
133 | 3. You may copy and distribute the Program (or a work based on it, | |
134 | under Section 2) in object code or executable form under the terms of | |
135 | Sections 1 and 2 above provided that you also do one of the following: | |
136 | ||
137 | a) Accompany it with the complete corresponding machine-readable | |
138 | source code, which must be distributed under the terms of Sections | |
139 | 1 and 2 above on a medium customarily used for software interchange; or, | |
140 | ||
141 | b) Accompany it with a written offer, valid for at least three | |
142 | years, to give any third party, for a charge no more than your | |
143 | cost of physically performing source distribution, a complete | |
144 | machine-readable copy of the corresponding source code, to be | |
145 | distributed under the terms of Sections 1 and 2 above on a medium | |
146 | customarily used for software interchange; or, | |
147 | ||
148 | c) Accompany it with the information you received as to the offer | |
149 | to distribute corresponding source code. (This alternative is | |
150 | allowed only for noncommercial distribution and only if you | |
151 | received the program in object code or executable form with such | |
152 | an offer, in accord with Subsection b above.) | |
153 | ||
154 | The source code for a work means the preferred form of the work for | |
155 | making modifications to it. For an executable work, complete source | |
156 | code means all the source code for all modules it contains, plus any | |
157 | associated interface definition files, plus the scripts used to | |
158 | control compilation and installation of the executable. However, as a | |
159 | special exception, the source code distributed need not include | |
160 | anything that is normally distributed (in either source or binary | |
161 | form) with the major components (compiler, kernel, and so on) of the | |
162 | operating system on which the executable runs, unless that component | |
163 | itself accompanies the executable. | |
164 | ||
165 | If distribution of executable or object code is made by offering | |
166 | access to copy from a designated place, then offering equivalent | |
167 | access to copy the source code from the same place counts as | |
168 | distribution of the source code, even though third parties are not | |
169 | compelled to copy the source along with the object code. | |
170 | ||
171 | 4. You may not copy, modify, sublicense, or distribute the Program | |
172 | except as expressly provided under this License. Any attempt | |
173 | otherwise to copy, modify, sublicense or distribute the Program is | |
174 | void, and will automatically terminate your rights under this License. | |
175 | However, parties who have received copies, or rights, from you under | |
176 | this License will not have their licenses terminated so long as such | |
177 | parties remain in full compliance. | |
178 | ||
179 | 5. You are not required to accept this License, since you have not | |
180 | signed it. However, nothing else grants you permission to modify or | |
181 | distribute the Program or its derivative works. These actions are | |
182 | prohibited by law if you do not accept this License. Therefore, by | |
183 | modifying or distributing the Program (or any work based on the | |
184 | Program), you indicate your acceptance of this License to do so, and | |
185 | all its terms and conditions for copying, distributing or modifying | |
186 | the Program or works based on it. | |
187 | ||
188 | 6. Each time you redistribute the Program (or any work based on the | |
189 | Program), the recipient automatically receives a license from the | |
190 | original licensor to copy, distribute or modify the Program subject to | |
191 | these terms and conditions. You may not impose any further | |
192 | restrictions on the recipients' exercise of the rights granted herein. | |
193 | You are not responsible for enforcing compliance by third parties to | |
194 | this License. | |
195 | ||
196 | 7. If, as a consequence of a court judgment or allegation of patent | |
197 | infringement or for any other reason (not limited to patent issues), | |
198 | conditions are imposed on you (whether by court order, agreement or | |
199 | otherwise) that contradict the conditions of this License, they do not | |
200 | excuse you from the conditions of this License. If you cannot | |
201 | distribute so as to satisfy simultaneously your obligations under this | |
202 | License and any other pertinent obligations, then as a consequence you | |
203 | may not distribute the Program at all. For example, if a patent | |
204 | license would not permit royalty-free redistribution of the Program by | |
205 | all those who receive copies directly or indirectly through you, then | |
206 | the only way you could satisfy both it and this License would be to | |
207 | refrain entirely from distribution of the Program. | |
208 | ||
209 | If any portion of this section is held invalid or unenforceable under | |
210 | any particular circumstance, the balance of the section is intended to | |
211 | apply and the section as a whole is intended to apply in other | |
212 | circumstances. | |
213 | ||
214 | It is not the purpose of this section to induce you to infringe any | |
215 | patents or other property right claims or to contest validity of any | |
216 | such claims; this section has the sole purpose of protecting the | |
217 | integrity of the free software distribution system, which is | |
218 | implemented by public license practices. Many people have made | |
219 | generous contributions to the wide range of software distributed | |
220 | through that system in reliance on consistent application of that | |
221 | system; it is up to the author/donor to decide if he or she is willing | |
222 | to distribute software through any other system and a licensee cannot | |
223 | impose that choice. | |
224 | ||
225 | This section is intended to make thoroughly clear what is believed to | |
226 | be a consequence of the rest of this License. | |
227 | ||
228 | 8. If the distribution and/or use of the Program is restricted in | |
229 | certain countries either by patents or by copyrighted interfaces, the | |
230 | original copyright holder who places the Program under this License | |
231 | may add an explicit geographical distribution limitation excluding | |
232 | those countries, so that distribution is permitted only in or among | |
233 | countries not thus excluded. In such case, this License incorporates | |
234 | the limitation as if written in the body of this License. | |
235 | ||
236 | 9. The Free Software Foundation may publish revised and/or new versions | |
237 | of the General Public License from time to time. Such new versions will | |
238 | be similar in spirit to the present version, but may differ in detail to | |
239 | address new problems or concerns. | |
240 | ||
241 | Each version is given a distinguishing version number. If the Program | |
242 | specifies a version number of this License which applies to it and "any | |
243 | later version", you have the option of following the terms and conditions | |
244 | either of that version or of any later version published by the Free | |
245 | Software Foundation. If the Program does not specify a version number of | |
246 | this License, you may choose any version ever published by the Free Software | |
247 | Foundation. | |
248 | ||
249 | 10. If you wish to incorporate parts of the Program into other free | |
250 | programs whose distribution conditions are different, write to the author | |
251 | to ask for permission. For software which is copyrighted by the Free | |
252 | Software Foundation, write to the Free Software Foundation; we sometimes | |
253 | make exceptions for this. Our decision will be guided by the two goals | |
254 | of preserving the free status of all derivatives of our free software and | |
255 | of promoting the sharing and reuse of software generally. | |
256 | ||
257 | NO WARRANTY | |
258 | ||
259 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |
260 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |
261 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |
262 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |
263 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
264 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |
265 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |
266 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |
267 | REPAIR OR CORRECTION. | |
268 | ||
269 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
270 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |
271 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |
272 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |
273 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |
274 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |
275 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |
276 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |
277 | POSSIBILITY OF SUCH DAMAGES. | |
278 | ||
279 | END OF TERMS AND CONDITIONS | |
280 | ||
281 | How to Apply These Terms to Your New Programs | |
282 | ||
283 | If you develop a new program, and you want it to be of the greatest | |
284 | possible use to the public, the best way to achieve this is to make it | |
285 | free software which everyone can redistribute and change under these terms. | |
286 | ||
287 | To do so, attach the following notices to the program. It is safest | |
288 | to attach them to the start of each source file to most effectively | |
289 | convey the exclusion of warranty; and each file should have at least | |
290 | the "copyright" line and a pointer to where the full notice is found. | |
291 | ||
292 | <one line to give the program's name and a brief idea of what it does.> | |
293 | Copyright (C) <year> <name of author> | |
294 | ||
295 | This program is free software; you can redistribute it and/or modify | |
296 | it under the terms of the GNU General Public License as published by | |
297 | the Free Software Foundation; either version 2 of the License, or | |
298 | (at your option) any later version. | |
299 | ||
300 | This program is distributed in the hope that it will be useful, | |
301 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
302 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
303 | GNU General Public License for more details. | |
304 | ||
305 | You should have received a copy of the GNU General Public License | |
306 | along with this program; if not, write to the Free Software | |
307 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
308 | ||
309 | ||
310 | Also add information on how to contact you by electronic and paper mail. | |
311 | ||
312 | If the program is interactive, make it output a short notice like this | |
313 | when it starts in an interactive mode: | |
314 | ||
315 | Gnomovision version 69, Copyright (C) year name of author | |
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |
317 | This is free software, and you are welcome to redistribute it | |
318 | under certain conditions; type `show c' for details. | |
319 | ||
320 | The hypothetical commands `show w' and `show c' should show the appropriate | |
321 | parts of the General Public License. Of course, the commands you use may | |
322 | be called something other than `show w' and `show c'; they could even be | |
323 | mouse-clicks or menu items--whatever suits your program. | |
324 | ||
325 | You should also get your employer (if you work as a programmer) or your | |
326 | school, if any, to sign a "copyright disclaimer" for the program, if | |
327 | necessary. Here is a sample; alter the names: | |
328 | ||
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. | |
331 | ||
332 | <signature of Ty Coon>, 1 April 1989 | |
333 | Ty Coon, President of Vice | |
334 | ||
335 | This General Public License does not permit incorporating your program into | |
336 | proprietary programs. If your program is a subroutine library, you may | |
337 | consider it more useful to permit linking proprietary applications with the | |
338 | library. If this is what you want to do, use the GNU Library General | |
339 | Public License instead of this License. |
0 | all: doc | |
1 | ||
2 | metche-manpage.xml: metche-manpage.sgml | |
3 | sgml2xml -xlower -xid $< > $@ | |
4 | ||
5 | metche.8: metche-manpage.xml | |
6 | db2x_xsltproc -s /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl $< | |
7 | ||
8 | doc: metche.8 | |
9 | ||
10 | clean: | |
11 | rm -f metche-manpage.xml | |
12 | ||
13 | distclean: clean | |
14 | rm -f metche.8 | |
15 | ||
16 | .PHONY: all doc clean distclean |
0 | metche - reducing root bus factor | |
1 | homepage : https://poivron.org/dev/metche/ | |
2 | ||
3 | ,------------------------------------------------------------------------------- | |
4 | | Copyright (C) 2004-2006 boum.org collective - property is theft ! | |
5 | `------------------------------------------------------------------------------- | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free Software | |
9 | Foundation; either version 2 of the License, or (at your option) any later | |
10 | version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
14 | PARTICULAR PURPOSE. See the GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License along with | |
17 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple | |
18 | Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | ||
20 | ,------------------------------------------------------------------------------- | |
21 | | OVERVIEW | |
22 | `------------------------------------------------------------------------------- | |
23 | ||
24 | metche is a tool meant to facilitate collective sysadmin ; basically, it | |
25 | periodically : | |
26 | - saves the "system state" to $BACKUP_DIR (default /var/lib/metche), i.e. : | |
27 | . $WATCHED_DIR (default: /etc) | |
28 | . $CHANGELOG_FILE (default /root/Changelog) | |
29 | or $CHANGELOG_DIR/*/Changelog (default: /root/changelogs/*/Changelog) | |
30 | . Debian packages states and versions (using apt-show-versions) | |
31 | - sends you, in a nicely formated email, the last changes to the "system | |
32 | state"; see https://poivron.org/dev/metche/ for an example. | |
33 | ||
34 | ,------------------------------------------------------------------------------- | |
35 | | BASIC USAGE | |
36 | `------------------------------------------------------------------------------- | |
37 | ||
38 | When installed and configured, metche is run by a cronjob, and you just have to | |
39 | read the report emails. Of course, it's not useful at all if you don't : | |
40 | - set $EMAIL_ADDRESS config variable to your sysadmin collective mailing-list | |
41 | address ; | |
42 | - use the Changelog files in a rigorous way. | |
43 | ||
44 | Note: it is dangerous to use metche without before reading the SECURITY section | |
45 | of the manpage. | |
46 | ||
47 | For a deeper explanation of the way metche works, read the metche(8) manpage. | |
48 | ||
49 | ,------------------------------------------------------------------------------- | |
50 | | REQUIREMENTS | |
51 | `------------------------------------------------------------------------------- | |
52 | ||
53 | * Debian GNU/Linux and apt-show-versions (if Debian packages monitoring is | |
54 | enabled) | |
55 | * mutt | |
56 | * bzip2 | |
57 | * If you want metche to encrypt the email it sends you : gnupg | |
58 | * If you want metche to monitor your vservers as well : util-vserver tools | |
59 | * If you want metche to monitor one manually written Changelog file, | |
60 | it must be located at $CHANGELOG_FILE. | |
61 | _or_ If you want metche to monitor multiple manually written Changelog | |
62 | files, they must be located in $CHANGELOG_DIR/*/Changelog ; | |
63 | for example, you can have : | |
64 | /root/ | |
65 | changelogs/ | |
66 | common/Changelog | |
67 | apache/Changelog | |
68 | postfix/Changelog | |
69 | ||
70 | ,------------------------------------------------------------------------------- | |
71 | | INSTALLATION | |
72 | `------------------------------------------------------------------------------- | |
73 | ||
74 | See the included INSTALL file. | |
75 | ||
76 | ,------------------------------------------------------------------------------- | |
77 | | CONFIGURATION | |
78 | `------------------------------------------------------------------------------- | |
79 | ||
80 | 1. Copy metche.conf.default to /etc/metche.conf and edit it so that it suits | |
81 | your needs. | |
82 | 2. Read the next sections of this document and the metche(8) manpage. | |
83 | 3. Add to /etc/cron.d/metche something like : | |
84 | 0-59/5 * * * * root test -x /usr/local/sbin/metche && \ | |
85 | /usr/local/sbin/metche cron | |
86 | ||
87 | ,------------------------------------------------------------------------------- | |
88 | | SECURITY : BIG FAT WARNING | |
89 | `------------------------------------------------------------------------------- | |
90 | ||
91 | Read the SECURITY section of metche(8). Really. | |
92 | ||
93 | ,------------------------------------------------------------------------------- | |
94 | | FAQ | |
95 | `------------------------------------------------------------------------------- | |
96 | ||
97 | 1. How are the monitored Changelog files ($CHANGELOG_FILE or | |
98 | $CHANGELOG_DIR/*/Changelog) generated ? | |
99 | ||
100 | With Emacs or Vim. Ah ah. They are written by *you* ! They are an important | |
101 | part of the collective sysadmin process metche is supposed to facilitate. | |
102 | ||
103 | 2. Hey, how is metche working, and what are the underlying concepts I have to | |
104 | know ? | |
105 | ||
106 | When called with the "cron" command line switch, metche looks if the "system | |
107 | state" has changed in the last $TESTING_TIME minutes. If it is the case, a | |
108 | "unstable" state is saved. Otherwise, a "testing state" is saved, and a | |
109 | report is emailed to you. | |
110 | ||
111 | A similar mechanism to automatically turn a "testing" state into a "stable" | |
112 | one ; see metche(8) for explainations. | |
113 | ||
114 | 3. How do I see the saved states list ? | |
115 | ||
116 | Run "metche list". | |
117 | ||
118 | 4. I've broken my system, how can I see a report against a previous, known | |
119 | working, system state ? | |
120 | ||
121 | Run "metche report [{stable,testing,unstable}-YYYYMMDDHHMM]". | |
122 | If no saved state is specified, the latest "testing state" is used as | |
123 | reference. | |
124 | ||
125 | 5. How do I create a "stable state" by hand ? | |
126 | ||
127 | Run "metche stabilize [testing-YYYYMMDDHHMM]". | |
128 | This turns the given testing state, if specified, or the latest one, | |
129 | otherwise, into a "stable state". |
0 | metche (1.0-1) unstable; urgency=low | |
1 | ||
2 | * Initial Release. | |
3 | ||
4 | -- ricola <ricola@anargeek.net> Thu, 24 Nov 2005 19:18:47 +0100 |
0 | 4 |
0 | #!/bin/sh | |
1 | ||
2 | CONFIGFILE=/etc/metche.conf | |
3 | set -e | |
4 | . /usr/share/debconf/confmodule | |
5 | ||
6 | if [ -e $CONFIGFILE ]; then | |
7 | . $CONFIGFILE || true | |
8 | db_set metche/email $EMAIL_ADDRESS | |
9 | db_set metche/changelog/type "No changelog monitoring" | |
10 | if [ "$CHANGELOG_FILE" ]; then | |
11 | db_set metche/changelog/type "Single changelog file" | |
12 | db_set metche/changelog/file $CHANGELOG_FILE | |
13 | fi | |
14 | if [ "$CHANGELOG_DIR" ]; then | |
15 | db_set metche/changelog/type "Multiple changelog files" | |
16 | db_set metche/changelog/directory $CHANGELOG_DIR | |
17 | fi | |
18 | fi | |
19 | ||
20 | db_input medium metche/email || true | |
21 | db_input medium metche/changelog/type || true | |
22 | db_go || true | |
23 | db_get metche/changelog/type | |
24 | case "$RET" in | |
25 | "Single changelog file") | |
26 | db_input medium metche/changelog/file || true | |
27 | db_go || true | |
28 | ;; | |
29 | "Multiple changelog files") | |
30 | db_input medium metche/changelog/directory || true | |
31 | db_go || true | |
32 | ;; | |
33 | esac |
0 | Source: metche | |
1 | Section: admin | |
2 | Priority: optional | |
3 | Maintainer: boum.org collective <boum@anargeek.net> | |
4 | Build-Depends-Indep: debhelper (>> 4.0.0), docbook2x, sp, docbook-xsl, docbook-to-man | |
5 | Standards-Version: 3.6.1 | |
6 | ||
7 | Package: metche | |
8 | Architecture: all | |
9 | Depends: debconf, mutt, bzip2 | |
10 | Recommends: apt-show-versions, gnupg | |
11 | Description: configuration monitor to ease collective administration | |
12 | metche monitors changes made to a "system state" composed of: | |
13 | - a "watched" directory (typically: /etc) | |
14 | - changelogs written by you in one or several files | |
15 | (e.g. /root/Changelog) | |
16 | - States and versions of Debian packages (using apt-show-versions) | |
17 | by periodically: | |
18 | - saving backups of the corresponding files | |
19 | - emailing the changes in the system state to your administrator's | |
20 | mailing list |
0 | This package was debianized by boum.org collective <boum@anargeek.net> on | |
1 | Thu, 24 Nov 2005 19:18:47 +0100. | |
2 | ||
3 | It was downloaded from http://www.poivron.org/dev/metche | |
4 | ||
5 | Copyright: | |
6 | ||
7 | Upstream Authors: boum.org collective <boum@anargeek.net> | |
8 | ||
9 | Copyright (C) 2004-2006 boum.org collective - property is theft ! | |
10 | ||
11 | You are free to distribute this software under the terms of | |
12 | the GNU General Public License. | |
13 | On Debian systems, the complete text of the GNU General Public | |
14 | License can be found in the file `/usr/share/common-licenses/GPL'. |
0 | 0-59/5 * * * * root test -x /usr/sbin/metche && /usr/sbin/metche cron |
0 | #!/bin/sh | |
1 | ||
2 | CONFIGFILE=/etc/metche.conf | |
3 | set -e | |
4 | . /usr/share/debconf/confmodule | |
5 | ||
6 | cp -a -f $CONFIGFILE $CONFIGFILE.tmp | |
7 | ||
8 | db_get metche/email | |
9 | EMAIL_ADDRESS="$RET" | |
10 | sed -e "s/^ *EMAIL_ADDRESS=.*/EMAIL_ADDRESS=\"$EMAIL_ADDRESS\"/" -i $CONFIGFILE.tmp | |
11 | ||
12 | db_get metche/changelog/type | |
13 | case "$RET" in | |
14 | "Single changelog file") | |
15 | db_get metche/changelog/file | |
16 | CHANGELOG_FILE="$RET" | |
17 | sed -e "s@^[# ]*CHANGELOG_FILE=.*@CHANGELOG_FILE=\"$CHANGELOG_FILE\"@" \ | |
18 | -e "s@^[# ]*CHANGELOG_DIR@#CHANGELOG_DIR@" -i $CONFIGFILE.tmp | |
19 | ;; | |
20 | "Multiple changelog files") | |
21 | db_get metche/changelog/directory | |
22 | CHANGELOG_DIR="$RET" | |
23 | sed -e "s@^[# ]*CHANGELOG_DIR=.*@CHANGELOG_DIR=\"$CHANGELOG_DIR\"@" \ | |
24 | -e "s@^[# ]*CHANGELOG_FILE@#CHANGELOG_FILE@" -i $CONFIGFILE.tmp | |
25 | ;; | |
26 | "No changelog monitoring") | |
27 | sed -e "s@^[# ]*CHANGELOG_FILE@#CHANGELOG_FILE@" \ | |
28 | -e "s@^[# ]*CHANGELOG_DIR@#CHANGELOG_DIR@" -i $CONFIGFILE.tmp | |
29 | ;; | |
30 | esac | |
31 | ||
32 | mv -f $CONFIGFILE.tmp $CONFIGFILE | |
33 | ||
34 | metche cron | |
35 | ||
36 | #DEBHELPER# |
0 | #!/usr/bin/make -f | |
1 | # debian rules file for metche | |
2 | ||
3 | PACKAGE = metche | |
4 | DESTDIR = $(CURDIR)/debian/$(PACKAGE) | |
5 | ||
6 | build: build-stamp | |
7 | build-stamp: | |
8 | dh_testdir | |
9 | $(MAKE) | |
10 | touch build-stamp | |
11 | ||
12 | clean: | |
13 | dh_testdir | |
14 | dh_testroot | |
15 | rm -f build-stamp | |
16 | -$(MAKE) clean | |
17 | dh_clean | |
18 | ||
19 | install: build | |
20 | dh_testdir | |
21 | dh_testroot | |
22 | dh_clean -k | |
23 | dh_installdirs | |
24 | cp $(CURDIR)/metche $(DESTDIR)/usr/sbin | |
25 | cp $(CURDIR)/metche.conf.default $(DESTDIR)/etc/metche.conf | |
26 | cp $(CURDIR)/metche.8 $(DESTDIR)/usr/share/man/man8 | |
27 | chown root:staff $(DESTDIR)/var/lib/metche | |
28 | chmod 750 $(DESTDIR)/var/lib/metche | |
29 | ||
30 | # Build architecture-independent files here. | |
31 | binary-indep: build install | |
32 | ||
33 | # Build architecture-dependent files here. | |
34 | binary-arch: build install | |
35 | dh_testdir | |
36 | dh_testroot | |
37 | dh_installchangelogs | |
38 | dh_installdocs | |
39 | dh_installexamples | |
40 | dh_installdebconf | |
41 | dh_installcron | |
42 | dh_installman metche.8 | |
43 | dh_link | |
44 | dh_strip | |
45 | dh_compress | |
46 | dh_fixperms | |
47 | dh_installdeb | |
48 | dh_shlibdeps | |
49 | dh_gencontrol | |
50 | dh_md5sums | |
51 | dh_builddeb | |
52 | ||
53 | binary: binary-indep binary-arch | |
54 | .PHONY: build clean binary-indep binary-arch binary install |
0 | Template: metche/email | |
1 | Type: string | |
2 | Default: root | |
3 | Description: E-mail address receiving metche reports | |
4 | metche monitors "system state" changes. An hour after the last change has | |
5 | been recorded an e-mail report is sent describing changes made to: | |
6 | - files inside the watched directory (/etc by default), | |
7 | - user maintainted changelog file(s) (if configured to do so), | |
8 | - the list of installed Debian packages (if configured to do so). | |
9 | . | |
10 | Please enter the e-mail that should receive these reports. It typically | |
11 | corresponds to the alias or mailing-list used by system administators for | |
12 | this computer. | |
13 | . | |
14 | Note: by default, metche does not send detailed diffs describing file changes | |
15 | as this can leak confidential information. If you want to use this feature, | |
16 | we strongly encourage you to turn on GPG encryption at the same time. | |
17 | See the metche(8) man page and the configuration file for more details. | |
18 | ||
19 | Template: metche/changelog/type | |
20 | Type: select | |
21 | Choices: Single changelog file, Multiple changelog files, No changelog monitoring | |
22 | Description: Changelog monitoring type. | |
23 | metche can monitor one or more changelogs written by the system | |
24 | administrators. | |
25 | . | |
26 | These changelogs should contain comments describing the changes made | |
27 | to the system. The easiest way to organize these comments is to put them all | |
28 | together in one file. | |
29 | . | |
30 | Another possibility is to have a subdirectory for each administrative task | |
31 | with a file named "Changelog". This way, you can store source code or | |
32 | configuration examples along with the documentation on how they have been used. | |
33 | ||
34 | Template: metche/changelog/file | |
35 | Type: string | |
36 | Description: Changelog file to be monitored. | |
37 | This option sets the path of the changelog file to be monitored. | |
38 | ||
39 | Template: metche/changelog/directory | |
40 | Type: string | |
41 | Description: Changelog directory to be monitored. | |
42 | This option sets the path to the root directory containing the Changelogs. Each | |
43 | "Changelog" file should be in a sub-directory of this directory. |
0 | #! /bin/bash | |
1 | # -*- mode: sh; sh-basic-offset: 4; indent-tabs-mode: nil; -*- | |
2 | # | |
3 | # metche: reducing root bus factor | |
4 | # Copyright (C) 2004-2006 boum.org collective - property is theft ! | |
5 | # | |
6 | # This program is free software; you can redistribute it and/or modify | |
7 | # it under the terms of the GNU General Public License as published by | |
8 | # the Free Software Foundation; either version 2 of the License, or | |
9 | # (at your option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License along | |
17 | # with this program; if not, write to the Free Software Foundation, Inc., | |
18 | # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | # | |
20 | ||
21 | set -e | |
22 | shopt -s nullglob | |
23 | ||
24 | ### | |
25 | ### Auxiliary functions | |
26 | ### | |
27 | ||
28 | display_usage() { | |
29 | ( echo "Usage: `basename $0` list" | |
30 | echo " `basename $0` report" \ | |
31 | "[{stable|testing|unstable}-YYYYMMDDHHMM]" | |
32 | echo " `basename $0` cron" | |
33 | echo " `basename $0` stabilize [testing-YYYYMMDDHHMM]" | |
34 | echo "" | |
35 | ) >&2 | |
36 | } | |
37 | ||
38 | fatal() { | |
39 | echo -e "$@" >&2 | |
40 | exit 2 | |
41 | } | |
42 | ||
43 | executable_not_found() { | |
44 | local executable="$1" | |
45 | local software="$2" | |
46 | local option="$3" | |
47 | ||
48 | fatal "$executable not found. Please install $software or turn $option off." | |
49 | } | |
50 | ||
51 | debug() { | |
52 | [ "$DEBUG" != yes ] || echo -e "debug: $@" >&2 | |
53 | } | |
54 | ||
55 | email() { | |
56 | debug "email $@" | |
57 | local subject="$_MAIL_SUBJECT : $1" | |
58 | if [ $ENCRYPT_EMAIL = "yes" ]; then | |
59 | LC_ALL="$LOCALE" gpg --batch --armor --encrypt \ | |
60 | --recipient "$EMAIL_ADDRESS" | | |
61 | LC_ALL="$LOCALE" mutt -s "$subject" "$EMAIL_ADDRESS" | |
62 | else | |
63 | LC_ALL="$LOCALE" mutt -s "$subject" "$EMAIL_ADDRESS" | |
64 | fi | |
65 | } | |
66 | ||
67 | ### | |
68 | ### Configuration | |
69 | ### | |
70 | ||
71 | DEBUG="yes" | |
72 | WATCHED_DIR="/etc" | |
73 | BACKUP_DIR="/var/lib/metche" | |
74 | # if set, activate single changelog mode | |
75 | #CHANGELOG_FILE="/root/Changelog" | |
76 | # if set, activate multiple changelogs mode | |
77 | #CHANGELOG_DIR="/root/changelogs" | |
78 | DO_PACKAGES="no" | |
79 | DO_DETAILS="no" | |
80 | TESTING_TIME="60" | |
81 | STABLE_TIME="3" | |
82 | EMAIL_ADDRESS="root@`hostname -f`" | |
83 | ENCRYPT_EMAIL="no" | |
84 | EXCLUDES="*.swp #* *~ *.key ifstate adjtime ld.so.cache shadow* \ | |
85 | blkid.tab* aumixrc net.enable mtab \ | |
86 | vdirbase run.rev vdir run.rev" | |
87 | LOCALE="C" | |
88 | ||
89 | _MAIL_SUBJECT="`hostname -f` - changes report" | |
90 | _NO_DEBIAN_PACKAGES_CHANGE="No change in Debian packages state." | |
91 | _NO_CHANGE="No change." | |
92 | ||
93 | MAIN_HEADER=" | |
94 | c h a n g e s r e p o r t | |
95 | --------------------------- | |
96 | ||
97 | " | |
98 | ||
99 | CHANGELOGS_HEADER=" | |
100 | ||
101 | Changelogs | |
102 | ========== | |
103 | ||
104 | " | |
105 | ||
106 | FILES_HEADER=" | |
107 | ||
108 | Changed files | |
109 | ============= | |
110 | ||
111 | " | |
112 | ||
113 | DEBIAN_PACKAGES_HEADER=" | |
114 | ||
115 | Changes in Debian packages | |
116 | ========================== | |
117 | ||
118 | " | |
119 | ||
120 | FILES_DETAILS_HEADER=" | |
121 | ||
122 | Details for changed files | |
123 | ========================= | |
124 | ||
125 | " | |
126 | ||
127 | if [ "$1" = "-h" ]; then | |
128 | if [ -f /etc/metche/$2.conf ]; then | |
129 | . /etc/metche/$2.conf | |
130 | CMD="$3" | |
131 | MILESTONE="$4" | |
132 | else | |
133 | display_usage | |
134 | fatal "Config file /etc/metche/$2.conf does not exist." | |
135 | fi | |
136 | elif [ -f /etc/metche.conf ]; then | |
137 | . /etc/metche.conf | |
138 | CMD="$1" | |
139 | MILESTONE="$2" | |
140 | else | |
141 | display_usage | |
142 | fatal "Config file not found." | |
143 | fi | |
144 | ||
145 | PATH="/bin:/usr/bin" | |
146 | unset LC_ALL | |
147 | unset LC_CTYPE | |
148 | unset LANGUAGE | |
149 | unset LANG | |
150 | umask 077 | |
151 | ||
152 | test -d "$WATCHED_DIR" || fatal "WATCHED_DIR ($WATCHED_DIR) does not exist." | |
153 | test -d "$BACKUP_DIR" || fatal "BACKUP_DIR ($BACKUP_DIR) does not exist." | |
154 | test -z "$TAR_OPTS" || fatal "TAR_OPTS is deprecated, use EXCLUDES instead." | |
155 | ||
156 | if [ "$DO_PACKAGES" = "yes" ]; then | |
157 | which apt-show-versions > /dev/null || | |
158 | executable_not_found "apt-show-versions" "it" "DO_PACKAGES" | |
159 | fi | |
160 | ||
161 | if [ "$ENCRYPT_EMAIL" = "yes" ]; then | |
162 | which gpg > /dev/null || | |
163 | executable_not_found "gpg" "GnuPG" "ENCRPYT_EMAIL" | |
164 | gpg --batch --list-public-keys $EMAIL_ADDRESS >/dev/null 2>&1 || | |
165 | fatal "GnuPG public key for $EMAIL_ADDRESS not found." | |
166 | fi | |
167 | ||
168 | DATE=`date "+%Y%m%d%H%M"` | |
169 | WATCHED_PARENT=`dirname $WATCHED_DIR` | |
170 | if [ "$WATCHED_PARENT" != '/' ]; then | |
171 | WATCHED_PARENT="$WATCHED_PARENT/" | |
172 | fi | |
173 | ||
174 | # How to use $TAR_OPTS: | |
175 | # - $TAR_OPTS should be used unquoted | |
176 | # - 'set -o noglob' has to be run before any $TAR_OPTS use | |
177 | # - 'set +o noglob' has to be run after any $TAR_OPTS use | |
178 | TAR_OPTS="" | |
179 | set -o noglob | |
180 | for pattern in $EXCLUDES; do | |
181 | TAR_OPTS="$TAR_OPTS --exclude=$pattern" | |
182 | done | |
183 | set +o noglob | |
184 | ||
185 | # How to use $FIND_OPTS: | |
186 | # - $FIND_OPTS should appear unquoted between: | |
187 | # . the (optional) target files and directories | |
188 | # . the (compulsory) action, such as -print or -exec | |
189 | # - 'set -o noglob' has to be run before any $FIND_OPTS use | |
190 | # - 'set +o noglob' has to be run after any $FIND_OPTS use | |
191 | FIND_OPTS="" | |
192 | set -o noglob | |
193 | # DO NOT fix me: the final -or at the end of $FIND_OPTS is really needed | |
194 | for pattern in $EXCLUDES; do | |
195 | FIND_OPTS="$FIND_OPTS -path */$pattern -prune -or" | |
196 | done | |
197 | set +o noglob | |
198 | ||
199 | ### | |
200 | ### Modules enabling/disabling | |
201 | ### | |
202 | ||
203 | DO_CHANGELOGS="no" | |
204 | if [ "$CHANGELOG_DIR" ]; then | |
205 | if [ -d "$CHANGELOG_DIR" ]; then | |
206 | DO_CHANGELOGS="dir" | |
207 | fi | |
208 | elif [ -f "$CHANGELOG_FILE" ]; then | |
209 | DO_CHANGELOGS="file" | |
210 | fi | |
211 | ||
212 | # Debian packages | |
213 | # Enabled/disabled by $DO_PACKAGES, initialized to "yes", can be | |
214 | # overriden by the sourced conf file. | |
215 | ||
216 | ||
217 | ### | |
218 | ### A few functions to do the real work | |
219 | ### | |
220 | ||
221 | # Returns 0 if, and only if, specified milestone exists. | |
222 | milestone_exists() { | |
223 | local milestone="$1" | |
224 | if [ -f "${BACKUP_DIR}/${milestone}.tar.bz2" -o \ | |
225 | -L "${BACKUP_DIR}/${milestone}.tar.bz2" ]; then | |
226 | return 0 | |
227 | else | |
228 | return 1 | |
229 | fi | |
230 | } | |
231 | ||
232 | # Echoes the given milestone's version (i.e. "stable", "testing", "unstable") | |
233 | # if it has a valid version, else "none". | |
234 | # The given milestone can be inexistant. | |
235 | milestone_version() { | |
236 | local milestone="$1" | |
237 | local version="`echo $milestone | sed 's/-.*$//'`" | |
238 | case $version in | |
239 | stable|testing|unstable) | |
240 | echo $version;; | |
241 | *) | |
242 | echo "none";; | |
243 | esac | |
244 | } | |
245 | ||
246 | # Echoes given milestone's date. | |
247 | # Symlinks (e.g.: *-latest) are dereferenced if needed. | |
248 | # The given milestone can be inexistant. | |
249 | milestone_date() { | |
250 | local milestone="$1" | |
251 | ||
252 | if [ -L "${BACKUP_DIR}/${milestone}.tar.bz2" ]; then | |
253 | milestone="`readlink ${BACKUP_DIR}/${milestone}.tar.bz2`" | |
254 | fi | |
255 | echo `basename $milestone` | sed 's/.*-//' | sed 's/\..*$//' | |
256 | } | |
257 | ||
258 | # Returns 0 if, and only if, the given milestone ($1) is the latest one | |
259 | # of its type. | |
260 | # The given milestone can be inexistant. | |
261 | is_latest() { | |
262 | local file milestone ref_milestone ref_date ref_version | |
263 | ||
264 | ref_milestone="$1" | |
265 | ref_date="`milestone_date $ref_milestone`" | |
266 | ref_version="`milestone_version $ref_milestone`" | |
267 | for file in "${BACKUP_DIR}/${ref_version}-"*.tar.bz2; do | |
268 | milestone=`basename $file | sed 's/\.tar\.bz2$//'` | |
269 | if [ "`milestone_date $milestone`" -gt "$ref_date" ]; then | |
270 | return 1 | |
271 | fi | |
272 | done | |
273 | return 0 | |
274 | } | |
275 | ||
276 | # This will save an archive of the watched directory with the given prefix | |
277 | save_files() { | |
278 | debug " - save_files $@" | |
279 | set -o noglob | |
280 | tar jcf "$BACKUP_DIR/$1-$DATE".tar.bz2 \ | |
281 | -C "$WATCHED_PARENT" $TAR_OPTS `basename "$WATCHED_DIR"` | |
282 | set +o noglob | |
283 | ln -sf "$1-$DATE".tar.bz2 "$BACKUP_DIR/$1"-latest.tar.bz2 | |
284 | } | |
285 | ||
286 | # This will save packages list with the given prefix | |
287 | save_packages() { | |
288 | debug " - save_packages $@" | |
289 | apt-show-versions -i | |
290 | apt-show-versions | | |
291 | sort > "$BACKUP_DIR/$1-$DATE".packages | |
292 | ln -sf "$1-$DATE".packages "$BACKUP_DIR/$1"-latest.packages | |
293 | } | |
294 | ||
295 | # This will save Changelogs with the given prefix | |
296 | save_changelogs() { | |
297 | debug " - save_changelogs $@" | |
298 | local changelog domain file | |
299 | ||
300 | if [ "$DO_CHANGELOGS" = "dir" ]; then | |
301 | for file in "$CHANGELOG_DIR"/*/Changelog; do | |
302 | changelog="${file##$CHANGELOG_DIR/}" | |
303 | domain="${changelog%%/Changelog}" | |
304 | cat "$file" > "$BACKUP_DIR/$1-$DATE.$domain.Changelog" | |
305 | ln -sf "$1-$DATE.$domain.Changelog" \ | |
306 | "$BACKUP_DIR/$1-latest.$domain.Changelog" | |
307 | done | |
308 | elif [ "$DO_CHANGELOGS" = "file" ]; then | |
309 | cat "$CHANGELOG_FILE" > "$BACKUP_DIR/$1-$DATE.Changelog" | |
310 | ln -sf "$1-$DATE.Changelog" "$BACKUP_DIR/$1-latest.Changelog" | |
311 | fi | |
312 | } | |
313 | ||
314 | # Save whatever reflect the current state with the given prefix | |
315 | save_state() { | |
316 | debug "save_state $@" | |
317 | save_files "$1" | |
318 | [ $DO_PACKAGES = "no" ] || save_packages "$1" | |
319 | [ $DO_CHANGELOGS = "no" ] || save_changelogs "$1" | |
320 | } | |
321 | ||
322 | # Report changes against given version to standard output | |
323 | report_changes() { | |
324 | debug "report_changes $@" | |
325 | local tmp tmpdir changelog domain diff tar_diff diff_diff | |
326 | local files old new tmp_packages file | |
327 | ||
328 | # File to store results | |
329 | tmp=`mktemp -q` | |
330 | # We need to diff against given version, so extract it | |
331 | tmpdir=`mktemp -d -q` | |
332 | tar jxf "$BACKUP_DIR/$1".tar.bz2 -C "$tmpdir" | |
333 | ||
334 | echo "$MAIN_HEADER" >> "$tmp" | |
335 | ||
336 | if [ $DO_CHANGELOGS = "dir" ]; then | |
337 | echo "$CHANGELOGS_HEADER" >> "$tmp" | |
338 | for file in "$CHANGELOG_DIR"/*/Changelog; do | |
339 | changelog="${file##$CHANGELOG_DIR/}" | |
340 | domain="${changelog%%/Changelog}" | |
341 | diff=`LC_ALL=$LOCALE \ | |
342 | diff -wEbBN "$BACKUP_DIR/$1.$domain.Changelog" \ | |
343 | "$file"` || | |
344 | # diff returns false when files differ | |
345 | (echo "$domain:" ; echo "$diff" | | |
346 | grep -v '^[0-9-]\|^\\') >> "$tmp" | |
347 | done | |
348 | fi | |
349 | if [ $DO_CHANGELOGS = "file" ]; then | |
350 | echo "$CHANGELOGS_HEADER" >> "$tmp" | |
351 | diff=`LC_ALL=$LOCALE \ | |
352 | diff -wEbBN "$BACKUP_DIR/$1.Changelog" "$CHANGELOG_FILE"` || | |
353 | # diff returns false when files differ | |
354 | (echo "$diff" | grep -v '^[0-9-]\|^\\') >> "$tmp" | |
355 | fi | |
356 | ||
357 | echo "$FILES_HEADER" >> "$tmp" | |
358 | ||
359 | # Find differences with tar | |
360 | set -o noglob | |
361 | tar_diff=$(tar jdf "$BACKUP_DIR/$1".tar.bz2 \ | |
362 | -C "$WATCHED_PARENT" $TAR_OPTS 2>&1 | | |
363 | # transform: | |
364 | # etc/issue: Gid differs -> etc/issue | |
365 | # tar: etc/irssi.conf: ... -> etc/irssi.conf | |
366 | sed -e 's/\(tar: \)\?\([^:]*\):.*/\2/') | |
367 | # Get new files | |
368 | diff_diff=$(diff -qr $TAR_OPTS "$tmpdir"/`basename "$WATCHED_DIR"` \ | |
369 | "$WATCHED_DIR" 2>/dev/null | | |
370 | # Only in test/etc: issue -> test/etc/issue | |
371 | sed -n -e "s,^Only in $WATCHED_PARENT\([^:]*\): \(.*\),\1/\2,p") | |
372 | files="`echo "$tar_diff$diff_diff" | sort -u`" | |
373 | set +o noglob | |
374 | if [ -z "$files" ]; then | |
375 | echo "$_NO_CHANGE" >> "$tmp" | |
376 | else | |
377 | for file in $files; do | |
378 | old="$tmpdir"/"$file" | |
379 | new="$WATCHED_PARENT$file" | |
380 | if [ -e "$old" -a -e "$new" ]; then | |
381 | echo -n '< ' | |
382 | ls -ld "$old" | sed -e "s;$tmpdir/;;" | |
383 | echo -n '> ' | |
384 | ls -ld "$new" | sed -e "s;$WATCHED_PARENT;;" | |
385 | elif [ -e "$old" ]; then | |
386 | echo -n '- ' | |
387 | ls -ld "$old" | sed -e "s;$tmpdir/;;" | |
388 | elif [ -e "$new" ]; then | |
389 | echo -n '+ ' | |
390 | ls -ld "$new" | sed -e "s;$WATCHED_PARENT;;" | |
391 | fi | |
392 | done >> "$tmp" | |
393 | fi | |
394 | ||
395 | if [ "$DO_PACKAGES" = "yes" ]; then | |
396 | echo "$DEBIAN_PACKAGES_HEADER" >> "$tmp" | |
397 | ||
398 | tmp_packages=`mktemp -q` | |
399 | apt-show-versions -i | |
400 | apt-show-versions | sort > "$tmp_packages" | |
401 | if diff -wEbB "$BACKUP_DIR/$1".packages "$tmp_packages"; then | |
402 | echo "$_NO_DEBIAN_PACKAGES_CHANGE" | |
403 | fi | grep -v '^[0-9-]' >> "$tmp" | |
404 | fi | |
405 | ||
406 | if [ "$DO_DETAILS" = "yes" ]; then | |
407 | echo "$FILES_DETAILS_HEADER" >> "$tmp" | |
408 | ||
409 | # Just diff it! | |
410 | set -o noglob | |
411 | if (LC_ALL=$LOCALE diff -urBN $TAR_OPTS \ | |
412 | --minimal "$tmpdir"/`basename "$WATCHED_DIR"` \ | |
413 | "$WATCHED_DIR" 2>/dev/null); then | |
414 | echo "$_NO_CHANGE" | |
415 | fi | grep -v '^--- \|diff ' | | |
416 | sed -e "s;^+++ $WATCHED_PARENT\([^ ]*\) .*;+++ \1;" \ | |
417 | >> "$tmp" | |
418 | set +o noglob | |
419 | fi | |
420 | ||
421 | # Put on standard output | |
422 | cat "$tmp" | |
423 | ||
424 | # Clean temporaries | |
425 | rm -rf "$tmp" "$tmpdir" | |
426 | } | |
427 | ||
428 | # Turns into stable the given testing. | |
429 | # NB: argument validity is supposed to have been already checked. | |
430 | stabilize_state() { | |
431 | debug "stabilize_state $@" | |
432 | local testing stable file dst | |
433 | ||
434 | testing="$1" | |
435 | # follow symlink if needed | |
436 | if [ -L "${BACKUP_DIR}/$testing".tar.bz2 ]; then | |
437 | testing="`readlink ${BACKUP_DIR}/${testing}.tar.bz2`" | |
438 | testing="`basename $testing | sed 's/\..*//'`" | |
439 | fi | |
440 | stable="`echo $testing | sed 's/^testing/stable/'`" | |
441 | for file in "${BACKUP_DIR}/${testing}"*; do | |
442 | dst="`echo $file | sed 's/\/testing-/\/stable-/'`" | |
443 | cp "$file" "$dst" | |
444 | # create/change stable-latest* links if, and only if, | |
445 | # it's really the latest | |
446 | if is_latest $stable; then | |
447 | ln -sf "`basename $dst`" "${BACKUP_DIR}/`basename $dst | | |
448 | sed 's/-[0-9]*\./-latest\./'`" | |
449 | fi | |
450 | done | |
451 | } | |
452 | ||
453 | # Print watched directory and files separated by spaces | |
454 | # (suitable for find) | |
455 | # Note: this function needs pathname expansion, but is called from places where | |
456 | # it is disabled; that's why we need to save the pathname expansion status | |
457 | # in the beginning and reset it to end with. | |
458 | print_watched_files() { | |
459 | local files | |
460 | local reset_noglob_status_cmd | |
461 | ||
462 | files="$WATCHED_DIR" | |
463 | reset_noglob_status_cmd="`set +o | grep 'set .o noglob'`" | |
464 | set +o noglob | |
465 | if [ "$DO_CHANGELOGS" = "dir" ]; then | |
466 | files="$files `echo "$CHANGELOG_DIR"/*/Changelog`" | |
467 | elif [ "$DO_CHANGELOGS" = "file" ]; then | |
468 | files="$files $CHANGELOG_FILE" | |
469 | fi | |
470 | $reset_noglob_status_cmd | |
471 | echo "$files" | |
472 | } | |
473 | ||
474 | # Return true if watched files has not changed since $1 minutes | |
475 | no_change_since() { | |
476 | local time | |
477 | ||
478 | time="$1" | |
479 | set -o noglob | |
480 | if [ -z "$(find $(print_watched_files) $FIND_OPTS -cmin "-$time" -print | head -1)" ]; then | |
481 | set +o noglob | |
482 | return 0 | |
483 | else | |
484 | set +o noglob | |
485 | return 1 | |
486 | fi | |
487 | } | |
488 | ||
489 | # Return true if watched files has changed since file $1 last modification | |
490 | changed_from() { | |
491 | local ref_file | |
492 | ||
493 | ref_file="$1" | |
494 | set -o noglob | |
495 | if [ "$(find $(print_watched_files) $FIND_OPTS -newer "$ref_file" -print | head -1)" ]; then | |
496 | set +o noglob | |
497 | return 0 | |
498 | else | |
499 | set +o noglob | |
500 | return 1 | |
501 | fi | |
502 | } | |
503 | ||
504 | ### | |
505 | ### Main | |
506 | ### | |
507 | ||
508 | # make sure we've got at least one testing and one stable | |
509 | milestone_exists testing-latest || save_state "testing" | |
510 | milestone_exists stable-latest || stabilize_state "testing-latest" | |
511 | ||
512 | case "$CMD" in | |
513 | ||
514 | report) | |
515 | DO_DETAILS="yes" | |
516 | if [ -z "$MILESTONE" ]; then | |
517 | report_changes "testing-latest" | |
518 | elif milestone_exists "$MILESTONE"; then | |
519 | report_changes "$MILESTONE" | |
520 | else | |
521 | display_usage | |
522 | fatal "The specified state does not exist." | |
523 | fi | |
524 | ;; | |
525 | ||
526 | list) | |
527 | for file in "$BACKUP_DIR"/*.tar.bz2; do | |
528 | echo `basename ${file%%.tar.bz2}` | |
529 | done | |
530 | ;; | |
531 | ||
532 | cron) | |
533 | STABLE_TIME_MIN=`expr 24 '*' 60 '*' "$STABLE_TIME"` | |
534 | ||
535 | ### Algorithm | |
536 | # | |
537 | # if (no change happened for TESTING_TIME) then | |
538 | # if (something has changed since the last testing) then | |
539 | # send a report against last testing | |
540 | # save a new testing state | |
541 | # delete all saved unstable states | |
542 | # elif (no change happened for STABLE_TIME) then | |
543 | # if (something has changed since the last stable) then | |
544 | # save a new stable state and notify EMAIL_ADDRESS | |
545 | # delete all saved testing states older than STABLE_TIME | |
546 | # fi | |
547 | # fi | |
548 | # elif (last unstable exists) then | |
549 | # if (something has changed since the last unstable) then | |
550 | # save a new unstable state | |
551 | # fi | |
552 | # else | |
553 | # save a new unstable state | |
554 | # fi | |
555 | if no_change_since "$TESTING_TIME"; then | |
556 | debug "no change since TESTING_TIME" | |
557 | if changed_from "$BACKUP_DIR"/testing-latest.tar.bz2; then | |
558 | debug "changed from testing-latest" | |
559 | report_changes "testing-latest" | email "testing-$DATE" | |
560 | save_state "testing" | |
561 | debug "removing all saved unstable states." | |
562 | find "$BACKUP_DIR" -name 'unstable-*' -exec rm "{}" \; | |
563 | elif no_change_since "$STABLE_TIME_MIN"; then | |
564 | if changed_from "$BACKUP_DIR"/stable-latest.tar.bz2; then | |
565 | save_state "stable" | |
566 | echo "metche saved a new stable state : stable-${DATE}." | | |
567 | email "stable-$DATE" | |
568 | debug "removing all saved testing states older " \ | |
569 | "than STABLE_TIME ($STABLE_TIME)." | |
570 | find "$BACKUP_DIR" -name 'testing-*' \ | |
571 | -ctime +"$STABLE_TIME" -exec rm "{}" \; | |
572 | fi | |
573 | fi | |
574 | elif milestone_exists unstable-latest; then | |
575 | if changed_from "$BACKUP_DIR"/unstable-latest.tar.bz2; then | |
576 | debug "changed from unstable-latest" | |
577 | save_state "unstable" | |
578 | fi | |
579 | else | |
580 | save_state "unstable" | |
581 | fi | |
582 | ;; | |
583 | ||
584 | stabilize) | |
585 | if [ -z "$MILESTONE" ]; then | |
586 | stabilize_state "testing-latest" | |
587 | elif [ "`milestone_version $MILESTONE`" = "testing" -a \ | |
588 | milestone_exists $MILESTONE ]; then | |
589 | stabilize_state "$MILESTONE" | |
590 | else | |
591 | display_usage | |
592 | fatal "The specified state is not an existing testing state." | |
593 | fi | |
594 | ;; | |
595 | ||
596 | test) | |
597 | milestone_version "stable-200507040202" | |
598 | milestone_version "testing-latest" | |
599 | milestone_version "testing-200507030047" | |
600 | milestone_version "testing-200507030047qsfd" | |
601 | milestone_date "stable-200507040202" | |
602 | milestone_date "testing-latest" | |
603 | milestone_date "testing-200507030047" | |
604 | milestone_date "testing-200507030047qsfd" | |
605 | (is_latest testing-latest && echo oui) || echo non | |
606 | (is_latest testing-200507031821 && echo oui) || echo non | |
607 | (is_latest stable-200507031831 && echo oui) || echo non | |
608 | (is_latest stable-200507040202 && echo oui) || echo non | |
609 | ;; | |
610 | ||
611 | *) | |
612 | display_usage | |
613 | exit 1 | |
614 | ;; | |
615 | esac | |
616 | ||
617 | # vim: et sw=4 |
0 | <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" | |
1 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> | |
2 | ||
3 | <RefEntry id="metche"> | |
4 | ||
5 | <refmeta> | |
6 | <refentrytitle>metche</refentrytitle> | |
7 | <manvolnum>8</manvolnum> | |
8 | </refmeta> | |
9 | ||
10 | <refnamediv> | |
11 | <refname>metche</refname> | |
12 | <refpurpose>reducing root bus factor</refpurpose> | |
13 | </refnamediv> | |
14 | ||
15 | <refsynopsisdiv> | |
16 | <cmdsynopsis> | |
17 | <command>metche</command> | |
18 | <group choice="req"> | |
19 | <arg>cron</arg> | |
20 | <arg>report | |
21 | <arg choice="opt"> | |
22 | <group choice="req"> | |
23 | <arg>stable</arg> | |
24 | <arg>testing</arg> | |
25 | <arg>unstable</arg> | |
26 | </group>-<replaceable>YYYYMMDDHHMM</replaceable> | |
27 | </arg> | |
28 | </arg> | |
29 | <arg>list</arg> | |
30 | <arg>stabilize <arg choice="opt">testing-<replaceable>YYYYMMDDHHMM</replaceable></arg></arg> | |
31 | </group> | |
32 | </cmdsynopsis> | |
33 | </refsynopsisdiv> | |
34 | ||
35 | <refsect1 id="description"> | |
36 | ||
37 | <title>DESCRIPTION</title> | |
38 | ||
39 | <Para>metche is a tool meant to facilitate collective sysadmin by | |
40 | monitoring changes in the system configuration.</Para> | |
41 | ||
42 | <Para>metche basic usage is to monitor changes in a directory, usually | |
43 | <filename>/etc</filename> ; optionally, metche can also | |
44 | monitor:</Para> | |
45 | <ItemizedList> | |
46 | <ListItem> | |
47 | <Para>one or more user maintained changelog files, | |
48 | </ListItem> | |
49 | <ListItem> | |
50 | <Para>the state of Debian packages and versions.</Para> | |
51 | </ListItem> | |
52 | </ItemizedList> | |
53 | ||
54 | <Para>metche should be installed with a cronjob that regularly runs to | |
55 | automatically save the system state as needed. These states are saved in a | |
56 | way similar to the Debian development model:</Para> | |
57 | <ItemizedList> | |
58 | <ListItem> | |
59 | <Para><emphasis>unstable</emphasis> states are saved as soon as | |
60 | a change is detected. They are kept until a new | |
61 | <emphasis>testing</emphasis> state appears.</Para> | |
62 | </ListItem> | |
63 | <ListItem> | |
64 | <Para><emphasis>testing</emphasis> states is created from the last | |
65 | <emphasis>unstable</emphasis> state that has not been changed | |
66 | after a short amount of time (by default, one hour). Old | |
67 | <emphasis>unstable</emphasis> states are deleted afterwards.</Para> | |
68 | </ListItem> | |
69 | <ListItem> | |
70 | <Para><emphasis>stable</emphasis> states are created from the last | |
71 | <emphasis>testing</emphasis> state, either manually, or after a | |
72 | long amount of time (by default, 3 days). Old <emphasis | |
73 | >testing</emphasis> states are deleted afterwards.</Para> | |
74 | </ListItem> | |
75 | </ItemizedList> | |
76 | ||
77 | <Para>When a new <emphasis>testing</emphasis> state is saved, an email is | |
78 | sent to a configurable address, giving an overwiew of | |
79 | the differences with the previous <emphasis>testing</emphasis>. | |
80 | A notification is also sent when a new <emphasis>stable</emphasis> state is | |
81 | saved.</Para> | |
82 | ||
83 | <Para>metche's configuration is read from | |
84 | <filename>/etc/metche.conf</filename>. Various settings like changelog | |
85 | monitoring or time between system state switches are described | |
86 | there.</Para> | |
87 | ||
88 | </refsect1> | |
89 | <refsect1 id="options"> | |
90 | ||
91 | <title>OPTIONS</title> | |
92 | ||
93 | <Para>One of the following commands must be specified on the | |
94 | command line:</Para> | |
95 | ||
96 | <VariableList> | |
97 | ||
98 | <VarListEntry><Term><command>report</command></Term> | |
99 | <ListItem> | |
100 | <Para>When run with the <command>report</command> command, metche | |
101 | displays a report against the specified saved state, or if unspecified, | |
102 | against the latest testing state. This is useful when you | |
103 | have broken your system and want to know which changes have been made | |
104 | since a given, known working, system state. | |
105 | </ListItem> | |
106 | ||
107 | <VarListEntry><Term><command>list</command></Term> | |
108 | <ListItem> | |
109 | <Para>When run with the <command>list</command> command, metche | |
110 | displays a list of all the saved states.</Para> | |
111 | </ListItem> | |
112 | ||
113 | <VarListEntry><Term><command>stabilize</command></Term> | |
114 | <ListItem> | |
115 | <Para>When run with the <command>stabilize</command> command, metche | |
116 | turns a "testing state" into a "stable state". By default, it will | |
117 | use the last "testing state", but this can be overriden by giving | |
118 | a specific state as argument.</Para> | |
119 | </ListItem> | |
120 | ||
121 | <VarListEntry><Term><command>cron</command></Term> | |
122 | <ListItem> | |
123 | <Para>This command should not be called manually, but used from | |
124 | a cronjob. When called, it can perform various operations like: | |
125 | saving "unstable", "testing" or "stable" states as needed and | |
126 | sending reports and notification if configured to do so.</Para> | |
127 | </ListItem> | |
128 | ||
129 | </VariableList> | |
130 | ||
131 | </refsect1> | |
132 | ||
133 | <refsect1 id="files"><title>FILES</title> | |
134 | <Para><filename>/etc/metche.conf</filename> contains metche configuration. | |
135 | </Para> | |
136 | ||
137 | <Para>When configured to monitor one changelog, | |
138 | <filename><envar>CHANGELOG_FILE</envar></filename> (default | |
139 | <filename>/root/Changelog</filename>). | |
140 | </Para> | |
141 | ||
142 | <Para>When configured to monitor multiple changelogs, | |
143 | <filename><envar>CHANGELOG_DIR</envar>/*/Changelog</filename> | |
144 | (default : <filename>/root/changelogs</filename>).</Para> | |
145 | ||
146 | <Para>System states are saved in | |
147 | <filename><envar>BACKUP_DIR</envar></filename> (default | |
148 | <filename>/var/lib/metche)</filename>.</Para> | |
149 | </refsect1> | |
150 | ||
151 | <refsect1 id="security"><title>SECURITY</title> | |
152 | <Para>metche is able to use GnuPG to encrypt the email it sends, but does | |
153 | not by default; just enable the <envar>ENCRYPT_EMAIL</envar> configuration | |
154 | option, and make sure <envar>EMAIL_ADDRESS</envar>' public key is in root's | |
155 | keyring, trusted enough to be used blindly by metche.</Para> | |
156 | ||
157 | <Para>In its default setup (<envar>ENCRYPT_EMAIL</envar> configuration | |
158 | option disabled) metche sends in <emphasis>clear text email</emphasis> the | |
159 | changes made to the watched directory... either make sure that the | |
160 | <envar>TAR_OPTS</envar> configuration variable prevents it to send sensitive | |
161 | information, or triple check that secure connections will be used end-to-end | |
162 | on the email path. If unsure, set <envar>EMAIL_ADDRESS</envar> configuration | |
163 | variable to a local mailbox.</Para> | |
164 | ||
165 | <Para>metche stores, in <envar>BACKUP_DIR</envar> (default : | |
166 | <filename>/var/lib/metche</filename>), various backups of | |
167 | <envar>WATCHED_DIR</envar>. Make sure that this backup place is at least as | |
168 | secured as the source. | |
169 | </refsect1> | |
170 | ||
171 | <refsect1 id="bugs"><title>BUGS</title> | |
172 | <Para>See <ulink url="https://poivron.org/dev/metche/">metche's ticket | |
173 | system</ulink> for known bugs, missing features, and the development | |
174 | road-map.</Para> | |
175 | </refsect1> | |
176 | ||
177 | <refsect1 id="author"><title>AUTHOR</title> | |
178 | <Para>This manual page was written by the boum collective | |
179 | <email>boum@anargeek.net</email>.</Para> | |
180 | </refsect1> | |
181 | ||
182 | </RefEntry> | |
183 |
0 | ####################################################################### | |
1 | # | |
2 | # metche configuration | |
3 | # | |
4 | ||
5 | # Directory watched by metche | |
6 | WATCHED_DIR="/etc" | |
7 | ||
8 | # Directory containing backups | |
9 | BACKUP_DIR="/var/lib/metche" | |
10 | ||
11 | # Activate single changelog file monitoring | |
12 | CHANGELOG_FILE="/root/Changelog" | |
13 | ||
14 | # Activate multiple changelogs file monitoring. | |
15 | # Each "Changelog" should be in a sub-directory of CHANGELOG_DIR. | |
16 | # (Override CHANGELOG_FILE if both are set) | |
17 | #CHANGELOG_DIR="/root/changelogs" | |
18 | ||
19 | # Debian packages monitoring (need apt-show-versions) | |
20 | DO_PACKAGES="no" | |
21 | ||
22 | # Show diff details for modified files | |
23 | # WARNING! This can send sensitive data by e-mail if not used with encryption. | |
24 | DO_DETAILS="no" | |
25 | ||
26 | # Minutes until unstable goes to testing | |
27 | TESTING_TIME="60" | |
28 | ||
29 | # Days until testing goes to stable | |
30 | STABLE_TIME="3" | |
31 | ||
32 | # Address receiving testing changes report | |
33 | EMAIL_ADDRESS="root@localhost" | |
34 | ||
35 | # Encrypt emails with GnuPG ? (uncomment next line to do so) | |
36 | #ENCRYPT_EMAIL="yes" | |
37 | ||
38 | # Filename patterns to ignore (space-separated list) | |
39 | # GNU tar --exclude pattern matching rules are used: | |
40 | # - If a pattern matches a directory, all the files beneath it are | |
41 | # recursively excluded. | |
42 | # - Periods (`.') or forward slashes (`/') are not considered special for | |
43 | # wildcard matches. | |
44 | # Example (default value): | |
45 | #EXCLUDES="*.swp #* *~ *.key ifstate adjtime ld.so.cache shadow* \ | |
46 | # blkid.tab* aumixrc net.enable mtab \ | |
47 | # vdirbase run.rev vdir run.rev" | |
48 | ||
49 | # Locale (will be used to feed LC_ALL) | |
50 | # Warning: values different from "C" are untested. | |
51 | LOCALE="C" | |
52 | ||
53 | # Set this to yes to get more debugging output. | |
54 | DEBUG="no" | |
55 | ||
56 | ####################################################################### | |
57 | # | |
58 | # Localizable strings | |
59 | # | |
60 | ||
61 | # Add your custom headers below | |
62 | ||
63 | #_MAIL_SUBJECT="`hostname -f` - changes report" | |
64 | #_NO_DEBIAN_PACKAGES_CHANGE="No change in Debian packages state." | |
65 | #_NO_CHANGE="No change." | |
66 | #MAIN_HEADER="" | |
67 | #CHANGELOGS_HEADER="" | |
68 | #FILES_HEADER="" | |
69 | #DEBIAN_PACKAGES_HEADER="" | |
70 | #FILES_DETAILS_HEADER="" |