mirror of
https://0xacab.org/liberate/backupninja.git
synced 2024-11-10 04:42:31 +01:00
creating a debian only branch out of what used to be a subversion repository
This commit is contained in:
parent
386c427594
commit
27a7859c42
50
.gitignore
vendored
50
.gitignore
vendored
@ -1,50 +0,0 @@
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
configure
|
||||
etc/Makefile.in
|
||||
examples/Makefile.in
|
||||
handlers/Makefile.in
|
||||
install-sh
|
||||
lib/Makefile.in
|
||||
man/Makefile.in
|
||||
missing
|
||||
src/Makefile.in
|
||||
Makefile
|
||||
backupninja.spec
|
||||
config.log
|
||||
config.status
|
||||
etc/Makefile
|
||||
etc/backupninja.conf
|
||||
etc/cron.d/backupninja
|
||||
etc/logrotate.d/backupninja
|
||||
examples/Makefile
|
||||
handlers/Makefile
|
||||
handlers/dup
|
||||
handlers/dup.helper
|
||||
handlers/ldap
|
||||
handlers/ldap.helper
|
||||
handlers/maildir
|
||||
handlers/makecd
|
||||
handlers/makecd.helper
|
||||
handlers/mysql
|
||||
handlers/mysql.helper
|
||||
handlers/pgsql
|
||||
handlers/pgsql.helper
|
||||
handlers/rdiff
|
||||
handlers/rdiff.helper
|
||||
handlers/rsync
|
||||
handlers/sh
|
||||
handlers/svn
|
||||
handlers/sys
|
||||
handlers/sys.helper
|
||||
handlers/trac
|
||||
lib/Makefile
|
||||
lib/easydialog
|
||||
lib/parseini
|
||||
lib/tools
|
||||
lib/vserver
|
||||
man/Makefile
|
||||
src/Makefile
|
||||
src/backupninja
|
||||
src/ninjahelper
|
31
AUTHORS
31
AUTHORS
@ -1,31 +0,0 @@
|
||||
BACKUPNINJA was written by the Riseup Collective: intellectual property is theft.
|
||||
|
||||
Ninjas:
|
||||
|
||||
elijah@riseup.net -- original code, bug fixes, man pages
|
||||
micah@riseup.net -- debian package, vserver support, bug fixes
|
||||
stefani@riseup.net -- makecd handler, man pages
|
||||
intrigeri@boum.org -- dup handler, pgsql handler, vserver support, bug fixes
|
||||
Charles Lepple -- trac handler
|
||||
Petr Klíma <petr.klima@madeta-group.cz> -- autotools, RPM support and sys checks
|
||||
paulv@bikkel.org -- rsnap handler
|
||||
Robert Napier -- improved RPM build
|
||||
rhatto -- rub handler and patches
|
||||
|
||||
Patches:
|
||||
|
||||
cmccallum@thecsl.org
|
||||
Daniel.Bonniot@inria.fr -- mysql ignores and nodata
|
||||
Brad Fritz <brad@fritzfam.com> -- trac patch
|
||||
garcondumonde@riseup.net
|
||||
Martin Krafft madduck@debian.org -- admingroup patch
|
||||
Anarcat -- lotsa patches
|
||||
Jamie McClelland -- cstream patches
|
||||
ale -- ldap cleanup
|
||||
Sami Haahtinen <ressu@ressukka.net>
|
||||
Matthew Palmer -- mysql enhancements
|
||||
romain.tartiere@healthgrid.org -- ldap fixes
|
||||
Adam Monsen - spec file updates
|
||||
Matthew Palmer <mpalmer@debian.org> -- halt loglevel feature
|
||||
dan@garthwaite.org -- reportspace bugfix
|
||||
Tuomas Jormola <tj@solitudo.net> -- "when = manual" option
|
340
COPYING
340
COPYING
@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
536
ChangeLog
536
ChangeLog
@ -1,536 +0,0 @@
|
||||
version 0.9.7 -- UNRELEASED
|
||||
backupninja changes
|
||||
. fix bug in reportspace, thanks Dan Garthwaite
|
||||
. do not assume English locale when using date (Closes: #465837)
|
||||
. add 'when = manual' option, that can be used in the global config
|
||||
file or in a given backup action file. Thanks Tuomas Jormola for the
|
||||
preliminary patch (Closes: #511299)
|
||||
handler changes
|
||||
maildir:
|
||||
. fix location of deleted_on file
|
||||
. add missing destid_file options to ssh connections
|
||||
mysql:
|
||||
. Options passed to mysqldump are now customizable with the new
|
||||
sqldumpoptions configuration variable. Thanks to Chris Lamb for his
|
||||
preliminary patch (Closes: #502966)
|
||||
. Hide 'mysqladmin ping' output, to prevent confusing the user in
|
||||
case mysqld is running but the authentication fails, which apparently
|
||||
does not prevent mysqldump to work.
|
||||
. Fix the error message displayed when mysqld is not running:
|
||||
mysqladmin ping indeed returns 0 when authentication fails.
|
||||
sys:
|
||||
. New luksheaders option (default=disabled) to backup the Luks header
|
||||
of every Luks device.
|
||||
. New lvm option (default=disabled) to backup LVM metadata for every
|
||||
detected volume group.
|
||||
. Backup dmsetup info as well, for easier restoring of Luks headers.
|
||||
|
||||
version 0.9.6 -- July 21, 2008
|
||||
backupninja changes
|
||||
. fix bug in cstream definition, thanks Jamie McClelland
|
||||
. Allow the entire backup run to be halted by an action, thanks to
|
||||
Matthew Palmer (Closes: #455836)
|
||||
. Fixed tr construct reporting a warning (Closes: #452669)
|
||||
lib changes
|
||||
vserver:
|
||||
. added vservers_running function
|
||||
tools
|
||||
. mktemp is now required to run backupninja, removed less secure
|
||||
fall-back if mktemp did not exist on the system
|
||||
handler changes
|
||||
dup:
|
||||
. General cleanup
|
||||
. Better support for new duplicity (>= 0.4.4) command line syntax:
|
||||
run remove-older-than when $keep is not set to yes (Closes: #458816),
|
||||
and run "duplicity cleanup" before any other duplicity command; both
|
||||
only trigger a warning on failure, since they should not stop backups
|
||||
from being done. Also migrated full/incremental backup switch to the
|
||||
new syntax.
|
||||
. Support every duplicity-supported transport with new configuration
|
||||
option desturl (Closes: #483712, #346040, Trac#2).
|
||||
. Actually allow to backup only VServers, by relaxing $include test.
|
||||
. Set secure permissions on tmpdir when creating it.
|
||||
ldap:
|
||||
. support HDB backend just as the BDB one, and make message clearer
|
||||
when no supported backend is found (Closes: #476910)
|
||||
rdiff:
|
||||
. Fixed ignore_version default value missing
|
||||
. Add patch from Matthew Palmer to rdiff handler to incorporate sshoptions
|
||||
into options via remote-schema not already specified (Closes: #424639)
|
||||
wget:
|
||||
. New handler from rhatto designed to incrementally pull content from
|
||||
a website to a local folder, based on the rsync handler
|
||||
maildir:
|
||||
. fixed bug where maildirs that start with a number were skipped
|
||||
. make maildir helper look in every subdirectory of the source directory for
|
||||
maildirs, rather than just looking in the directories [a-zA-Z0-9], thanks
|
||||
for the patch from chris@cenolan.com (Trac#43).
|
||||
. make deleted maildirs record the date they were deleted
|
||||
. add destid_file configuration option to enable you to specify an alternate
|
||||
ssh public key authentication file (defaulting to /root/.ssh/id_rsa)
|
||||
pgsql, mysql, svn, sys:
|
||||
. use new vservers_running function from lib/vserver (factorization++)
|
||||
sys:
|
||||
. update for 2.6 kernels: use /proc/kallsyms instead of /proc/ksyms
|
||||
(Closes: Trac#39)
|
||||
. support selection of VServers to run on, in the same way as in the
|
||||
dup handler, with the new vsnames configuration option ; (Closes: Trac#45)
|
||||
. add support for capturing the package debconf selection states using
|
||||
debconf-get-selections
|
||||
. fixed catifexec function to actually work, also now passes the arguments
|
||||
given to catifexec() to the called command (Thanks John Hallam!)
|
||||
. Added more robust software RAID information capture by running mdadm
|
||||
-Q --detail /dev/md?* because some people may have empty mdadm.conf files
|
||||
(Thanks to John Hallam).
|
||||
trac:
|
||||
. stop failing on all the trac backups if just one fails, this means
|
||||
removing the temporary trac backup directories if they fail
|
||||
makecd
|
||||
. updated handler for new toolset (genisoimage and wodim)
|
||||
|
||||
version 0.9.5 -- December 2, 2007
|
||||
backupninja changes
|
||||
. Fixed checks on configuration files permissions, since the patch
|
||||
applied to fix #370396 broke this, especially for configuration files
|
||||
created with permissions 000 by an older ninjahelper version.
|
||||
. Enhanced portability for other platforms
|
||||
. Added quoting because it was needed to prevent shell expansion, broking the
|
||||
toint function sometimes (Closes: Trac#11)
|
||||
. Fixed reportspace option (Closes: Trac#10)
|
||||
. Fixed ldap handler not recognizing database suffix (Closes: Trac#28)
|
||||
handler changes
|
||||
dup:
|
||||
. Support duplicity >= 0.4.3 invocation syntax (--ssh-command option
|
||||
is not supported anymore) (Closes: #447425)
|
||||
. New tmpdir configuration option, very useful in case duplicity tends
|
||||
to fill up /tmp.
|
||||
ldap:
|
||||
. Fixed shell command quoting issues, missing 'then' clauses, cleaned up
|
||||
compress=yes to be less redundant and not create empty uncompressed
|
||||
file (Closes: #394935)
|
||||
. Fixed ninjahelper to properly set compress option, standardized on yes/no
|
||||
instead of on/off
|
||||
. Fixed problem that caused combination of slapcat and compress to not work
|
||||
together (Closes: Trac#29)
|
||||
. Applied patch from romain.tartiere@healthgrid.org to fix the SSL/TLS options
|
||||
to be correct, also set TLS to be the default over SSL (Closes: Trac#13)
|
||||
maildir:
|
||||
. Added an examples file (Closes: Trac#23)
|
||||
. Applied patch from Anarcat that fixes the cp/mkdir calls to not use GNU
|
||||
coreutils options, as well as some bashisms (Closes: Trac#24)
|
||||
. Fix test mode (Closes: Trac#25)
|
||||
mysql:
|
||||
. Fixed case where odd combination of configuration options caused sqldump
|
||||
backups to get overwritten with an empty file (Closes: #402679)
|
||||
. Added 'nodata' option to enable you to specify tables that you want to omit
|
||||
the data from a backup, but still backup the table structure. This is very
|
||||
useful in cases where tables contain large amounts of cache data. See the
|
||||
example.mysql for options, thanks Daniel Bonniot (Closes: #408829)
|
||||
. Enhance code for selecting databases by asking MySQL not to give us the
|
||||
header (-N), to not draw pretty boxes around the output (-B), send the query
|
||||
via -e instead of a pipe and ensure MySQL listens to -B. Thanks to
|
||||
Matthew Palmer (Closes: #452039).
|
||||
pgsql:
|
||||
. Support configuring PGSQLUSER for real, and document it a bit; this
|
||||
broken support actually prevented pgsql handler to work for VServers
|
||||
(Closes: #396578)
|
||||
rdiff-backup:
|
||||
. Added cstream support to allow for bandwidth limiting
|
||||
. Handle "keep = yes" to disable old backups removal (Closes: #424633)
|
||||
. Add configuration option to allow you to disable the version check
|
||||
as in some instances this may be an ok scenario (Closes: #424632)
|
||||
. Added local destination support to helper (Closes: Trac#4)
|
||||
. Allow exclude-only configurations (Closes: Trac#21)
|
||||
rub/rsync
|
||||
. Fixed typo in rub handler that caused it to not work
|
||||
. Changed to use lib/vserver code
|
||||
. Fixed fsck error
|
||||
. Fixed integer comparison (Closes: Trac#3)
|
||||
. Renamed handler to 'rsync', replaces outdated rub handler
|
||||
. updated examples/Makefile.am and handlers/Makefile.am to include
|
||||
rsnap/rsync (Closes: #440554)
|
||||
. Added example.rsync configuration file
|
||||
sys:
|
||||
. Fixed typo breaking things for VServers.
|
||||
. Fix bug when vrootdir is on its own partition (Closes: #395928)
|
||||
. Better sfdisk error and output handling: should now properly warn
|
||||
when it does not manage to backup a partition table, and shut up when
|
||||
it succeeds (Closes: #396632)
|
||||
. Added option to not use sfdisk at all, useful for vserver/xen instances
|
||||
that produce warnings about no harddisks found (Closes: #404071)
|
||||
. Fixed example in example.sys to detail the __star__ in partitionsfile and
|
||||
note why its necessary (Closes: #409192)
|
||||
. Force C locale for sfdisk to ensure english words are found in grep
|
||||
. Make directory where output is placed configurable, and create the parent dir
|
||||
if it doesn't exist (Closes: Trac#1)
|
||||
ninjareport
|
||||
. Added first draft of method to aggregate reports from many servers into
|
||||
one email. Requires logtail, rsync, configuration of reporthost,
|
||||
reportdirectory and reportuser in backupninja.conf. Configure cron to
|
||||
run once a day, and individual backupninjas not to report by email their
|
||||
status, then enjoy one email report from all hosts, rather than multiple
|
||||
fixed 'make install' bug that failed if /etc/backup.d already existed
|
||||
changed spaces to tabs in Makefile.am
|
||||
updated redhat spec file (thanks Adam Monsen)
|
||||
|
||||
version 0.9.4 -- October 6th, 2006
|
||||
backupninja changes
|
||||
. Fixed bug in toint(), and thus isnow(), which caused it
|
||||
to not work when run from cron.
|
||||
. Recursively ignore subdirs in /etc/backup.d (Closes: #361102)
|
||||
. Add admingroup option to configuration to allow a group that can
|
||||
read/write configurations (instead of only allowing root). Checks
|
||||
and complains about group-readable files only when the group differs
|
||||
from the one in the configuration file (default is root as before).
|
||||
Thanks to Martin Krafft for the patch (Closes: #370396).
|
||||
. When determining which backup actions to make, find now follows
|
||||
symlinks for $configdirectory
|
||||
. Changed order of -s to mail for compatibility
|
||||
. fixed permission stat call so it uses the --format supported by
|
||||
coreutils (Closes: #382747)
|
||||
. Added disk space report option (thanks Adam Kosmin)
|
||||
handler changes
|
||||
Added tar handler:
|
||||
. create tarballs
|
||||
Added rsnap handler:
|
||||
. rotated rsync snapshops
|
||||
. code from paulv@bikkel.org
|
||||
Added rub handler:
|
||||
. alternative to rsnap
|
||||
. code from rhatto@riseup.net
|
||||
mysql:
|
||||
. Fixed improper use of $vuserhome (Closes: #351083)
|
||||
. Fixed erroneous removal of tmpfile when it didn't exit
|
||||
. Fixed inversed vsname emptiness check
|
||||
. Fixed su quote usage to be more posixy
|
||||
. Compress for sqldumps now happens in-line to save some disk space (Closes: #370778)
|
||||
. Fixed --defaults-file now as --defaults-extra-file (thanks rhatto)
|
||||
pgsql:
|
||||
. Fixed inversed vsname emptiness check
|
||||
. Fixed su quote usage to be more posixy
|
||||
. Fixed shell expansion, thanks Thomas Kotzian (Closes: #363297)
|
||||
. postgres user UID is now the one from inside the vserver if necessary
|
||||
. Compress now happens in-line to save some disk space (Closes: #370778)
|
||||
. $PGSQLUSER is used instead of hardcoding user 'postgres' (although this is the default)
|
||||
svn:
|
||||
. Fixed inversed vsname emptiness check
|
||||
rdiff:
|
||||
. Symlink and globbing support in include/exclude/vsinclude
|
||||
clarification: globbing is fully supported again, whereas no attempt
|
||||
is done to dereference symlinks anymore, due to incompatibilities
|
||||
between various readlink versions in this field.
|
||||
. Removed overzealous vsnames check
|
||||
. Now works if testconnect=no and if $test is not defined.
|
||||
. add $sshoptions config parameter in [dest] section of config so
|
||||
connections to ports other than 22 can be made by adding the
|
||||
following to the top of the handler config:
|
||||
options = --remote-schema 'ssh -p REMOTE-PORT -C %s rdiff-backup
|
||||
--server'
|
||||
dup:
|
||||
. Symlink and globbing support in include/exclude/vsinclude
|
||||
clarification: globbing is fully supported again, whereas no attempt
|
||||
is done to dereference symlinks anymore, due to incompatibilities
|
||||
between various readlink versions in this field.
|
||||
. Removed over zealous vsnames check
|
||||
. Does not pretend anymore that duplicity can work without
|
||||
any passphrase
|
||||
. Support duplicity 0.4.2 (with Debian patches applied; upstream's
|
||||
0.4.3 will integrate them); documented how to write sftp-compatible
|
||||
sshoptions (Closes: #388543)
|
||||
. Now forbid to (try to) include /.
|
||||
sys:
|
||||
. Many more system checks were added, (thanks to Petr Klíma)
|
||||
. Added warning if no devices were found (thanks Ranier Zocholl)
|
||||
. Enhanced debian package selections to include purged packages (thanks
|
||||
Tom Hoover)
|
||||
. Removed warning about vserver not running (thanks anarcat)
|
||||
ldap:
|
||||
. Compress now happens in-line to save some disk space (Closes: #370778)
|
||||
makecd:
|
||||
. Added nicelevel option (thanks rhatto)
|
||||
trac:
|
||||
. fixed problem when src was set to the trac repo directly (Closes: #382737)
|
||||
lib changes
|
||||
vserver:
|
||||
. init_vservers: fixed Debian bug #351083 (improper readlink syntax)
|
||||
. found_vservers: escaped special grep repetition character +
|
||||
. forced mktemp to use a template with a name to be more compatible with
|
||||
different versions of mktemp, thanks anarcat
|
||||
ninjahelper changes
|
||||
. Recursively ignore subdirs in /etc/backup.d (Closes: #361102)
|
||||
. Fix configdirectory error that forced you to use /etc/backup.d, thanks anarcat
|
||||
. When determining which backup actions to list, find now follows
|
||||
symlinks for $configdirectory
|
||||
. Stop checking helpers perms: both "make install" and distros packages
|
||||
install them with appropriate permissions, it's overzealous to check
|
||||
this at runtime, and is more complicated to do with current
|
||||
admingroup option.
|
||||
dup.helper:
|
||||
. Fix: signing was enabled with symmetric encryption.
|
||||
changed cron permissions to 644
|
||||
changed /etc/backup.d permissions to 0770 (for admingroup)
|
||||
minor documentation fixes
|
||||
improved RPM build process allowing 'make rpm-package' and 'make
|
||||
srpm-package' targets, also fixes permissions on man directories,
|
||||
cleans up RPM-related files during distclean, and adds default
|
||||
EDITOR for "autogen.sh -f" if none is set. (thanks Robert Napier)
|
||||
|
||||
version 0.9.3 -- February 1st, 2006
|
||||
autotools fixes
|
||||
backupninja changes
|
||||
backupninja.conf
|
||||
. added (commented out) the various default paths to
|
||||
programs such as PGSQLDUMP, so that users can figure
|
||||
out more easily they can customize them
|
||||
code refactor:
|
||||
. now uses vservers lib to initialize vservers support
|
||||
handler changes
|
||||
duplicity, mysql, pgsql, rdiff, svn, sys: start to use (at different
|
||||
degrees) new lib/vserver functionality
|
||||
mysql:
|
||||
. fixed no user defaults file processing
|
||||
duplicity:
|
||||
. fixed (again...) globbing in include and exclude options (Debian bug
|
||||
#348022, follow-up to #338796)
|
||||
. warn if vsnames or vsinclude is enabled while vservers support is
|
||||
disabled in backupninja.conf
|
||||
. now works when multiple vservers names are given (separated by space)
|
||||
in vsnames config variable
|
||||
rdiff
|
||||
. fixed globbing bug in include, exclude and vsinclude options
|
||||
. it's now possible to choose exactly which vservers should be
|
||||
backed-up, as it already was with duplicity handler, with the
|
||||
"vsnames" configuration setting
|
||||
ninjahelper changes
|
||||
rdiff.helper:
|
||||
. fixed errors in create remote dir
|
||||
. code formatting cleanup (three spaces indent)
|
||||
. fixed bug which caused only first include/exclude dir to
|
||||
have "include = "
|
||||
. fixed globbing bug with exclude
|
||||
ninjahelper:
|
||||
. now reports error if the helper script has a syntax error or bombs out.
|
||||
. code formatting cleanup (three spaces indent)
|
||||
lib changes
|
||||
vserver:
|
||||
. init_vservers: improved VROOTDIR detection
|
||||
. init_vservers: test in a stricter way the real vservers availability
|
||||
. init_vservers: canonicalize VROOTDIR (since duplicity et al.
|
||||
don't follow symlinks)
|
||||
. init_vservers: warn if vservers are enabled but no vserver is found
|
||||
. new function: vservers_exist
|
||||
known bugs:
|
||||
easydialog:
|
||||
. formDisplay does not return exit status.
|
||||
|
||||
version 0.9.2 -- December 29, 2005
|
||||
backupninja changes
|
||||
fixed broken toint() which caused when "everyday" problems
|
||||
backupninja.conf.5 updated to include "when" and "vservers"
|
||||
code refactor:
|
||||
. moved to lib/ some code that has to be shared between
|
||||
backupninja and ninjahelper
|
||||
handler changes
|
||||
trac:
|
||||
. mkdir subdirectory problem fixed
|
||||
duplicity:
|
||||
. globbing support fixed in include and exclude options
|
||||
. different signing and encrypting key support added
|
||||
. fixed erroneous comments in example.dup about the way
|
||||
GnuPG-related options are used
|
||||
mysql:
|
||||
. handler vserver bugs fixed and debug output enhanced
|
||||
ninjahelper(s) changes
|
||||
vserver-related functions added to lib/vservers.in
|
||||
added man/ninjahelper.1 man page
|
||||
makecd:
|
||||
. was missing in Makefile.am/.in
|
||||
rdiff-backup:
|
||||
. used to expand '*' in default source directories
|
||||
. the "Cancel" buttons used to have a weird behaviour
|
||||
. updated to include Vserver selection
|
||||
pgsql:
|
||||
. forbid the user to choose an empty database set
|
||||
. "Cancel" button now does what it is meant to do
|
||||
mysql:
|
||||
. enhanced for vserver support
|
||||
. now able to select databases and dump directory
|
||||
duplicity:
|
||||
. new handler added (with Vserver support)
|
||||
|
||||
version 0.9.1 -- November 05 2005
|
||||
rearranged source so that it is relocatable with autotools
|
||||
(thanks to Petr Klíma petr.klima@madeta-group.cz)
|
||||
fixed many bugs in rdiff helper
|
||||
rdiff handler does not require 'label' (for real this time?)
|
||||
added makecd ninjahelper
|
||||
(thanks to Stefani stefani@riseup.net)
|
||||
made ninjahelper create files with mode 600 rather than 000
|
||||
changed subversion handler to use svnadmin hotcopy instead of
|
||||
the unsupported hot-copy.py script, which was moved in Debian
|
||||
update rdiff ninjahelper
|
||||
now detects and auto-install rdiff-backup on the remote
|
||||
machine if possible, also tests the remote backup directory
|
||||
and offers to create it if it doesn't exist
|
||||
|
||||
version 0.9 -- October 19 2005
|
||||
*** IMPORTANT CHANGE, UPGRADE AT ONCE ***
|
||||
fixed insecure temporary file creation
|
||||
*****************************************
|
||||
removed erroneous magic file marker in pgsql handler
|
||||
fixed incorrect find positional
|
||||
changed direct grep of /etc/passwd to getent passwd.
|
||||
rdiff helper has much better information on failed ssh attempt
|
||||
(patch from cmccallum@thecsl.org).
|
||||
rdiff handler now supports remote source and local dest.
|
||||
(patch from cmccallum@thecsl.org).
|
||||
man pages are greatly improved.
|
||||
|
||||
version 0.8 -- September 15 2005
|
||||
added pgsql (PostgreSQL) handler, with vservers support.
|
||||
added vservers support to duplicity handler
|
||||
Note: the configuration is a bit different than the rdiff
|
||||
handler's one, but the default behavior is the same:
|
||||
have a look at example.dup.
|
||||
improved README
|
||||
documented .disabled method.
|
||||
corrected VROOTDIR default value.
|
||||
added ninjahelper to the install instructions.
|
||||
improved rdiff, dup and sys handlers' vservers support
|
||||
prevent vserver-debiantools' $VROOTDIR/ARCHIVES directory
|
||||
to be seen as a vserver
|
||||
changes to sys handler
|
||||
make use of configurable $VSERVERINFO instead of hard-coded vserver-info.
|
||||
fixed dpkg existence test inside vserver.
|
||||
fixed $nodpkg use.
|
||||
changes to pgsql handler
|
||||
now checks if the specified vserver is running.
|
||||
now checks if $PGSQLDUMP/$PGSQLDUMPALL are available where needed.
|
||||
now checks if "postgres" user exists on the host/vserver.
|
||||
changes to ninjahelper
|
||||
check_perms() does not die anymore on group/world readable
|
||||
helper scripts (now consistent with the "helper scripts
|
||||
must not be group or world writable!" error msg).
|
||||
xedit action now tries $EDITOR, then /etc/alternatives/editor,
|
||||
then nano, vim and vi, and aborts if none of these exists.
|
||||
added helper for pgsql handler.
|
||||
rdiff handler now does not require 'label'
|
||||
changes to mysql and svn handlers' vservers support
|
||||
these handlers now check if the source vserver is running
|
||||
added 'ignores' for mysql handler. (thanks Daniel.Bonniot@inria.fr)
|
||||
|
||||
version 0.7 -- July 26 2005
|
||||
added ninjahelper: a dialog based wizard for creating backupninja configs.
|
||||
considerably improved and changed the log file output.
|
||||
you can now disable actions with .disabled (this is new preferred method).
|
||||
added makecd handler and example.makecd for backing up to cd/dvd (thanks stef).
|
||||
fixed bug when specifying multiple 'when' options.
|
||||
|
||||
version 0.6 -- June 16 2005
|
||||
ldap handler has new options: backup method to use (ldapsearch or
|
||||
slapcat), restart, passwordfile and binddn. Default backup method
|
||||
is set to ldapsearch as this is safer
|
||||
******************************************************************
|
||||
NOTE: to get the previous default behavior with the ldap handler,
|
||||
you must set "method = slapcat". The new default is ldapsearch.
|
||||
******************************************************************
|
||||
implemented fix so that the main script will echo fatal errors rather
|
||||
than being silent about them, this means an error message every hour
|
||||
if there is a major configuration problem (not a handler problem)
|
||||
added vserver support to main script and to the handlers: mysql, svn, sys, rdiff
|
||||
changes to duplicity handler (thanks intrigeri!):
|
||||
"keep = yes" now disables file cleaning on desthost
|
||||
added "sign" option for backups signing
|
||||
added "encryptkey" option to specify the gpg key to use
|
||||
split config into [source], [gpg] and [dest] sections
|
||||
added "nicelevel" option
|
||||
added "testconnect" option
|
||||
added "sshoptions" option (will be passed to ssh/scp)
|
||||
added "bandwidthlimit" option
|
||||
example.dup example config file for duplicity handler
|
||||
added trac (http://trac.edgewall.com/) environment handler (thanks Charles Lepple!)
|
||||
added configfile option to mysql handler
|
||||
the default is /etc/mysql/debian.cnf. with this,
|
||||
sqldump doesn't need dbusername. (hotcopy still does).
|
||||
fixed bug in mysql handler which caused some passwords to not work.
|
||||
(.my.cnf files now have double quotes around password)
|
||||
can now pass options to hwinfo and sfdisk in sys handler.
|
||||
|
||||
version 0.5 -- April 12 2005
|
||||
rdiff handler works when remote sshd has a banner
|
||||
rdiff handler supports local dest
|
||||
logfile is created if it doesn't exist
|
||||
added "when = hourly"
|
||||
added optional 'nicelevel' to rdiff handler
|
||||
fixed bug where actions were not run in numeric order.
|
||||
improved 'when' parsing.
|
||||
|
||||
version 0.4.4 -- March 18 2005
|
||||
results of handlers are now read line by line.
|
||||
changes to rdiff handler: added "options", and "keep" is
|
||||
not necessarily days now (ie, it will pass straight through to
|
||||
rdiff-backup if the keep has a unit on it, otherwise it adds the 'D').
|
||||
added dup handler (still pretty beta)
|
||||
added maildir handler (very specialized handler)
|
||||
added --run option (runs the specified action file)
|
||||
improved sys handler, now uses hwinfo
|
||||
added subversion hotbackup handler, svn.
|
||||
added PATH to cron.d file, which fixes file not found errors.
|
||||
|
||||
version 0.4.2 -- Jan 6 2005
|
||||
fixed bug which caused a report email to be sent even if no actions were run.
|
||||
fixed bug where multiple handler status messages were ignored
|
||||
added status in the subject line of report emails
|
||||
|
||||
version 0.4.1 -- Jan 3 2005
|
||||
added $usecolors and now more conservative about when colors are echoed.
|
||||
fixed major bug, 'when' actually works now.
|
||||
replaced debug function with debug, info, warning, error, fatal.
|
||||
added --now option to force all actions to be performed now.
|
||||
|
||||
version 0.4 -- Dec 26 2004
|
||||
added "when" option, so that all configs can specify when
|
||||
they are to be run.
|
||||
added reportsuccess and reportwarning config options
|
||||
added .sys handler (hardware, packages, partitions).
|
||||
|
||||
version 0.3.4 -- Dec 8 2004
|
||||
fixed numerical variable quoting compatibility with older wc
|
||||
fixed stderr redirect bug
|
||||
some comments in example.rdiff
|
||||
|
||||
version 0.3.3 -- Nov 10 2004
|
||||
'*' (asterisk) works now in rdiff config files
|
||||
works now with gawk as well as mawk
|
||||
many bug fixes to ldap handler
|
||||
paths to helper scripts can be configured in global config
|
||||
does not require /usr/bin/stat
|
||||
|
||||
version 0.3.2 -- Sept 29 2004
|
||||
handler scripts are no longer executable (to comply with debian policy)
|
||||
handler error and warning messages are sent with the notify email
|
||||
|
||||
version 0.3.1 -- Sept 5 2004
|
||||
added ldap handler
|
||||
moved sh support to a handler script
|
||||
add test mode, where no action is taken.
|
||||
added --help
|
||||
force only root can read /etc/backup.d/*
|
||||
fixed missing equals symbols in example.rdiff
|
||||
changed backupninja executable to be /usr/sbin rather than /usr/bin
|
||||
|
||||
version 0.3 -- Oct 20 2004
|
||||
** IMPORTANT ** all config files are now ini style, not apache style
|
||||
rewrote all scripts in bash for portability
|
||||
added drop-in backupninja lib directory (/usr/share/backupninja)
|
||||
all scripts are now run as root
|
||||
|
||||
version 0.2 -- Oct 14 2004
|
||||
move distribution folder ./cron.d to ./etc/cron.d
|
||||
fixed bug: removed printr of excludes (!)
|
||||
added support for changing the user/group in rdiff sources.
|
||||
added support for .mysql config files.
|
||||
|
||||
version 0.1 -- Oct 8 2004
|
||||
initial release
|
||||
|
19
FAQ
19
FAQ
@ -1,19 +0,0 @@
|
||||
Q: duplicity works fine when run standalone, but complains about gpg
|
||||
"public key not found" when run from backupninja
|
||||
|
||||
A: We bet you're using sudo to run both duplicity and backupninja, and have been
|
||||
using sudo as well when generating the GnuPG key pair used by duplicity.
|
||||
|
||||
Quick fix: generate a new GnuPG key pair in a root shell, or using
|
||||
"sudo -H" instead of plain sudo.
|
||||
|
||||
Another solution: import the GnuPG keypair into the root user's keyring, taking
|
||||
care of running "gpg --update-trustdb" in a root shell or using "sudo -H"
|
||||
afterwards, in order to tag this keypair as "ultimately trusted".
|
||||
|
||||
Detailed explanation: sudo does not change $HOME by default, so GnuPG saved the
|
||||
newly generated key pair to your own keyring, rather than to the root user's
|
||||
keyring. Running "sudo duplicity" hides the problem, as it uses your own
|
||||
keyring. Running "sudo backupninja" reveals the problem, as backupninja uses
|
||||
"su" to make sure it runs duplicity in a real root environment, i.e. using the
|
||||
root user's GnuPG keyring.
|
231
INSTALL
231
INSTALL
@ -1,231 +0,0 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
||||
use PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
45
Makefile.am
45
Makefile.am
@ -1,45 +0,0 @@
|
||||
# vi: noexpandtab softtabstop=0
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
EXTRA_DIST = README COPYING AUTHORS INSTALL NEWS ChangeLog \
|
||||
backupninja.spec backupninja.spec.in autogen.sh
|
||||
|
||||
SUBDIRS = etc examples handlers lib man src
|
||||
|
||||
local_rpm_topdir=`cd $(top_srcdir) && pwd`/rpm
|
||||
rpm-package: dist
|
||||
if test x$(HAVE_RPM) = xyes ; then \
|
||||
mkdir -p $(local_rpm_topdir) ; \
|
||||
cd $(local_rpm_topdir) ; \
|
||||
mkdir -p BUILD RPMS SOURCES SPECS ; \
|
||||
cd SOURCES ; \
|
||||
$(LN_S) ../../$(distdir).tar.gz ; \
|
||||
cd .. ; \
|
||||
cd SPECS ; \
|
||||
$(LN_S) ../../backupninja.spec . ; \
|
||||
cd .. ; \
|
||||
rpmbuild --define "_topdir `cd . && pwd`" -bb SPECS/backupninja.spec && \
|
||||
echo "Package successfully built in `pwd`/RPMS." ; \
|
||||
else \
|
||||
echo "Error: RPM executable and/or source directory not found." ; \
|
||||
fi
|
||||
|
||||
srpm-package: dist
|
||||
if test x$(HAVE_RPM) = xyes ; then \
|
||||
mkdir -p $(local_rpm_topdir) ; \
|
||||
cd $(local_rpm_topdir) ; \
|
||||
mkdir -p BUILD SRPMS SOURCES SPECS ; \
|
||||
cd SOURCES ; \
|
||||
$(LN_S) ../../$(distdir).tar.gz ; \
|
||||
cd .. ; \
|
||||
cd SPECS ; \
|
||||
$(LN_S) ../../backupninja.spec . \
|
||||
cd .. ; \
|
||||
rpmbuild --define "_topdir `cd . && pwd`" -bs SPECS/backupninja.spec && \
|
||||
echo "Package successfully built in `pwd`/SRPMS." ; \
|
||||
else \
|
||||
echo "Error: RPM executable and/or source directory not found." ; \
|
||||
fi
|
||||
|
||||
clean-local:
|
||||
-rm -rf $(local_rpm_topdir)
|
33
NEWS
33
NEWS
@ -1,33 +0,0 @@
|
||||
backupninja (0.9.4-1) UNRELEASED
|
||||
|
||||
* duplicity: Old (pre-0.9.4) example.dup file used to give false
|
||||
information about the way the GnuPG-related options are used.
|
||||
Please read the new /usr/share/doc/backupninja/examples/example.dup
|
||||
file, and update your own configuration files if needed.
|
||||
|
||||
* duplicity, rdiff: symlinks and globbing support in
|
||||
include/exclude/vsinclude was unclear and did not work in all
|
||||
situations, with weird behavious, due to incompatibilities
|
||||
between various readlink versions in this field. This has been made
|
||||
clear eventually: globbing is fully supported again, whereas no
|
||||
attempt is done to dereference symlinks anymore.
|
||||
Please read the new /usr/share/doc/backupninja/examples/example.dup
|
||||
or /usr/share/doc/backupninja/examples/example.rdiff file, and update
|
||||
your own configuration files if needed.
|
||||
|
||||
* duplicity: duplicity now uses sftp, which does not support all scp
|
||||
command line options; you thus have to convert the sshoptions setting
|
||||
in your *.dup configuration files, to sftp-compatible syntax; for
|
||||
example, you can replace:
|
||||
sshoptions = -i /root/.ssh/id_dsa_duplicity
|
||||
with:
|
||||
sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity
|
||||
|
||||
backupninja (0.9.2-1) unstable; urgency=low
|
||||
|
||||
WARNING FOR DUPLICITY USERS
|
||||
|
||||
Old (pre-0.9.2) example.dup file used to give false information about the way
|
||||
the GnuPG-related options are used. Please read the new example.dup file, and
|
||||
update your own configuration files if needed.
|
||||
|
263
README
263
README
@ -1,263 +0,0 @@
|
||||
|
||||
|\_
|
||||
B A C K U P N I N J A /()/
|
||||
`\|
|
||||
|
||||
a silent flower blossom death strike to lost data.
|
||||
|
||||
Backupninja allows you to coordinate system backup by dropping a few
|
||||
simple configuration files into /etc/backup.d/. Most programs you
|
||||
might use for making backups don't have their own configuration file
|
||||
format. Backupninja provides a centralized way to configure and
|
||||
coordinate many different backup utilities.
|
||||
|
||||
Features:
|
||||
- easy to read ini style configuration files.
|
||||
- you can drop in scripts to handle new types of backups.
|
||||
- backup actions can be scheduled
|
||||
- you can choose when status report emails are mailed to you
|
||||
(always, on warning, on error, never).
|
||||
- console-based wizard (ninjahelper) makes it easy to create
|
||||
backup action configuration files.
|
||||
- passwords are never sent via the command line to helper programs.
|
||||
- works with Linux-Vservers (http://linux-vserver.org/)
|
||||
|
||||
Backup types:
|
||||
- secure, remote, incremental filesytem backup (via rdiff-backup).
|
||||
incremental data is compressed. permissions are retained even
|
||||
with an unpriviledged backup user.
|
||||
- backup of mysql databases (via mysqlhotcopy and mysqldump).
|
||||
- backup of ldap databases (via slapcat and ldapsearch).
|
||||
- basic system and hardware info
|
||||
- encrypted remote backups (via duplicity).
|
||||
- backup of subversion repositories.
|
||||
|
||||
The following options are available:
|
||||
-h, --help This usage message
|
||||
-d, --debug Run in debug mode, where all log messages are
|
||||
output to the current shell.
|
||||
-f, --conffile FILE Use FILE for the main configuration instead
|
||||
of /etc/backupninja.conf
|
||||
-t, --test Test run mode. This will test if the backup could run, without actually
|
||||
preforming any backups. For example, it will attempt to authenticate
|
||||
or test that ssh keys are set correctly.
|
||||
-n, --now Perform actions now, instead of when they might be scheduled.
|
||||
No output will be created unless also run with -d.
|
||||
--run FILE Runs the specified action FILE (e.g. one of the /etc/backup.d/ files).
|
||||
Also puts backupninja in debug mode.
|
||||
|
||||
CONFIGURATION FILES
|
||||
===================
|
||||
|
||||
The general configuration file is /etc/backupninja.conf. In this file
|
||||
you can set the log level and change the default directory locations.
|
||||
You can force a different general configuration file with "backupninja
|
||||
-f /path/to/conf".
|
||||
|
||||
To preform the actual backup, backupninja processes each configuration
|
||||
file in /etc/backup.d according to the file's suffix:
|
||||
|
||||
.sh -- run this file as a shell script.
|
||||
.rdiff -- filesystem backup (using rdiff-backup)
|
||||
.dup -- filesystem backup (using duplicity)
|
||||
.mysql -- backup mysql databases
|
||||
.ldap -- backup ldap databases
|
||||
.pgsql -- backup PostgreSQL databases
|
||||
.sys -- general hardware, partition, and system reports.
|
||||
.svn -- backup subversion repositories
|
||||
.maildir -- incrementally backup maildirs (very specialized)
|
||||
|
||||
Support for additional configuration types can be added by dropping
|
||||
bash scripts with the name of the suffix into /usr/share/backupninja.
|
||||
|
||||
The configuration files are processed in alphabetical order. However,
|
||||
it is suggested that you name the config files in "sysvinit style."
|
||||
|
||||
For example:
|
||||
00-disabled.ldap
|
||||
10-runthisfirst.sh
|
||||
20-runthisnext.mysql
|
||||
90-runthislast.rdiff
|
||||
|
||||
Typically, you will put a '.rdiff' config file last, so that any
|
||||
database dumps you make are included in the filesystem backup.
|
||||
Configurations files with names beginning with 0 (zero) or ending with
|
||||
.disabled (preferred method) are skipped.
|
||||
|
||||
Unless otherwise specified, the config file format is "ini style."
|
||||
|
||||
For example:
|
||||
|
||||
# this is a comment
|
||||
|
||||
[fishes]
|
||||
fish = red
|
||||
fish = blue
|
||||
|
||||
[fruit]
|
||||
apple = yes
|
||||
pear = no thanks \
|
||||
i will not have a pear.
|
||||
|
||||
|
||||
SCHEDULING
|
||||
==========
|
||||
|
||||
By default, each configuration file is processed everyday at 01:00 (1
|
||||
AM). This can be changed by specifying the 'when' option in a config
|
||||
file.
|
||||
|
||||
For example:
|
||||
|
||||
when = sundays at 02:00
|
||||
when = 30th at 22
|
||||
when = 30 at 22:00
|
||||
when = everyday at 01 <-- the default
|
||||
when = Tuesday at 05:00
|
||||
|
||||
A configuration file will be processed at the time(s) specified by the
|
||||
"when" option. If multiple "when" options are present, then they all
|
||||
apply. If two configurations files are scheduled to run in the same
|
||||
hour, then we fall back on the alphabetical ordering specified above.
|
||||
If two configurations files are scheduled close to one another in
|
||||
time, it is possible to have multiple copies of backupninja running if
|
||||
the first instance is not finished before the next one starts.
|
||||
|
||||
Make sure that you put the "when" option before any sections in your
|
||||
configuration file.
|
||||
|
||||
These values for 'when' are equivalent:
|
||||
|
||||
when = tuesday at 05:30
|
||||
when = TUESDAYS at 05
|
||||
|
||||
These values for 'when' are invalid:
|
||||
|
||||
when = tuesday at 2am
|
||||
when = tuesday at 2
|
||||
when = tues at 02
|
||||
|
||||
|
||||
REAL WORLD USAGE
|
||||
================
|
||||
|
||||
Backupninja can be used to implement whatever backup strategy you
|
||||
choose. It is intended, however, to be used like so:
|
||||
|
||||
(1) First, databases are safely copied or exported to /var/backups.
|
||||
Typically, you cannot make a file backup of a database while it
|
||||
is in use, hence the need to use special tools to make a safe copy
|
||||
or export into /var/backups.
|
||||
|
||||
(2) Then, vital parts of the file system, including /var/backups, are
|
||||
nightly pushed to a remote, off-site, hard disk (using
|
||||
rdiff-backup). The local user is root, but the remote user is not
|
||||
priviledged. Hopefully, the remote filesystem is encrypted.
|
||||
|
||||
There are many different backup strategies out there, including "pull
|
||||
style", magnetic tape, rsync + hard links, etc. We believe that the
|
||||
strategy outlined above is the way to go because: (1) hard disks are
|
||||
very cheap these days, (2) pull style backups are no good, because then
|
||||
the backup server must have root on the production server, and (3)
|
||||
rdiff-backup is more space efficient and featureful than using rsync +
|
||||
hard links.
|
||||
|
||||
|
||||
SSH KEYS
|
||||
========
|
||||
|
||||
In order for rdiff-backup to sync files over ssh unattended, you must
|
||||
create ssh keys on the source server and copy the public key to the
|
||||
remote user's authorized keys file. For example:
|
||||
|
||||
root@srchost# ssh-keygen -t dsa
|
||||
root@srchost# ssh-copy-id -i /root/.ssh/id_dsa.pub backup@desthost
|
||||
|
||||
Now, you should be able to ssh from user 'root' on srchost to
|
||||
user 'backup' on desthost without specifying a password.
|
||||
|
||||
Note: when prompted for a password by ssh-keygen, just leave it
|
||||
blank by hitting return.
|
||||
|
||||
The included helper program "ninjahelper" will walk you through creating
|
||||
an rdiff-backup configuration, and will set up the ssh keys for you.
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
Requirements:
|
||||
apt-get install bash gawk
|
||||
|
||||
Recommended:
|
||||
apt-get install rdiff-backup gzip hwinfo
|
||||
|
||||
Files:
|
||||
/usr/sbin/backupninja -- main script
|
||||
/etc/cron.d/backupninja -- runs main script nightly
|
||||
/etc/logrotate.d/backupninja -- rotates backupninja.log
|
||||
/etc/backup.d/ -- directory for configuration files
|
||||
/etc/backupninja.conf -- general options
|
||||
/usr/share/backupninja -- handler scripts which do the actual work
|
||||
|
||||
Installation:
|
||||
There is no install script, but you just need to move files to the
|
||||
correct locations. All files should be owned by root.
|
||||
|
||||
# tar xvzf backupninja.tar.gz
|
||||
# cd backupninja
|
||||
# mv backupninja /usr/sbin/backupninja
|
||||
# mv ninjahelper /usr/sbin/ninjahelper
|
||||
# mv etc/logrotate.d/backupninja /etc/logrotate.d/backupninja
|
||||
# mv etc/cron.d/backupninja /etc/cron.d/backupninja
|
||||
# mkdir /etc/backup.d/
|
||||
# mv etc/backupninja.conf /etc/backupninja.conf
|
||||
# mv handlers /usr/share/backupninja
|
||||
|
||||
|
||||
VSERVERS
|
||||
========
|
||||
|
||||
If you are using Linux-Vservers (http://linux-vserver.org/) there are some
|
||||
special capabilities that different handlers have to make vserver
|
||||
backups easier.
|
||||
|
||||
Set the variable "vservers" to be "yes" in /etc/backupninja.conf and see the
|
||||
example configuration files for each handler to configure the vserver specific
|
||||
variables.
|
||||
|
||||
Additional vserver variables that can be configured in /etc/backupninja.conf,
|
||||
but they probably don't need to be changed:
|
||||
|
||||
VSERVERINFO (default: /usr/sbin/vserver-info)
|
||||
VSERVER (default: /usr/sbin/vserver)
|
||||
VROOTDIR (default: `$VSERVERINFO info SYSINFO |grep vserver-Rootdir | awk '{print $2}'`)
|
||||
|
||||
NINJAHELPER
|
||||
===========
|
||||
|
||||
Ninjahelper is an additional script which will walk you through the process of
|
||||
configuring backupninja. Ninjahelper has a menu driven curses based interface
|
||||
(using dialog).
|
||||
|
||||
To add an additional 'wizard' to ninjahelper, follow these steps:
|
||||
|
||||
(1) to add a helper for the handler "blue", create the file
|
||||
blue.helper in the directory where the handlers live.
|
||||
(ie /usr/share/backupninja).
|
||||
|
||||
(2) next, you need to add your helper to the global HELPERS variable
|
||||
and define the main function for your helper (the function name
|
||||
is always <helper>_wizard). for example, blue.helper:
|
||||
HELPERS="$HELPERS blue:description_of_this_helper"
|
||||
blue_wizard() {
|
||||
... do work here ...
|
||||
}
|
||||
|
||||
(3) look at the existing helpers to see how they are written. Try to re-use
|
||||
functions, such as the dialog functions that are defined in easydialog.sh,
|
||||
or the vserver functions defined in lib/vserver.
|
||||
|
||||
(4) test, re-test, and test again. Try to break the helper by going backwards,
|
||||
try to think like someone who has no idea how to configure your handler
|
||||
would think, try to make your helper as simple as possible. Walk like a cat,
|
||||
become your shadow, don't let your senses betray you.
|
29
TODO
29
TODO
@ -1,29 +0,0 @@
|
||||
|
||||
This is a todo list, want to help? Pick something and let the list know
|
||||
you are working on it!
|
||||
|
||||
. Fix all bugs reported on the Debian BTS:
|
||||
http://bugs.debian.org/cgi-bin/pkgreport.cgi?which=pkg&data=backupninja&archive=no
|
||||
|
||||
. Fix all bugs reported on our Trac:
|
||||
https://code.autistici.org/trac/backupninja/report/3
|
||||
|
||||
. Make ninjahelper allow you to pick what type of backup you want (instead
|
||||
of just assuming you want local-to-remote, or push backups. Some people
|
||||
want local-to-local, or remote-to-local, or pull backups). This has been
|
||||
reported for the duplicity handler as Debian bug #346040.
|
||||
|
||||
. Make it so backupninja can be run as a regular user, instead of requiring
|
||||
root
|
||||
|
||||
. Allow vsnames "all" in the msyql handler.
|
||||
|
||||
. Factorize the rdiff.helper's connection-related functions into a lib, so
|
||||
that they can be used by dup.helper too. (NB: don't forget that the dup
|
||||
handler has a sshoptions configuration setting, that is often used to
|
||||
specify an alternative SSH key, or a specific IP to bind to.)
|
||||
|
||||
. Add an exclude option to database handlers so you can configure it to backup
|
||||
all databases, except for the excluded ones
|
||||
|
||||
. Consolidate the 'rsnap' and 'rub' handlers into one rsync snapshot handler
|
22
autogen.sh
22
autogen.sh
@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "x$EDITOR" = "x" ];
|
||||
then
|
||||
EDITOR=vi
|
||||
fi
|
||||
|
||||
if [ "x$1" = "x-f" ]
|
||||
then
|
||||
autoscan
|
||||
[ -f "configure.in" ] && cp "configure.in" "configure.in.old"
|
||||
mv -f "configure.scan" "configure.in"
|
||||
echo "## This is just AUTOSCAN draft of configure.in"
|
||||
$EDITOR "configure.in"
|
||||
fi
|
||||
|
||||
### použít jen když je třeba použít configure.h.in
|
||||
#autoheader
|
||||
|
||||
aclocal \
|
||||
&& automake -a -c \
|
||||
&& autoconf
|
@ -1,65 +0,0 @@
|
||||
%define name @PACKAGE_NAME@
|
||||
%define version @PACKAGE_VERSION@
|
||||
|
||||
Summary: Backupninja backup tool
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: 1
|
||||
License: GPL
|
||||
Group: Applications/System
|
||||
URL: http://dev.riseup.net/backupninja/
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
Requires: bash, gawk, rdiff-backup, gzip
|
||||
Provides: %{name}
|
||||
Packager: Petr Klima <Petr.Klima@madeta-group.cz>
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}
|
||||
Prefix: %{_prefix}
|
||||
|
||||
%description
|
||||
Modular rdiff.backup tool
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%configure
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf ${buildroot}
|
||||
%makeinstall
|
||||
mkdir -p "%{buildroot}%{_sysconfdir}/backup.d"
|
||||
mkdir -p "%{buildroot}%{_localstatedir}/backups"
|
||||
mkdir -p "%{buildroot}%{_localstatedir}/log"
|
||||
touch "%{buildroot}%{_localstatedir}/log/backupninja.log"
|
||||
|
||||
%clean
|
||||
rm -fr %{buildroot}
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%{_sbindir}/*
|
||||
%{_datadir}/backupninja/*
|
||||
%{_libdir}/backupninja/*
|
||||
|
||||
%config %{_sysconfdir}/cron.d/backupninja
|
||||
%config %{_sysconfdir}/logrotate.d/backupninja
|
||||
|
||||
%config(noreplace) %{_sysconfdir}/backupninja.conf
|
||||
%dir %{_localstatedir}/backups
|
||||
|
||||
%ghost %{_localstatedir}/log/backupninja.log
|
||||
|
||||
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README
|
||||
%{_mandir}/man1/*
|
||||
%{_mandir}/man5/*
|
||||
|
||||
%defattr(0640,root,root,0750)
|
||||
%dir %{_sysconfdir}/backup.d
|
||||
|
||||
|
||||
%changelog
|
||||
* Sun Oct 14 2007 Adam Monsen <haircut@gmail.com> 0.9.5-1
|
||||
- use cleanup steps during %install and %clean
|
||||
* Mon Apr 29 2002 Petr Klima <Petr.Klima@madeta-group.cz> 0.7.0
|
||||
- first RPM release
|
79
configure.in
79
configure.in
@ -1,79 +0,0 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
# The maintainer mode is causing me grief with newest versions of autotools
|
||||
#AM_MAINTAINER_MODE
|
||||
AC_INIT([backupninja],[0.9.6],[backupninja@lists.riseup.net])
|
||||
AC_CONFIG_SRCDIR([src/backupninja.in])
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# Checks for programs.
|
||||
|
||||
# BASH may already be set in the shell, if the admin then changes the
|
||||
# the /bin/sh symlink to a non-bash shell, all hell will break lose.
|
||||
unset BASH
|
||||
AC_PATH_PROGS(BASH, bash, "no", [$PATH:/bin:/usr/bin:/usr/sbin])
|
||||
if test x$BASH = "xno"; then
|
||||
AC_MSG_ERROR([bash is required])
|
||||
fi
|
||||
|
||||
AC_PATH_PROGS(SED, sed, "no")
|
||||
if test x$SED = "xno"; then
|
||||
AC_MSG_ERROR([sed is required])
|
||||
else
|
||||
export SED
|
||||
fi
|
||||
|
||||
AC_PATH_PROGS(AWK, awk, "no")
|
||||
if test x$AWK = "xno"; then
|
||||
AC_MSG_ERROR([awk is required])
|
||||
else
|
||||
export AWK
|
||||
fi
|
||||
|
||||
AC_PATH_PROGS(MKTEMP, mktemp, "no")
|
||||
if test x$MKTEMPT = "xno"; then
|
||||
AC_MSG_ERROR([mktemp is required])
|
||||
fi
|
||||
|
||||
AC_CHECK_PROG(ac_cv_have_rpm, rpm, "yes", "no")
|
||||
if test "x$ac_cv_have_rpm" = "xyes"; then
|
||||
rpm --define '_topdir /tmp' > /dev/null 2>&1
|
||||
AC_MSG_CHECKING(to see if we can redefine _topdir)
|
||||
if test $? -eq 0 ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
HAVE_RPM=yes
|
||||
else
|
||||
AC_MSG_RESULT(no. You'll have to build packages manually.)
|
||||
HAVE_RPM=no
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_RPM)
|
||||
|
||||
AC_CHECK_PROG(ac_cv_have_rpm, rpm, "yes", "no")
|
||||
if test "x$ac_cv_have_rpm" = "xyes"; then
|
||||
rpm --define '_topdir /tmp' > /dev/null 2>&1
|
||||
AC_MSG_CHECKING(to see if we can redefine _topdir)
|
||||
if test $? -eq 0 ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
HAVE_RPM=yes
|
||||
else
|
||||
AC_MSG_RESULT(no. You'll have to build packages manually.)
|
||||
HAVE_RPM=no
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(HAVE_RPM)
|
||||
|
||||
AC_PROG_LN_S
|
||||
|
||||
AC_SUBST([CFGDIR], "${sysconfdir}")
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
etc/Makefile
|
||||
examples/Makefile
|
||||
handlers/Makefile
|
||||
lib/Makefile
|
||||
man/Makefile
|
||||
src/Makefile])
|
||||
|
||||
AC_OUTPUT([ backupninja.spec])
|
@ -1,38 +0,0 @@
|
||||
|
||||
EXTRA_DIST = backupninja.conf.in cron.d/backupninja.in \
|
||||
logrotate.d/backupninja.in
|
||||
|
||||
GENERATED_FILES = backupninja.conf cron.d/backupninja logrotate.d/backupninja
|
||||
|
||||
CLEANFILES = $(GENERATED_FILES)
|
||||
|
||||
nobase_sysconf_DATA = $(GENERATED_FILES)
|
||||
|
||||
edit = sed \
|
||||
-e "s,@BASH\@,$(BASH),g" \
|
||||
-e "s,@CFGDIR\@,$(CFGDIR),g" \
|
||||
-e "s,@sysconfdir\@,$(sysconfdir),g" \
|
||||
-e "s,@localstatedir\@,$(localstatedir),g" \
|
||||
-e "s,@pkgdatadir\@,$(pkgdatadir),g" \
|
||||
-e "s,@pkglibdir\@,$(pkglibdir),g" \
|
||||
-e "s,@sbindir\@,$(sbindir),g" \
|
||||
-e "s,@exec_prefix\@,$(exec_prefix),g" \
|
||||
-e "s,@prefix\@,$(prefix),g"
|
||||
|
||||
cron.d/backupninja: cron.d/backupninja.in
|
||||
rm -f cron.d/backupninja
|
||||
$(edit) cron.d/backupninja.in > cron.d/backupninja
|
||||
chmod 644 cron.d/backupninja
|
||||
|
||||
logrotate.d/backupninja: logrotate.d/backupninja.in
|
||||
rm -f logrotate.d/backupninja
|
||||
$(edit) logrotate.d/backupninja.in > logrotate.d/backupninja
|
||||
chmod ugo+x logrotate.d/backupninja
|
||||
|
||||
backupninja.conf: backupninja.conf.in
|
||||
rm -f backupninja.conf
|
||||
$(edit) backupninja.conf.in > backupninja.conf
|
||||
|
||||
install-data-hook:
|
||||
mkdir -p $(DESTDIR)/$(sysconfdir)/backup.d
|
||||
chmod 0770 $(DESTDIR)/$(sysconfdir)/backup.d
|
@ -1,88 +0,0 @@
|
||||
#
|
||||
# |\_
|
||||
# B A C K U P N I N J A /()/
|
||||
# `\|
|
||||
# main configuration file
|
||||
#
|
||||
|
||||
# how verbose to make the logs
|
||||
# 5 -- Debugging messages (and below)
|
||||
# 4 -- Informational messages (and below)
|
||||
# 3 -- Warnings (and below)
|
||||
# 2 -- Errors (and below)
|
||||
# 1 -- Fatal errors (only)
|
||||
loglevel = 4
|
||||
|
||||
# send a summary of the backup status to
|
||||
# this email address:
|
||||
reportemail = root
|
||||
|
||||
# if set to 'yes', a report email will be generated
|
||||
# even if all modules reported success. (default = yes)
|
||||
reportsuccess = yes
|
||||
|
||||
# if set to 'yes', a report email will be generated
|
||||
# even if there was no error. (default = yes)
|
||||
reportwarning = yes
|
||||
|
||||
# if set to 'yes', disk space usage will be included in
|
||||
# the backup email report
|
||||
reportspace = no
|
||||
|
||||
# where to rsync the backupninja.log to be aggregated in
|
||||
# a ninjareport
|
||||
reporthost =
|
||||
|
||||
# what user to connect to reporthost to sync the
|
||||
# backupninja.log
|
||||
reportuser = ninja
|
||||
|
||||
# where on the reporthost should the report go
|
||||
# NOTE: the name of the log will be used in the report,
|
||||
# use a globally unique name, preferably the hostname
|
||||
reportdirectory = /var/lib/backupninja/reports
|
||||
|
||||
# set to the administration group that is allowed to
|
||||
# read/write configuration files in /etc/backup.d
|
||||
admingroup = root
|
||||
|
||||
#######################################################
|
||||
# for most installations, the defaults below are good #
|
||||
#######################################################
|
||||
|
||||
# where to log:
|
||||
logfile = @localstatedir@/log/backupninja.log
|
||||
|
||||
# directory where all the backup configuration files live
|
||||
configdirectory = @CFGDIR@/backup.d
|
||||
|
||||
# where backupninja helper scripts are found
|
||||
scriptdirectory = @pkgdatadir@
|
||||
|
||||
# where backupninja libs are found
|
||||
libdirectory = @pkglibdir@
|
||||
|
||||
# whether to use colors in the log file
|
||||
usecolors = yes
|
||||
|
||||
# default value for 'when'
|
||||
when = everyday at 01:00
|
||||
|
||||
# if running vservers, set to yes
|
||||
vservers = no
|
||||
|
||||
# programs paths
|
||||
# SLAPCAT=/usr/sbin/slapcat
|
||||
# LDAPSEARCH=/usr/bin/ldapsearch
|
||||
# RDIFFBACKUP=/usr/bin/rdiff-backup
|
||||
# CSTREAM=/usr/bin/cstream
|
||||
# MYSQL=/usr/bin/mysql
|
||||
# MYSQLHOTCOPY=/usr/bin/mysqlhotcopy
|
||||
# MYSQLDUMP=/usr/bin/mysqldump
|
||||
# PGSQLDUMP=/usr/bin/pg_dump
|
||||
# PGSQLDUMPALL=/usr/bin/pg_dumpall
|
||||
# GZIP=/bin/gzip
|
||||
# RSYNC=/usr/bin/rsync
|
||||
# VSERVERINFO=/usr/sbin/vserver-info
|
||||
# VSERVER=/usr/sbin/vserver
|
||||
# VROOTDIR=/var/lib/vservers
|
@ -1,6 +0,0 @@
|
||||
# /etc/cron.d/backupninja -- cron tab entry for package backupninja
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
# run backupninja every hour on the hour
|
||||
0 * * * * root if [ -x @sbindir@/backupninja ]; then @sbindir@/backupninja; fi
|
@ -1,6 +0,0 @@
|
||||
@localstatedir@/log/backupninja.log {
|
||||
rotate 6
|
||||
monthly
|
||||
compress
|
||||
missingok
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
|
||||
EXAMPLES = example.dup example.ldap example.makecd example.mysql \
|
||||
example.pgsql example.rdiff example.sh example.rsync \
|
||||
example.svn example.sys example.trac example.maildir
|
||||
|
||||
EXTRA_DIST = $(EXAMPLES)
|
||||
|
||||
dist_pkgdata_DATA = $(EXAMPLES)
|
||||
|
@ -1,147 +0,0 @@
|
||||
|
||||
# passed directly to duplicity
|
||||
#options = --verbosity 8
|
||||
|
||||
# default is 0, but set to 19 if you want to lower the priority.
|
||||
nicelevel = 19
|
||||
|
||||
# default is yes. set to no to skip the test if the remote host is alive
|
||||
#testconnect = no
|
||||
|
||||
# temporary directory used by duplicity
|
||||
# (default = /tmp or /usr/tmp, depending on the system)
|
||||
#tmpdir = /var/tmp/duplicity
|
||||
|
||||
######################################################
|
||||
## gpg section
|
||||
## (how to encrypt and optionally sign the backups)
|
||||
##
|
||||
## WARNING: old (pre-0.9.4) example.dup used to give wrong information about
|
||||
## the way the following options are used. Please read the following
|
||||
## carefully.
|
||||
##
|
||||
## If the encryptkey variable is set:
|
||||
## - data is encrypted with the GnuPG public key specified by the encryptkey
|
||||
## variable
|
||||
## - if signing is enabled, data is signed with the GnuPG private
|
||||
## key specified by the signkey variable
|
||||
## - the password variable is used to unlock the GnuPG key(s) used
|
||||
## for encryption and (optionnal) signing
|
||||
##
|
||||
## If the encryptkey option is not set:
|
||||
## - data signing is not possible
|
||||
## - the password variable is used to encrypt the data with symmetric
|
||||
## encryption: no GnuPG key pair is needed
|
||||
|
||||
[gpg]
|
||||
|
||||
# when set to yes, encryptkey variable must be set below; if you want to use
|
||||
# two different keys for encryption and signing, you must also set the signkey
|
||||
# variable below.
|
||||
# default is no, for backwards compatibility with backupninja <= 0.5.
|
||||
sign = yes
|
||||
|
||||
# ID of the GnuPG public key used for data encryption.
|
||||
# if not set, symmetric encryption is used, and data signing is not possible.
|
||||
encryptkey = 04D9EA79
|
||||
|
||||
# ID of the GnuPG private key used for data signing.
|
||||
# if not set, encryptkey will be used.
|
||||
#signkey = 04D9EA79
|
||||
|
||||
# password
|
||||
# NB: neither quote this, nor should it contain any quotes
|
||||
password = a_very_complicated_passphrase
|
||||
|
||||
######################################################
|
||||
## source section
|
||||
## (where the files to be backed up are coming from)
|
||||
|
||||
[source]
|
||||
|
||||
# A few notes about includes and excludes:
|
||||
# 1. include, exclude and vsinclude statements support globbing with '*'
|
||||
# 2. Symlinks are not dereferenced. Moreover, an include line whose path
|
||||
# contains, at any level, a symlink to a directory, will only have the
|
||||
# symlink backed-up, not the target directory's content. Yes, you have to
|
||||
# dereference yourself the symlinks, or to use 'mount --bind' instead.
|
||||
# Example: let's say /home is a symlink to /mnt/crypt/home ; the following
|
||||
# line will only backup a "/home" symlink ; neither /home/user nor
|
||||
# /home/user/Mail will be backed-up :
|
||||
# include = /home/user/Mail
|
||||
# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to
|
||||
# write :
|
||||
# include = /mnt/crypt/home/user/Mail
|
||||
# 3. All the excludes come after all the includes. The order is not otherwise
|
||||
# taken into account.
|
||||
|
||||
# files to include in the backup
|
||||
include = /var/spool/cron/crontabs
|
||||
include = /var/backups
|
||||
include = /etc
|
||||
include = /root
|
||||
include = /home
|
||||
include = /usr/local/bin
|
||||
include = /usr/local/sbin
|
||||
include = /var/lib/dpkg/status
|
||||
include = /var/lib/dpkg/status-old
|
||||
|
||||
# If vservers = yes in /etc/backupninja.conf then the following variables can
|
||||
# be used:
|
||||
# vsnames = all | <vserver1> <vserver2> ... (default = all)
|
||||
# vsinclude = <path>
|
||||
# vsinclude = <path>
|
||||
# ...
|
||||
# Any path specified in vsinclude is added to the include list for each vserver
|
||||
# listed in vsnames (or all if vsnames = all, which is the default).
|
||||
#
|
||||
# For example, vsinclude = /home will backup the /home directory in every
|
||||
# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this
|
||||
# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
|
||||
# and /vservers/baz/home.
|
||||
# Vservers paths are derived from $VROOTDIR.
|
||||
|
||||
# files to exclude from the backup
|
||||
exclude = /home/*/.gnupg
|
||||
|
||||
######################################################
|
||||
## destination section
|
||||
## (where the files are copied to)
|
||||
|
||||
[dest]
|
||||
|
||||
# perform an incremental backup? (default = yes)
|
||||
# if incremental = no, perform a full backup in order to start a new backup set
|
||||
#incremental = yes
|
||||
|
||||
# how many days of data to keep ; default is 60 days.
|
||||
# (you can also use the time format of duplicity)
|
||||
# 'keep = yes' means : do not delete old data, the remote host will take care of this
|
||||
#keep = 60
|
||||
#keep = yes
|
||||
|
||||
# full destination URL, in duplicity format; if set, desturl overrides
|
||||
# sshoptions, destdir, desthost and destuser; it also disables testconnect and
|
||||
# bandwithlimit. For details, see duplicity manpage, section "URL FORMAT".
|
||||
#desturl = file:///usr/local/backup
|
||||
#desturl = rsync://user@other.host//var/backup/bla
|
||||
|
||||
# bandwith limit, in kbit/s ; default is 0, i.e. no limit
|
||||
#bandwidthlimit = 128
|
||||
|
||||
# passed directly to ssh, scp (and sftp in duplicity >=0.4.2)
|
||||
# warning: sftp does not support all scp options, especially -i; as
|
||||
# a workaround, you can use "-o <SSHOPTION>"
|
||||
sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity
|
||||
|
||||
# put the backups under this directory
|
||||
destdir = /backups
|
||||
|
||||
# the machine which will receive the backups
|
||||
desthost = backuphost
|
||||
|
||||
# make the files owned by this user
|
||||
# note: you must be able to ssh backupuser@backhost
|
||||
# without specifying a password (if type = remote).
|
||||
destuser = backupuser
|
||||
|
@ -1,51 +0,0 @@
|
||||
##
|
||||
## configuration file for openldap backups
|
||||
##
|
||||
## If the method is set to "slapcat", the LDIFs generated are
|
||||
## suitable for use with slapadd. As the entries are in database
|
||||
## order, not superior first order, they cannot be loaded with
|
||||
## ldapadd without being reordered.
|
||||
##
|
||||
|
||||
## backupdir (default /var/backups/ldap): the destination for the backups
|
||||
# backupdir = /var/backups/ldap
|
||||
|
||||
## conf (default /etc/ldap/slapd.conf): the location of the slapd.conf file.
|
||||
# conf = /etc/ldap/slapd.conf
|
||||
|
||||
## databases (default all): either a space separated list of database
|
||||
## numbers or prefixes, or the keyword 'all'.
|
||||
# databases = all
|
||||
|
||||
## compress (default yes): if set to yes, ldif exports are gzipped.
|
||||
# compress = yes
|
||||
|
||||
## restart (default no): if set to yes, slapd is stopped before backups are
|
||||
## performed, and then started again after they have finished, this is necessary
|
||||
## if your backend is ldbm and your method is slapcat, but unnecessary otherwise.
|
||||
# restart = no
|
||||
|
||||
## method (default ldapsearch): either 'ldapsearch' or 'slapcat'
|
||||
## ldapsearch is the safer method to do backups, but is slow, slapcat
|
||||
## is much faster, but should not be done on an ldbm backend unless you have
|
||||
## restart set to yes
|
||||
## NOTE: with the ldapsearch method passwordfile and binddn need to be set
|
||||
# method = ldapsearch
|
||||
|
||||
## passwordfile (no default): this should be set to the file that contains
|
||||
## your ldap password, this is required for ldapsearch and not needed for slapcat
|
||||
## this file should have no newlines in it, echo -n "password" > passfile works.
|
||||
## NOTE: be sure to set the permissions on your password file appropriately
|
||||
## (hint: world readable is not appropriate)
|
||||
# passwordfile =
|
||||
|
||||
## binddn (no default): set this to the DN of the user that the ldapsearch binds
|
||||
## to, not needed for slapcat
|
||||
# binddn =
|
||||
|
||||
## ldaphost (no default): set this to your ldap host if it is not local
|
||||
# ldaphost =
|
||||
|
||||
## tls (default yes): if set to 'yes' then TLS connection will be
|
||||
## attempted to your ldaphost by using the URI base ldaps: otherwise ldap: will be used
|
||||
# tls = yes
|
@ -1,58 +0,0 @@
|
||||
##
|
||||
## This is an example maildir configuration file.
|
||||
##
|
||||
## The maildir handler slowly creates a backup of each user's
|
||||
## maildir to a remote server. It is designed to be run with
|
||||
## low overhead in terms of CPU and bandwidth, so it runs pretty
|
||||
## slow. Hardlinking is used to save storage space. The actual
|
||||
## maildir is stored within each snapshot directory.
|
||||
##
|
||||
## The basic algorithm is to rsync each maildir individually,
|
||||
## and to use hard links for retaining historical data.
|
||||
##
|
||||
## We handle each maildir individually because it becomes very
|
||||
## unweldy to hardlink and rsync many hundreds of thousands
|
||||
## of files at once. It is much faster to take on smaller
|
||||
## chunks at a time.
|
||||
##
|
||||
## Any maildir which is deleted from the source will be moved to
|
||||
## "deleted" directory in the destination. It is up to you to
|
||||
## periodically remove this directory or old maildirs in it.
|
||||
##
|
||||
## Note: This handler assumes that the remote shell is set to bash
|
||||
##
|
||||
## The defaults are useful in most cases, just make sure
|
||||
## to configure the source and destination information
|
||||
|
||||
when = everyday at 21:00
|
||||
|
||||
## each users maildir will contain these files:
|
||||
## daily.1, daily.2, daily.3, daily.4, daily.5, weekly.1, weekly.2,
|
||||
## weekly.3, monthly.1
|
||||
## if keepdaily is 5, keepweekly is 3, and keepmonthly is 1
|
||||
keepdaily = 5
|
||||
keepweekly = 3
|
||||
keepmonthly = 1
|
||||
|
||||
# directory which contains all the maildirs
|
||||
srcdir = /maildir/riseup.net
|
||||
|
||||
# the srcdir is expected to contain the following subdirectories. Each
|
||||
# of these will contain the user's Maildirs which start with these
|
||||
# letters
|
||||
srcsubdirs = 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z
|
||||
|
||||
# put the backups under this directory
|
||||
destdir = /crypta/maildir/riseup.net
|
||||
desthost = kakapo-pn
|
||||
|
||||
# For the backup rotation to work, destuser must be able to run
|
||||
# arbitrary bash commands on the desthost.
|
||||
destuser = backer
|
||||
|
||||
# remove any maildirs from backup which might have been deleted
|
||||
remove = yes
|
||||
|
||||
# use a ssh-mux to reuse connections, see the following article
|
||||
# http://www.debian-administration.org/articles/290 for an example
|
||||
multiconnection = notset
|
@ -1,31 +0,0 @@
|
||||
|
||||
# TYP is cd or dvd AS WELL AS the disk inside!!
|
||||
burnertype = cd
|
||||
|
||||
# system (yes) or directory/files (no)
|
||||
# this function not yet implemented
|
||||
#system = yes
|
||||
|
||||
# location for image file
|
||||
backupdir = /var/backups/makecd
|
||||
|
||||
# image filename
|
||||
imagefile = example.iso
|
||||
|
||||
# iso or burn to cd/dvd?
|
||||
isoonly = no
|
||||
|
||||
# cd/dvd burner device
|
||||
device=/dev/hdc
|
||||
|
||||
# base directory to include in the backup
|
||||
target = /
|
||||
|
||||
# files or directories to be excluded
|
||||
exclude = /proc
|
||||
exclude = /lost+found
|
||||
exclude = /tmp
|
||||
|
||||
# backupninja will perfrom this at gvien date/time
|
||||
when = wednesday at 02:00
|
||||
|
@ -1,89 +0,0 @@
|
||||
### backupninja mysql config file ###
|
||||
|
||||
databases = all
|
||||
backupdir = /var/backups/mysql
|
||||
hotcopy = no
|
||||
sqldump = yes
|
||||
compress = yes
|
||||
|
||||
### authentication ###
|
||||
|
||||
# three authentication methods:
|
||||
#
|
||||
# 1. setting the user, so that /home/user/.my.cnf is used.
|
||||
# user = some-unix-user
|
||||
#
|
||||
# 2. specifying the mysql dbuser and dbpassword,
|
||||
# which generates a temporary .my.cnf in /root/.my.cnf
|
||||
# dbusername = <some-mysql-user>
|
||||
# dbpassword = <password>
|
||||
#
|
||||
# 3. specify which config file to use with configfile
|
||||
# (this option does not work with hotcopy)
|
||||
# configfile = /etc/mysql/debian.cnf
|
||||
#
|
||||
# if user and dbusername are not specified, the default is to use
|
||||
# /etc/mysql/debian.cnf for configfile.
|
||||
|
||||
### all options ###
|
||||
|
||||
# configfile = < path/to/file > (default = /etc/mysql/debian.cnf)
|
||||
# The config file is passed to mysql with --defaults-file.
|
||||
# On debian, this default will allow backupninja to make backups
|
||||
# of mysql without configuring any additional options.
|
||||
# (this option is not compatible with "user" or "dbusername").
|
||||
#
|
||||
# user = <user> (default = root)
|
||||
# Run mysql commands as 'user'. A valid .my.cnf must exist with a
|
||||
# database username and password in the user's home directory.
|
||||
# (this option is not compatible with "configfile" or "dbusername").
|
||||
#
|
||||
# dbusername = <dbuser> (no default)
|
||||
# The user must have access to the databases specified later.
|
||||
# (this option is not compatible with "configfile" or "user").
|
||||
#
|
||||
# dbpassword = <dbpass> (no default)
|
||||
# The password used with dbusername. this password will NOT be passed
|
||||
# on the command line and is not readable using "ps aux".
|
||||
#
|
||||
# dbhost = <host> (default = localhost)
|
||||
# only localhost works right now.
|
||||
#
|
||||
# databases = < all | db1 db2 db3 > (default = all)
|
||||
# which databases to backup. should either be the word 'all' or a
|
||||
# space separated list of database names.
|
||||
#
|
||||
# nodata = < db.table1 db.table2 db.table3 > (no default)
|
||||
# only dump the structure for the database tables listed here, this means
|
||||
# no data contained in these tables will be dumped. This is very useful
|
||||
# to backup databases that have tables with large amounts of cache data that
|
||||
# isn't necessary to backup, but you still need the structure to exist
|
||||
# on a restore. You *must* specify the table as part of a database, such
|
||||
# as "drupal.cache", where the database name is "drupal" and the table that
|
||||
# you do not want to dump the data for is called "cache".
|
||||
#
|
||||
# backupdir = < path/to/destination > (default = /var/backups/mysql)
|
||||
# where to dump the backups. hotcopy backups will be in a subdirectory
|
||||
# 'hotcopy' and sqldump backups will be in a subdirectory 'sqldump'
|
||||
#
|
||||
# hotcopy = < yes | no > (default = no)
|
||||
# make a backup of the actual database binary files using mysqlhotcopy.
|
||||
#
|
||||
# sqldump = < yes | no > (default = no)
|
||||
# make a backup using mysqldump. this creates text files with sql commands
|
||||
# sufficient to recontruct the database.
|
||||
#
|
||||
# sqldumpoptions = <options>
|
||||
# (default = --lock-tables --complete-insert --add-drop-table --quick --quote-names)
|
||||
# arguments to pass to mysqldump
|
||||
#
|
||||
# compress = < yes | no > (default = yes)
|
||||
# if yes, compress the sqldump output.
|
||||
#
|
||||
# vsname = <vserver> (no default)
|
||||
# what vserver to operate on (only used if vserver = yes
|
||||
# in /etc/backupninja.conf), if you do not specify a vsname the
|
||||
# host will be operated on
|
||||
#
|
||||
# NB: databases = all doesn't seem to work with hotcopy = yes
|
||||
# when vsname is specified, I would like to know how to fix this.
|
@ -1,23 +0,0 @@
|
||||
### backupninja PostgreSQL config file ###
|
||||
|
||||
# vsname = <vserver> (no default)
|
||||
# what vserver to operate on, only used if vserver = yes in /etc/backupninja.conf
|
||||
# if you do not specify a vsname the host will be operated on
|
||||
# Note: if operating on a vserver, $VROOTDIR will be prepended to backupdir.
|
||||
|
||||
# backupdir = <dir> (default: /var/backups/postgres)
|
||||
# where to dump the backups
|
||||
|
||||
# databases = < all | db1 db2 db3 > (default = all)
|
||||
# which databases to backup. should either be the word 'all' or a
|
||||
# space separated list of database names.
|
||||
# Note: when using 'all', pg_dumpall is used instead of pg_dump, which means
|
||||
# that cluster-wide data (such as users and groups) are saved.
|
||||
|
||||
# compress = < yes | no > (default = yes)
|
||||
# if yes, compress the pg_dump/pg_dumpall output.
|
||||
|
||||
### You can also set the following variables in /etc/backupninja.conf:
|
||||
# PGSQLDUMP: pg_dump path (default: /usr/bin/pg_dump)
|
||||
# PGSQLDUMPALL: pg_dumpall path (default: /usr/bin/pg_dumpall)
|
||||
# PGSQLUSER: user running PostgreSQL (default: postgres)
|
@ -1,120 +0,0 @@
|
||||
##
|
||||
## This is an example rdiff-backup configuration file.
|
||||
## The defaults are useful in most cases, just make sure
|
||||
## to configure the destination host and user.
|
||||
##
|
||||
|
||||
## passed directly to rdiff-backup
|
||||
# options = --force
|
||||
|
||||
## default is 0, but set to 19 if you want to lower the priority.
|
||||
# nicelevel = 19
|
||||
|
||||
## default is yes. set to no to skip the test if the remote host is alive
|
||||
# testconnect = no
|
||||
|
||||
## default is not to limit bandwidth.
|
||||
## set to a number in bytes/second to limit bandwidth usage. Use a negative
|
||||
## number to set a limit that will never be exceeded, or a positive number
|
||||
## to set a target average bandwidth use. cstream is required. See cstream's
|
||||
## -t option for more information. 62500 bytes = 500 Kb (.5 Mb)
|
||||
# bwlimit = 62500
|
||||
|
||||
## should backupninja ignore the version differences between source and remote
|
||||
## rdiff-backup? (default: no)
|
||||
## This could be useful if the version differences between rdiff-backup instances
|
||||
## on remote and local side are different, and you are certain there are no
|
||||
## problems in using mis-matched versions and want to get beyond this check.
|
||||
## An example usage could be the remote side has its authorized_keys configured
|
||||
## with command="rdiff-backup --server" to allow for restricted yet automated
|
||||
## password-less backups
|
||||
# ignore_version = no
|
||||
|
||||
######################################################
|
||||
## source section
|
||||
## (where the files to be backed up are coming from)
|
||||
|
||||
[source]
|
||||
|
||||
# an optional subdirectory below 'directory' (see [dest])
|
||||
label = thishostname
|
||||
|
||||
# type can be "local" or "remote"
|
||||
type = local
|
||||
|
||||
# only use if '[source] type = remote'
|
||||
#host = srchost
|
||||
#user = srcuser
|
||||
|
||||
# how many days of data to keep
|
||||
# (you can also use the time format of rdiff-backup, e.g. 6D5h)
|
||||
# (to keep everything, set this to yes)
|
||||
#keep = yes
|
||||
keep = 60
|
||||
|
||||
# A few notes about includes and excludes:
|
||||
# 1. include, exclude and vsinclude statements support globbing with '*'
|
||||
# 2. Symlinks are not dereferenced. Moreover, an include line whose path
|
||||
# contains, at any level, a symlink to a directory, will only have the
|
||||
# symlink backed-up, not the target directory's content. Yes, you have to
|
||||
# dereference yourself the symlinks, or to use 'mount --bind' instead.
|
||||
# Example: let's say /home is a symlink to /mnt/crypt/home ; the following
|
||||
# line will only backup a "/home" symlink ; neither /home/user nor
|
||||
# /home/user/Mail will be backed-up :
|
||||
# include = /home/user/Mail
|
||||
# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to
|
||||
# write :
|
||||
# include = /mnt/crypt/home/user/Mail
|
||||
# 3. All the excludes come after all the includes. The order is not otherwise
|
||||
# taken into account.
|
||||
|
||||
# files to include in the backup
|
||||
include = /var/spool/cron/crontabs
|
||||
include = /var/backups
|
||||
include = /etc
|
||||
include = /root
|
||||
include = /home
|
||||
include = /usr/local/bin
|
||||
include = /usr/local/sbin
|
||||
include = /var/lib/dpkg/status
|
||||
include = /var/lib/dpkg/status-old
|
||||
|
||||
# If vservers = yes in /etc/backupninja.conf then the following variables can
|
||||
# be used:
|
||||
# vsnames = all | <vserver1> <vserver2> ... (default = all)
|
||||
# vsinclude = <path>
|
||||
# vsinclude = <path>
|
||||
# ...
|
||||
# Any path specified in vsinclude is added to the include list for each vserver
|
||||
# listed in vsnames (or all if vsnames = all, which is the default).
|
||||
#
|
||||
# For example, vsinclude = /home will backup the /home directory in every
|
||||
# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this
|
||||
# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
|
||||
# and /vservers/baz/home.
|
||||
# Vservers paths are derived from $VROOTDIR.
|
||||
|
||||
# files to exclude from the backup
|
||||
#exclude = /home/*/.gnupg
|
||||
|
||||
######################################################
|
||||
## destination section
|
||||
## (where the files are copied to)
|
||||
|
||||
[dest]
|
||||
|
||||
# type can be "local" or "remote"
|
||||
type = remote
|
||||
|
||||
# put the backups under this directory
|
||||
directory = /backups
|
||||
|
||||
# the machine which will receive the backups.
|
||||
# only use if "[dest] type = remote"
|
||||
host = backuphost
|
||||
|
||||
# make the files owned by this user. you must be able to
|
||||
# `su -c "ssh backupuser@backhost"` without specifying a password.
|
||||
# only use if "[dest] type = remote"
|
||||
user = backupuser
|
||||
|
@ -1,127 +0,0 @@
|
||||
#
|
||||
# rsync handler example file
|
||||
#
|
||||
# Mandatory options are uncommented with sugested values
|
||||
# Other options are commented out with their default values
|
||||
#
|
||||
# Note: You dont need to manually specify vservers using "include = /vservers".
|
||||
# They're automatically backuped if vserver is set to "yes" on you backupninja.conf.
|
||||
|
||||
[general]
|
||||
|
||||
# rsync log file
|
||||
#log = /var/log/backup/rsync.log
|
||||
|
||||
# partition device where the backup lives
|
||||
# just use this option if your data is backed up in a separate partition and
|
||||
# you want backupninja to fsck it; this option will just be used if fscheck
|
||||
# (see below) is set to 'yes'
|
||||
#partition =
|
||||
|
||||
# backup partition mountpoint or backup main folder
|
||||
# this doesn't need to be a real partition, but should be at least the
|
||||
# main folder where the backup is being stored
|
||||
mountpoint = /mnt/backup
|
||||
|
||||
# folder relative do mountpoint where the backup should be stored
|
||||
backupdir = myserver
|
||||
|
||||
# number of backup increments (min = 5)
|
||||
days = 7
|
||||
|
||||
# set to 1 if fsck should run on partition after the backup is made
|
||||
#fscheck =
|
||||
|
||||
# set to 1 if $partition is mounted read-only
|
||||
#read_only =
|
||||
|
||||
# use this if you need a lockfile to be kept during backup execution
|
||||
# this is an useful feature in case you have some tasks that should
|
||||
# know if the backup is running or not
|
||||
#lockfile =
|
||||
|
||||
# rsync command nice level
|
||||
#nicelevel = 0
|
||||
|
||||
# set to "yes" if your system isnt handling timestamps correctly
|
||||
#enable_mv_timestamp_bug = no
|
||||
|
||||
# temp folder
|
||||
#tmp = /tmp
|
||||
|
||||
[source]
|
||||
|
||||
# where the data to be backed up is (local or remote)
|
||||
#from = local
|
||||
|
||||
# if remote source, specify the hostname or IP
|
||||
#host =
|
||||
|
||||
# when "yes", test the connection for a remote source before backup
|
||||
#testconnect = no
|
||||
|
||||
# include folder on backup
|
||||
include = /etc
|
||||
include = /var
|
||||
|
||||
# exclude folder on backup
|
||||
exclude = exclude_folder1
|
||||
exclude = exclude_folder2
|
||||
|
||||
# exlude some vserver from backup
|
||||
# this is used only if vservers = yes on backupninja.conf
|
||||
exclude_vserver = excluded_vserver1
|
||||
exclude_vserver = excluded_vserver2
|
||||
|
||||
# ssh command line (remote only)
|
||||
#ssh = ssh
|
||||
|
||||
# rsync program
|
||||
# it defaults to $RSYNC value from backupninja.conf
|
||||
#rsync = $RSYNC
|
||||
|
||||
# rsync command options
|
||||
#rsync_options = "-av --delete"
|
||||
|
||||
# when set to 1, use numeric ids instead of user/group mappings on rsync
|
||||
#numericids = 0
|
||||
|
||||
# if set to 1, compress data on rsync (remote source only)
|
||||
#compress = 0
|
||||
|
||||
# set a badnwidth limit in kbps (remote source only)
|
||||
#bandwidthlimit =
|
||||
|
||||
# remote rsync program (remote source only)
|
||||
#remote_rsync = rsync
|
||||
|
||||
# This section is used to stop and start services that should be turned of
|
||||
# during the backup procedure.
|
||||
#
|
||||
#[services]
|
||||
#
|
||||
# absolute path where scripts are located
|
||||
#initscripts =
|
||||
#
|
||||
# script name to be stoped at the begining of the backup and started at its end
|
||||
#service =
|
||||
|
||||
# You can also specify some system comands if you don't want the default system values
|
||||
# by enabling the section below.
|
||||
#
|
||||
#[system]
|
||||
#
|
||||
# rm command
|
||||
#rm = rm
|
||||
#
|
||||
# cp command
|
||||
#cp = cp
|
||||
#
|
||||
# touch command
|
||||
#touch = touch
|
||||
#
|
||||
# mv command
|
||||
#mv = mv
|
||||
#
|
||||
# fsck command
|
||||
#fsck = fsck
|
@ -1,2 +0,0 @@
|
||||
|
||||
dpkg --get-selections > /var/backups/dpkg-selections.txt
|
@ -1,26 +0,0 @@
|
||||
##
|
||||
## Perform a hot backup of subversion repositories.
|
||||
##
|
||||
## REQUIRES: apt-get install subversion-tools
|
||||
##
|
||||
## This file can be empty, the defaults are usually good.
|
||||
##
|
||||
|
||||
## where subversion data lives
|
||||
# src = /var/lib/svn
|
||||
|
||||
## where to save the backups to
|
||||
# dest = /var/backups/svn
|
||||
|
||||
## where to save temporary backups
|
||||
## (if successful, $tmp is moved to $dest)
|
||||
# tmp = /var/backups/svn.tmp
|
||||
|
||||
## the hotbackup program to use.
|
||||
## svnadmin hotcopy now exists, the following script is located
|
||||
## in /usr/share/doc/subversion/examples now if you wish to use
|
||||
## it instead
|
||||
# HOTBACKUP = /usr/lib/subversion/hot-backup.py
|
||||
|
||||
## the name of the vserver containing svn, if using vservers
|
||||
# vsname =
|
@ -1,70 +0,0 @@
|
||||
#
|
||||
# this config file will save various reports of vital system information.
|
||||
# by default, all the reports are saved in /var/backups.
|
||||
#
|
||||
# requires dpkg, debconf-utils, sfdisk, and hwinfo
|
||||
#
|
||||
# (1) a capture of the debconf package selection states. This file
|
||||
# can be used to restore the answers to debconf questions for
|
||||
# packages that you will be installing through (2) below. To
|
||||
# do this, run: "debconf-set-selections < debconfsel.txt"
|
||||
#
|
||||
# (2) a list of all the packages installed and removed.
|
||||
# this file can be used to restore the state of installed packages
|
||||
# by running "dpkg --set-selections < dpkg-selections.txt and
|
||||
# then run "apt-get -u dselect-upgrade". If you have the
|
||||
# debconf-set-selections file from (1), you should restore those first.
|
||||
#
|
||||
# (3) the partition table of all disks.
|
||||
# this partition table can be used to format another disk of
|
||||
# the same size. this can be handy if using software raid and
|
||||
# you have a disk go bad. just replace the disk and partition it
|
||||
# by running "sfdisk /dev/sdb < partitions.sdb.txt"
|
||||
# (MAKE SURE YOU PARTITION THE CORRECT DISK!!!)
|
||||
#
|
||||
# (4) hardware information.
|
||||
# detailed information on most important aspects of the hardware.
|
||||
#
|
||||
# (5) the Luks header of every Luks block device, if option luksheaders
|
||||
# is enabled.
|
||||
# in case you (have to) scramble such a Luks header (for some time),
|
||||
# and restore it later by running "dd if=luksheader.sda2.bin of=/dev/sda2"
|
||||
# (MAKE SURE YOU PASS THE CORRECT DEVICE AS of= !!!)
|
||||
#
|
||||
# (6) LVM metadata for every detected volume group, if "lvm = yes"
|
||||
#
|
||||
|
||||
# here are the defaults, commented out:
|
||||
|
||||
# The output from the sys handler will be placed in $parentdir
|
||||
# parentdir = /var/backups
|
||||
# packages = yes
|
||||
# packagesfile = /var/backups/dpkg-selections.txt
|
||||
# selectionsfile = /var/backups/debconfsel.txt
|
||||
|
||||
# partitions = yes
|
||||
# NOTE: the __star__ below will be replaced by the disks found on the
|
||||
# system (e.g. partitions.sda.txt, partitions.sdb.txt). If you change
|
||||
# the partitionsfile default below, be sure to include the __star__
|
||||
# replacement in the filename, or you will get one file for only one disk,
|
||||
# the others being written to the same file, and then overwritten by the next.
|
||||
# partitionsfile = /var/backups/partitions.__star__.txt
|
||||
# dosfdisk = yes
|
||||
|
||||
# hardware = yes
|
||||
# hardwarefile = /var/backups/hardware.txt
|
||||
# dohwinfo = yes
|
||||
|
||||
# luksheaders = no
|
||||
# NOTE: the __star__ below will be replaced by the Luks partitions found on the
|
||||
# system (e.g. luksheader.sda2.bin, luksheader.sdb3.bin). If you change
|
||||
# the luksheadersfile default below, be sure to include the __star__
|
||||
# replacement in the filename, or you will get one file for only one partition,
|
||||
# the others being written to the same file, and then overwritten by the next.
|
||||
# luksheadersfile = /var/backups/luksheader.__star__.bin
|
||||
|
||||
# lvm = no
|
||||
|
||||
# If vservers = yes in /etc/backupninja.conf then the following variables can
|
||||
# be used:
|
||||
# vsnames = all | <vserver1> <vserver2> ... (default = all)
|
@ -1,16 +0,0 @@
|
||||
##
|
||||
## Perform backups of trac environment
|
||||
##
|
||||
## REQUIRES: apt-get install trac
|
||||
##
|
||||
## This file can be empty, the defaults are usually good.
|
||||
##
|
||||
|
||||
## where one or more Trac environments live
|
||||
src = /var/lib/trac
|
||||
|
||||
## where to save the backups to
|
||||
dest = /var/backups/trac
|
||||
|
||||
## where to save temporary backups
|
||||
tmp = /var/backups/trac.tmp
|
@ -1,92 +0,0 @@
|
||||
|
||||
HANDLERS = dup dup.helper ldap ldap.helper maildir makecd \
|
||||
makecd.helper mysql mysql.helper pgsql pgsql.helper rdiff \
|
||||
rdiff.helper rsync sh svn sys sys.helper trac
|
||||
|
||||
CLEANFILES = $(HANDLERS)
|
||||
|
||||
EXTRA_DIST = Makefile.am $(HANDLERS)
|
||||
|
||||
edit = sed \
|
||||
-e "s,@BASH\@,$(BASH),g" \
|
||||
-e "s,@AWK\@,$(AWK),g" \
|
||||
-e "s,@SED\@,$(SED),g"
|
||||
|
||||
dist_pkgdata_DATA = $(HANDLERS)
|
||||
|
||||
dup: $(srcdir)/dup.in
|
||||
rm -f dup
|
||||
$(edit) $(srcdir)/dup.in > dup
|
||||
|
||||
dup.helper: $(srcdir)/dup.helper.in
|
||||
rm -f dup.helper
|
||||
$(edit) $(srcdir)/dup.helper.in > dup.helper
|
||||
|
||||
ldap: $(srcdir)/ldap.in
|
||||
rm -f ldap
|
||||
$(edit) $(srcdir)/ldap.in > ldap
|
||||
|
||||
ldap.helper: $(srcdir)/ldap.helper.in
|
||||
rm -f ldap.helper
|
||||
$(edit) $(srcdir)/ldap.helper.in > ldap.helper
|
||||
|
||||
maildir: $(srcdir)/maildir.in
|
||||
rm -f maildir
|
||||
$(edit) $(srcdir)/maildir.in > maildir
|
||||
|
||||
makecd: $(srcdir)/makecd.in
|
||||
rm -f makecd
|
||||
$(edit) $(srcdir)/makecd.in > makecd
|
||||
|
||||
makecd.helper: $(srcdir)/makecd.helper.in
|
||||
rm -f makecd.helper
|
||||
$(edit) $(srcdir)/makecd.helper.in > makecd.helper
|
||||
|
||||
mysql: $(srcdir)/mysql.in
|
||||
rm -f mysql
|
||||
$(edit) $(srcdir)/mysql.in > mysql
|
||||
|
||||
mysql.helper: $(srcdir)/mysql.helper.in
|
||||
rm -f mysql.helper
|
||||
$(edit) $(srcdir)/mysql.helper.in > mysql.helper
|
||||
|
||||
pgsql: $(srcdir)/pgsql.in
|
||||
rm -f pgsql
|
||||
$(edit) $(srcdir)/pgsql.in > pgsql
|
||||
|
||||
pgsql.helper: $(srcdir)/pgsql.helper.in
|
||||
rm -f pgsql.helper
|
||||
$(edit) $(srcdir)/pgsql.helper.in > pgsql.helper
|
||||
|
||||
rdiff: $(srcdir)/rdiff.in
|
||||
rm -f rdiff
|
||||
$(edit) $(srcdir)/rdiff.in > rdiff
|
||||
|
||||
rdiff.helper: $(srcdir)/rdiff.helper.in
|
||||
rm -f rdiff.helper
|
||||
$(edit) $(srcdir)/rdiff.helper.in > rdiff.helper
|
||||
|
||||
rsync: $(srcdir)/rsync.in
|
||||
rm -f rsync
|
||||
$(edit) $(srcdir)/rsync.in > rsync
|
||||
|
||||
sh: $(srcdir)/sh.in
|
||||
rm -f sh
|
||||
$(edit) $(srcdir)/sh.in > sh
|
||||
|
||||
svn: $(srcdir)/svn.in
|
||||
rm -f svn
|
||||
$(edit) $(srcdir)/svn.in > svn
|
||||
|
||||
sys: $(srcdir)/sys.in
|
||||
rm -f sys
|
||||
$(edit) $(srcdir)/sys.in > sys
|
||||
|
||||
sys.helper: $(srcdir)/sys.helper.in
|
||||
rm -f sys.helper
|
||||
$(edit) $(srcdir)/sys.helper.in > sys.helper
|
||||
|
||||
trac: $(srcdir)/trac.in
|
||||
rm -f trac
|
||||
$(edit) $(srcdir)/trac.in > trac
|
||||
|
@ -1,514 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS dup:incremental_encrypted_remote_filesystem_backup"
|
||||
|
||||
### Functions
|
||||
|
||||
do_dup_host_includes() {
|
||||
set -o noglob
|
||||
# choose the files to backup
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$dup_title - host system: includes"
|
||||
[ -z "$dup_includes" ] && dup_includes="$dup_default_includes"
|
||||
for i in $dup_includes; do
|
||||
formItem include "$i"
|
||||
done
|
||||
formItem include ""
|
||||
formItem include ""
|
||||
formItem include ""
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
dup_includes="$REPLY"
|
||||
done
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
do_dup_vserver() {
|
||||
# choose the vservers to backup (into $selected_vservers)
|
||||
choose_one_or_more_vservers "$dup_title"
|
||||
[ $? = 0 ] || return 1
|
||||
|
||||
set -o noglob
|
||||
# choose the files to backup
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$dup_title - vservers: vsincludes (backup these directories from every selected vserver)"
|
||||
[ -z "$dup_vsincludes" ] && dup_vsincludes="$dup_default_includes"
|
||||
for i in $dup_vsincludes; do
|
||||
formItem include "$i"
|
||||
done
|
||||
formItem include ""
|
||||
formItem include ""
|
||||
formItem include ""
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
dup_vsincludes="$REPLY"
|
||||
done
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
do_dup_excludes() {
|
||||
set -o noglob
|
||||
formBegin "$dup_title: excludes"
|
||||
[ -z "$dup_excludes" ] && dup_excludes="$dup_default_excludes"
|
||||
for i in $dup_excludes; do
|
||||
formItem exclude "$i"
|
||||
done
|
||||
formItem exclude ""
|
||||
formItem exclude ""
|
||||
formItem exclude ""
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
dup_excludes="$REPLY"
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
do_dup_src() {
|
||||
choose_host_or_vservers_or_both "$dup_title"
|
||||
[ $? = 0 ] || return 1
|
||||
case $host_or_vservers in
|
||||
'host')
|
||||
do_dup_host_includes
|
||||
[ $? = 0 ] || return 1
|
||||
;;
|
||||
'vservers')
|
||||
do_dup_vserver
|
||||
[ $? = 0 ] || return 1
|
||||
;;
|
||||
'both')
|
||||
do_dup_host_includes
|
||||
[ $? = 0 ] || return 1
|
||||
do_dup_vserver
|
||||
[ $? = 0 ] || return 1
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
do_dup_excludes
|
||||
[ $? = 0 ] || return 1
|
||||
|
||||
_src_done="(DONE)"
|
||||
setDefault dest
|
||||
}
|
||||
|
||||
do_dup_dest() {
|
||||
|
||||
local replyconverted
|
||||
local thereply
|
||||
|
||||
set -o noglob
|
||||
REPLY=
|
||||
while [ -z "$REPLY" -o -z "$dup_destdir" -o -z "$dup_desthost" -o -z "$dup_destuser" ]; do
|
||||
formBegin "$dup_title - destination: first three items are compulsory"
|
||||
formItem "desthost" "$dup_desthost"
|
||||
formItem "destuser" "$dup_destuser"
|
||||
formItem "destdir" "$dup_destdir"
|
||||
formItem "keep" "$dup_keep"
|
||||
formItem "incremental" "$dup_incremental"
|
||||
formItem "bandwidthlimit" "$dup_bandwidth"
|
||||
formItem "sshoptions" "$dup_sshoptions"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
|
||||
IFS=$''
|
||||
replyconverted=`echo $REPLY | tr '\n' :`
|
||||
IFS=$':'
|
||||
thereply=($replyconverted)
|
||||
IFS=$' \t\n'
|
||||
|
||||
dup_desthost=${thereply[0]}
|
||||
dup_destuser=${thereply[1]}
|
||||
dup_destdir=${thereply[2]}
|
||||
dup_keep=${thereply[3]}
|
||||
dup_incremental=${thereply[4]}
|
||||
dup_bandwidth=${thereply[5]}
|
||||
dup_sshoptions=${thereply[6]}
|
||||
|
||||
done
|
||||
set +o noglob
|
||||
|
||||
_dest_done="(DONE)"
|
||||
setDefault gpg
|
||||
}
|
||||
|
||||
do_dup_gpg_encryptkey() {
|
||||
REPLY=
|
||||
while [ -z "$REPLY" -o -z "$dup_gpg_encryptkey" ]; do
|
||||
inputBox "$dup_title - GnuPG" "Enter ID of the public GnuPG key to be used to encrypt the backups:" "$dup_gpg_encryptkey"
|
||||
[ $? = 0 ] || return 1
|
||||
dup_gpg_encryptkey="$REPLY"
|
||||
done
|
||||
}
|
||||
|
||||
do_dup_gpg_sign() {
|
||||
# sign ?
|
||||
booleanBox "$dup_title - GnuPG" "Sign the backups?" "$dup_gpg_sign"
|
||||
if [ $? = 0 ]; then
|
||||
dup_gpg_sign=yes
|
||||
else
|
||||
dup_gpg_sign=no
|
||||
fi
|
||||
}
|
||||
|
||||
do_dup_gpg_signkey() {
|
||||
# one key pair ?
|
||||
booleanBox "$dup_title - GnuPG" "Use the same GnuPG key pair for encryption and signing?" "$dup_gpg_onekeypair"
|
||||
if [ $? = 0 ]; then
|
||||
dup_gpg_onekeypair=yes
|
||||
else
|
||||
dup_gpg_onekeypair=no
|
||||
fi
|
||||
|
||||
if [ "$dup_gpg_onekeypair" == "no" }; then
|
||||
# signkey ?
|
||||
REPLY=
|
||||
while [ -z "$REPLY" -o -z "$dup_gpg_signkey" ]; do
|
||||
inputBox "$dup_title - GnuPG" "Enter the ID of the private GnuPG key to be used to sign the backups:" "$dup_gpg_signkey"
|
||||
[ $? = 0 ] || return 1
|
||||
dup_gpg_signkey="$REPLY"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
do_dup_gpg_passphrase() {
|
||||
local question="Enter the passphrase needed to unlock the GnuPG key:"
|
||||
REPLY=
|
||||
while [ -z "$REPLY" -o -z "$dup_gpg_password" ]; do
|
||||
passwordBox "$dup_title - GnuPG" "$question"
|
||||
[ $? = 0 ] || return 1
|
||||
dup_gpg_password="$REPLY"
|
||||
done
|
||||
}
|
||||
|
||||
do_dup_gpg() {
|
||||
|
||||
# symmetric or public key encryption ?
|
||||
booleanBox "$dup_title - GnuPG" "Use public key encryption? Otherwise, symmetric encryption will be used, and data signing will be impossible." "$dup_gpg_asymmetric_encryption"
|
||||
if [ $? = 0 ]; then
|
||||
dup_gpg_asymmetric_encryption=yes
|
||||
else
|
||||
dup_gpg_asymmetric_encryption=no
|
||||
fi
|
||||
|
||||
# when using public/private key pair encryption, ask for the keys to use
|
||||
if [ "$dup_gpg_asymmetric_encryption" == yes ]; then
|
||||
do_dup_gpg_encryptkey ; [ $? = 0 ] || return 1
|
||||
do_dup_gpg_sign ; [ $? = 0 ] || return 1
|
||||
if [ "$dup_gpg_sign" == yes ]; then
|
||||
do_dup_gpg_signkey ; [ $? = 0 ] || return 1
|
||||
fi
|
||||
else
|
||||
dup_gpg_sign=no
|
||||
fi
|
||||
|
||||
# a passphrase is alway needed
|
||||
do_dup_gpg_passphrase
|
||||
|
||||
_gpg_done="(DONE)"
|
||||
setDefault adv
|
||||
# TODO: replace the above line by the following when do_dup_conn is written
|
||||
# setDefault conn
|
||||
}
|
||||
|
||||
# TODO: share rdiff.helper code in some lib, and use it here
|
||||
do_dup_conn() {
|
||||
_con_done="(DONE)"
|
||||
setDefault adv
|
||||
}
|
||||
|
||||
do_dup_misc_options() {
|
||||
|
||||
set -o noglob
|
||||
local replyconverted
|
||||
local thereply
|
||||
|
||||
formBegin "$dup_title - misc. options"
|
||||
formItem "nicelevel" "$dup_nicelevel"
|
||||
formItem "testconnect" "$dup_testconnect"
|
||||
formItem "options" "$dup_options"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
|
||||
IFS=$''
|
||||
replyconverted=`echo $REPLY | tr '\n' :`
|
||||
IFS=$':'
|
||||
thereply=($replyconverted)
|
||||
IFS=$' \t\n'
|
||||
|
||||
dup_nicelevel=${thereply[0]}
|
||||
dup_testconnect=${thereply[1]}
|
||||
dup_options=${thereply[2]}
|
||||
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
# (rdiff.helper compatible interface... there could be some sode to share, hmmm.)
|
||||
do_dup_adv() {
|
||||
do_dup_misc_options
|
||||
[ $? = 0 ] || return 1
|
||||
_adv_done="(DONE)"
|
||||
setDefault finish
|
||||
}
|
||||
|
||||
do_dup_finish() {
|
||||
get_next_filename $configdirectory/90.dup
|
||||
cat > $next_filename <<EOF
|
||||
# passed directly to duplicity
|
||||
#options = --verbosity 8
|
||||
options = $dup_options
|
||||
|
||||
# default is 0, but set to 19 if you want to lower the priority.
|
||||
nicelevel = $dup_nicelevel
|
||||
|
||||
# default is yes. set to no to skip the test if the remote host is alive
|
||||
testconnect = $dup_testconnect
|
||||
|
||||
######################################################
|
||||
## gpg section
|
||||
## (how to encrypt and optionally sign the backups)
|
||||
##
|
||||
## WARNING: old (pre-0.9.4) example.dup used to give wrong information about
|
||||
## the way the following options are used. Please read the following
|
||||
## carefully.
|
||||
##
|
||||
## If the encryptkey variable is set:
|
||||
## - data is encrypted with the GnuPG public key specified by the encryptkey
|
||||
## variable
|
||||
## - if signing is enabled, data is signed with the GnuPG private
|
||||
## key specified by the signkey variable
|
||||
## - the password variable is used to unlock the GnuPG key(s) used
|
||||
## for encryption and (optionnal) signing
|
||||
##
|
||||
## If the encryptkey option is not set:
|
||||
## - data signing is not possible
|
||||
## - the password variable is used to encrypt the data with symmetric
|
||||
## encryption: no GnuPG key pair is needed
|
||||
|
||||
[gpg]
|
||||
|
||||
# when set to yes, encryptkey variable must be set below; if you want to use
|
||||
# two different keys for encryption and signing, you must also set the signkey
|
||||
# variable below.
|
||||
# default is no, for backwards compatibility with backupninja <= 0.5.
|
||||
sign = $dup_gpg_sign
|
||||
|
||||
# ID of the GnuPG public key used for data encryption.
|
||||
# if not set, symmetric encryption is used, and data signing is not possible.
|
||||
encryptkey = $dup_gpg_encryptkey
|
||||
|
||||
# ID of the GnuPG private key used for data signing.
|
||||
# if not set, encryptkey will be used.
|
||||
signkey = $dup_gpg_signkey
|
||||
|
||||
# password
|
||||
# NB: neither quote this, nor should it include any quotes
|
||||
password = $dup_gpg_password
|
||||
|
||||
######################################################
|
||||
## source section
|
||||
## (where the files to be backed up are coming from)
|
||||
|
||||
[source]
|
||||
|
||||
# A few notes about includes and excludes:
|
||||
# 1. include, exclude and vsinclude statements support globbing with '*'
|
||||
# 2. Symlinks are not dereferenced. Moreover, an include line whose path
|
||||
# contains, at any level, a symlink to a directory, will only have the
|
||||
# symlink backed-up, not the target directory's content. Yes, you have to
|
||||
# dereference yourself the symlinks, or to use 'mount --bind' instead.
|
||||
# Example: let's say /home is a symlink to /mnt/crypt/home ; the following
|
||||
# line will only backup a "/home" symlink ; neither /home/user nor
|
||||
# /home/user/Mail will be backed-up :
|
||||
# include = /home/user/Mail
|
||||
# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to
|
||||
# write :
|
||||
# include = /mnt/crypt/home/user/Mail
|
||||
# 3. All the excludes come after all the includes. The order is not otherwise
|
||||
# taken into account.
|
||||
|
||||
# files to include in the backup
|
||||
EOF
|
||||
|
||||
if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
|
||||
set -o noglob
|
||||
for i in $dup_includes; do
|
||||
echo "include = $i" >> $next_filename
|
||||
done
|
||||
set +o noglob
|
||||
fi
|
||||
|
||||
cat >> $next_filename <<EOF
|
||||
|
||||
# If vservers = yes in /etc/backupninja.conf then the following variables can
|
||||
# be used:
|
||||
# vsnames = all | <vserver1> <vserver2> ... (default = all)
|
||||
# vsinclude = <path>
|
||||
# vsinclude = <path>
|
||||
# ...
|
||||
# Any path specified in vsinclude is added to the include list for each vserver
|
||||
# listed in vsnames (or all if vsnames = all, which is the default).
|
||||
#
|
||||
# For example, vsinclude = /home will backup the /home directory in every
|
||||
# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this
|
||||
# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
|
||||
# and /vservers/baz/home.
|
||||
# Vservers paths are derived from $VROOTDIR.
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then
|
||||
set -o noglob
|
||||
echo -e "vsnames = $selected_vservers\n" >> $next_filename
|
||||
for i in $dup_vsincludes; do
|
||||
echo "vsinclude = $i" >> $next_filename
|
||||
done
|
||||
set +o noglob
|
||||
fi
|
||||
|
||||
# excludes
|
||||
cat >> $next_filename <<EOF
|
||||
|
||||
# files to exclude from the backup
|
||||
EOF
|
||||
set -o noglob
|
||||
for i in $dup_excludes; do
|
||||
echo "exclude = $i" >> $next_filename
|
||||
done
|
||||
set +o noglob
|
||||
|
||||
cat >> $next_filename <<EOF
|
||||
|
||||
######################################################
|
||||
## destination section
|
||||
## (where the files are copied to)
|
||||
|
||||
[dest]
|
||||
|
||||
# perform an incremental backup? (default = yes)
|
||||
# if incremental = no, perform a full backup in order to start a new backup set
|
||||
incremental = $dup_incremental
|
||||
|
||||
# how many days of data to keep ; default is 60 days.
|
||||
# (you can also use the time format of duplicity)
|
||||
# 'keep = yes' means : do not delete old data, the remote host will take care of this
|
||||
#keep = 60
|
||||
#keep = yes
|
||||
keep = $dup_keep
|
||||
|
||||
# full destination URL, in duplicity format; if set, desturl overrides
|
||||
# sshoptions, destdir, desthost and destuser; it also disables testconnect and
|
||||
# bandwithlimit. For details, see duplicity manpage, section "URL FORMAT".
|
||||
#desturl = file:///usr/local/backup
|
||||
#desturl = rsync://user@other.host//var/backup/bla
|
||||
|
||||
# bandwith limit, in kbit/s ; default is 0, i.e. no limit
|
||||
#bandwidthlimit = 128
|
||||
bandwidthlimit = $dup_bandwidth
|
||||
|
||||
# passed directly to ssh, scp (and sftp in duplicity >=0.4.2)
|
||||
# warning: sftp does not support all scp options, especially -i; as
|
||||
# a workaround, you can use "-o <SSHOPTION>"
|
||||
#sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity
|
||||
sshoptions = $dup_sshoptions
|
||||
|
||||
# put the backups under this directory
|
||||
destdir = $dup_destdir
|
||||
|
||||
# the machine which will receive the backups
|
||||
desthost = $dup_desthost
|
||||
|
||||
# make the files owned by this user
|
||||
# note: you must be able to ssh backupuser@backhost
|
||||
# without specifying a password (if type = remote).
|
||||
destuser = $dup_destuser
|
||||
|
||||
EOF
|
||||
|
||||
chmod 600 $next_filename
|
||||
|
||||
}
|
||||
|
||||
dup_main_menu() {
|
||||
|
||||
while true; do
|
||||
srcitem="choose files to include & exclude $_src_done"
|
||||
destitem="configure backup destination $_dest_done"
|
||||
gpgitem="configure GnuPG encryption/signing $_gpg_done"
|
||||
conitem="set up ssh keys and test remote connection $_con_done"
|
||||
advitem="edit advanced settings $_adv_done"
|
||||
# TODO: add the following to the menu when do_dup_conn is written
|
||||
# conn "$conitem" \
|
||||
menuBox "$dup_title" "choose a step:" \
|
||||
src "$srcitem" \
|
||||
dest "$destitem" \
|
||||
gpg "$gpgitem" \
|
||||
adv "$advitem" \
|
||||
finish "finish and create config file"
|
||||
[ $? = 0 ] || return 1
|
||||
result="$REPLY"
|
||||
|
||||
case "$result" in
|
||||
"src") do_dup_src;;
|
||||
"dest") do_dup_dest;;
|
||||
"gpg") do_dup_gpg;;
|
||||
# TODO: enable the following when do_dup_conn is written
|
||||
# "conn") do_dup_conn;;
|
||||
"adv") do_dup_adv;;
|
||||
"finish")
|
||||
if [[ "$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then
|
||||
# TODO: replace the previous test by the following when do_dup_conn is written
|
||||
# if [[ "$_con_done$_dest_done$_gpg_done$_src_done" != "(DONE)(DONE)(DONE)(DONE)" ]]; then
|
||||
msgBox "$dup_title" "You cannot create the configuration file until the four first steps are completed."
|
||||
else
|
||||
do_dup_finish
|
||||
break
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
### Main function
|
||||
|
||||
dup_wizard() {
|
||||
|
||||
require_packages duplicity
|
||||
|
||||
# Global variables
|
||||
dup_title="Duplicity action wizard"
|
||||
_src_done=
|
||||
_dest_done=
|
||||
_con_done=
|
||||
_gpg_done=
|
||||
_adv_done=
|
||||
dup_includes=
|
||||
dup_excludes=
|
||||
dup_vsincludes=
|
||||
dup_incremental=yes
|
||||
dup_keep=60
|
||||
dup_bandwidth=
|
||||
dup_sshoptions=
|
||||
dup_destdir="/backups/`hostname`"
|
||||
dup_desthost=
|
||||
dup_destuser=
|
||||
dup_gpg_asymmetric_encryption="yes"
|
||||
dup_gpg_encryptkey=""
|
||||
dup_gpg_sign="yes"
|
||||
dup_gpg_onekeypair="yes"
|
||||
dup_gpg_signkey=""
|
||||
dup_gpg_password=""
|
||||
dup_nicelevel=19
|
||||
dup_testconnect=yes
|
||||
dup_options=
|
||||
|
||||
# Global variables whose '*' shall not be expanded
|
||||
set -o noglob
|
||||
dup_default_includes="/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*"
|
||||
dup_default_excludes="/home/*/.gnupg /home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads"
|
||||
set +o noglob
|
||||
|
||||
dup_main_menu
|
||||
}
|
279
handlers/dup.in
279
handlers/dup.in
@ -1,279 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# duplicity script for backupninja
|
||||
# requires duplicity
|
||||
#
|
||||
|
||||
getconf options
|
||||
getconf testconnect yes
|
||||
getconf nicelevel 0
|
||||
getconf tmpdir
|
||||
|
||||
setsection gpg
|
||||
getconf password
|
||||
getconf sign no
|
||||
getconf encryptkey
|
||||
getconf signkey
|
||||
|
||||
setsection source
|
||||
getconf include
|
||||
getconf vsnames all
|
||||
getconf vsinclude
|
||||
getconf exclude
|
||||
|
||||
setsection dest
|
||||
getconf incremental yes
|
||||
getconf keep 60
|
||||
getconf desturl
|
||||
getconf sshoptions
|
||||
getconf bandwidthlimit 0
|
||||
getconf desthost
|
||||
getconf destdir
|
||||
getconf destuser
|
||||
destdir=${destdir%/}
|
||||
|
||||
### SANITY CHECKS ##############################################################
|
||||
|
||||
[ -n "$desturl" -o -n "$destdir" ] || fatal "The destination directory (destdir) must be set when desturl is not used."
|
||||
[ -n "$include" -o -n "$vsinclude" ] || fatal "No source includes specified"
|
||||
[ -n "$password" ] || fatal "The password option must be set."
|
||||
|
||||
### VServers
|
||||
# If vservers are configured, check that the ones listed in $vsnames do exist.
|
||||
local usevserver=no
|
||||
if [ $vservers_are_available = yes ]; then
|
||||
if [ "$vsnames" = all ]; then
|
||||
vsnames="$found_vservers"
|
||||
else
|
||||
if ! vservers_exist "$vsnames" ; then
|
||||
fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist."
|
||||
fi
|
||||
fi
|
||||
if [ -n "$vsinclude" ]; then
|
||||
info "Using vservers '$vsnames'"
|
||||
usevserver=yes
|
||||
fi
|
||||
else
|
||||
[ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored'
|
||||
fi
|
||||
|
||||
### See if we can login on $desthost
|
||||
if [ "$testconnect" == "yes" ]; then
|
||||
if [ -n "$desturl" ]; then
|
||||
warning 'testconnect can not be used when desturl is set'
|
||||
else
|
||||
debug "ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'"
|
||||
if [ ! $test ]; then
|
||||
result=`ssh $sshoptions -o PasswordAuthentication=no $desthost -l $destuser 'echo -n 1'`
|
||||
if [ "$result" != "1" ]; then
|
||||
fatal "Can't connect to $desthost as $destuser."
|
||||
else
|
||||
debug "Connected to $desthost as $destuser successfully"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
### COMMAND-LINE MANGLING ######################################################
|
||||
|
||||
### initialize $execstr*
|
||||
execstr_command=
|
||||
execstr_options="$options --no-print-statistics"
|
||||
execstr_source=
|
||||
if [ -n "$desturl" ]; then
|
||||
[ -z "$destuser" ] || warning 'the configured destuser is ignored since desturl is set'
|
||||
[ -z "$desthost" ] || warning 'the configured desthost is ignored since desturl is set'
|
||||
[ -z "$destdir" ] || warning 'the configured destdir is ignored since desturl is set'
|
||||
execstr_serverpart="$desturl"
|
||||
else
|
||||
execstr_serverpart="scp://$destuser@$desthost/$destdir"
|
||||
fi
|
||||
|
||||
### duplicity version
|
||||
duplicity_version="`duplicity --version | @AWK@ '{print $2}'`"
|
||||
duplicity_major="`echo $duplicity_version | @AWK@ -F '.' '{print $1}'`"
|
||||
duplicity_minor="`echo $duplicity_version | @AWK@ -F '.' '{print $2}'`"
|
||||
duplicity_sub="`echo $duplicity_version | @AWK@ -F '.' '{print $3}'`"
|
||||
|
||||
### ssh/scp/sftp options
|
||||
# 1. duplicity >= 0.4.2 needs --sftp-command
|
||||
# (NB: sftp does not support the -l option)
|
||||
# 2. duplicity 0.4.3 to 0.4.9 replace --ssh-command with --ssh-options, which is
|
||||
# passed to scp and sftp commands by duplicity. We don't use it: since this
|
||||
# version does not use the ssh command anymore, we keep compatibility with
|
||||
# our previous config files by passing $sshoptions to --scp-command and
|
||||
# --sftp-command ourselves
|
||||
|
||||
scpoptions="$sshoptions"
|
||||
if [ "$bandwidthlimit" =! 0 ]; then
|
||||
[ -z "$testurl" ] || warning 'The bandwidthlimit option is not used when desturl is set.'
|
||||
scpoptions="$scpoptions -l $bandwidthlimit"
|
||||
fi
|
||||
|
||||
# < 0.4.2 : only uses ssh and scp
|
||||
if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -lt 2 ]; then
|
||||
execstr_options="${execstr_options} --scp-command 'scp $scpoptions' --ssh-command 'ssh $sshoptions'"
|
||||
# >= 0.4.2 : also uses sftp, --sftp-command option is now supported
|
||||
else
|
||||
sftpoptions="$sshoptions"
|
||||
# == 0.4.2 : uses ssh, scp and sftp
|
||||
if [ "$duplicity_major" -eq 0 -a "$duplicity_minor" -eq 4 -a "$duplicity_sub" -eq 2 ]; then
|
||||
execstr_options="${execstr_options} --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions' --ssh-command 'ssh $sshoptions'"
|
||||
# >= 0.4.3 : uses only scp and sftp, --ssh-command option is not supported anymore
|
||||
else
|
||||
execstr_options="${execstr_options} --scp-command 'scp $scpoptions' --sftp-command 'sftp $sftpoptions'"
|
||||
fi
|
||||
fi
|
||||
|
||||
### Symmetric or asymmetric (public/private key pair) encryption
|
||||
if [ -n "$encryptkey" ]; then
|
||||
execstr_options="${execstr_options} --encrypt-key $encryptkey"
|
||||
debug "Data will be encrypted with the GnuPG key $encryptkey."
|
||||
else
|
||||
debug "Data will be encrypted using symmetric encryption."
|
||||
fi
|
||||
|
||||
### Data signing (or not)
|
||||
if [ "$sign" == yes ]; then
|
||||
# duplicity is not able to sign data when using symmetric encryption
|
||||
[ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing."
|
||||
# if needed, initialize signkey to a value that is not empty (checked above)
|
||||
[ -n "$signkey" ] || signkey="$encryptkey"
|
||||
execstr_options="${execstr_options} --sign-key $signkey"
|
||||
debug "Data will be signed will the GnuPG key $signkey."
|
||||
else
|
||||
debug "Data won't be signed."
|
||||
fi
|
||||
|
||||
### Incremental or full backup mode
|
||||
# If incremental==yes, use the default duplicity behaviour: perform an
|
||||
# incremental backup if old signatures can be found, else switch to
|
||||
# full backup.
|
||||
# If incremental==no, force a full backup anyway.
|
||||
if [ "$incremental" == "no" ]; then
|
||||
# before 0.4.4, full was an option and not a command
|
||||
if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -lt 4 ]; then
|
||||
execstr_options="${execstr_options} --full"
|
||||
else
|
||||
execstr_command="full"
|
||||
fi
|
||||
fi
|
||||
|
||||
### Temporary directory
|
||||
precmd=
|
||||
if [ -n "$tmpdir" ]; then
|
||||
if [ ! -d "$tmpdir" ]; then
|
||||
info "Temporary directory ($tmpdir) does not exist, creating it."
|
||||
mkdir -p "$tmpdir"
|
||||
[ $? -eq 0 ] || fatal "Could not create temporary directory ($tmpdir)."
|
||||
chmod 0700 "$tmpdir"
|
||||
fi
|
||||
info "Using $tmpdir as TMPDIR"
|
||||
precmd="${precmd}TMPDIR=$tmpdir "
|
||||
fi
|
||||
|
||||
### Cleanup old backup sets (or not)
|
||||
if [ "$keep" != "yes" ]; then
|
||||
if [ "`echo $keep | tr -d 0-9`" == "" ]; then
|
||||
keep="${keep}D"
|
||||
fi
|
||||
# before 0.4.4, remove-older-than was an option and not a command
|
||||
if [ "$duplicity_major" -le 0 -a "$duplicity_minor" -le 4 -a "$duplicity_sub" -lt 4 ]; then
|
||||
execstr_options="${execstr_options} --remove-older-than $keep"
|
||||
fi
|
||||
fi
|
||||
|
||||
### Source
|
||||
|
||||
set -o noglob
|
||||
|
||||
# excludes
|
||||
for i in $exclude; do
|
||||
str="${i//__star__/*}"
|
||||
execstr_source="${execstr_source} --exclude '$str'"
|
||||
done
|
||||
|
||||
# includes
|
||||
for i in $include; do
|
||||
[ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
|
||||
str="${i//__star__/*}"
|
||||
execstr_source="${execstr_source} --include '$str'"
|
||||
done
|
||||
|
||||
# vsincludes
|
||||
if [ $usevserver = yes ]; then
|
||||
for vserver in $vsnames; do
|
||||
for vi in $vsinclude; do
|
||||
str="${vi//__star__/*}"
|
||||
str="$VROOTDIR/$vserver$str"
|
||||
execstr_source="${execstr_source} --include '$str'"
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
set +o noglob
|
||||
|
||||
### EXECUTE ####################################################################
|
||||
|
||||
execstr_source=${execstr_source//\\*/\\\\\\*}
|
||||
|
||||
### Cleanup commands (duplicity >= 0.4.4)
|
||||
|
||||
# cleanup
|
||||
if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 4 ]; then
|
||||
debug "$precmd duplicity cleanup --force $execstr_options $execstr_serverpart"
|
||||
if [ ! $test ]; then
|
||||
export PASSPHRASE=$password
|
||||
output=`nice -n $nicelevel \
|
||||
su -c \
|
||||
"$precmd duplicity cleanup --force $execstr_options $execstr_serverpart 2>&1"`
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
debug $output
|
||||
info "Duplicity cleanup finished successfully."
|
||||
else
|
||||
debug $output
|
||||
warning "Duplicity cleanup failed."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# remove-older-than
|
||||
if [ "$keep" != "yes" ]; then
|
||||
if [ "$duplicity_major" -ge 0 -a "$duplicity_minor" -ge 4 -a "$duplicity_sub" -ge 4 ]; then
|
||||
debug "$precmd duplicity remove-older-than $keep --force $execstr_options $execstr_serverpart"
|
||||
if [ ! $test ]; then
|
||||
export PASSPHRASE=$password
|
||||
output=`nice -n $nicelevel \
|
||||
su -c \
|
||||
"$precmd duplicity remove-older-than $keep --force $execstr_options $execstr_serverpart 2>&1"`
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
debug $output
|
||||
info "Duplicity remove-older-than finished successfully."
|
||||
else
|
||||
debug $output
|
||||
warning "Duplicity remove-older-than failed."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
### Backup command
|
||||
debug "$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart"
|
||||
if [ ! $test ]; then
|
||||
export PASSPHRASE=$password
|
||||
output=`nice -n $nicelevel \
|
||||
su -c \
|
||||
"$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart 2>&1"`
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
debug $output
|
||||
info "Duplicity finished successfully."
|
||||
else
|
||||
debug $output
|
||||
fatal "Duplicity failed."
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
@ -1,90 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS ldap:ldap_database_backup"
|
||||
|
||||
ldap_create_file() {
|
||||
while true; do
|
||||
checkBox "ldap action wizard" "check options (slapcat OR ldapsearch)" \
|
||||
"slapcat" "export ldif using slapcat" yes \
|
||||
"ldapsearch" "export ldif using ldapsearch" no \
|
||||
"compress" "compress the ldif output files" yes \
|
||||
"ssl" "use SSL (deprecated)" no \
|
||||
"tls" "use TLS extended operations (RFC2246, RFC2830)" yes
|
||||
status=$?
|
||||
compress="compress = no"
|
||||
method="method = <unset>"
|
||||
restart="restart = no"
|
||||
binddn=""
|
||||
passwordfile=""
|
||||
ssl="ssl = no"
|
||||
tls="tls = no"
|
||||
[ $status = 1 ] && return;
|
||||
result="$REPLY"
|
||||
for opt in $result; do
|
||||
case $opt in
|
||||
'"compress"') compress="compress = yes";;
|
||||
'"slapcat"')
|
||||
method="method = slapcat"
|
||||
[ "$_RESTART" == "yes" ] && restart="restart = yes"
|
||||
;;
|
||||
'"ldapsearch"')
|
||||
method="method = ldapsearch"
|
||||
inputBox "ldap action wizard" "ldapsearch requires authentication. Specify here what password file to use. It must have the password with no trailing return and it should not be world readable."
|
||||
[ $? = 1 ] && return
|
||||
passwordfile="passwordfile = $REPLY"
|
||||
inputBox "ldap action wizard" "ldapsearch requires authentication. Specify here what DN to bind as:"
|
||||
[ $? = 1 ] && return
|
||||
binddn="binddn = $REPLY"
|
||||
require_packages ldap-utils
|
||||
;;
|
||||
'"ssl"') ssl="ssl = yes";;
|
||||
'"tls"') tls="tls = yes";;
|
||||
esac
|
||||
done
|
||||
get_next_filename $configdirectory/30.ldap
|
||||
cat > $next_filename <<EOF
|
||||
$method
|
||||
$compress
|
||||
$restart
|
||||
$binddn
|
||||
$passwordfile
|
||||
$ssl
|
||||
$tls
|
||||
# backupdir = /var/backups/ldap
|
||||
# conf = /etc/ldap/slapd.conf
|
||||
# databases = all
|
||||
EOF
|
||||
chmod 600 $next_filename
|
||||
return
|
||||
done
|
||||
}
|
||||
|
||||
ldap_wizard() {
|
||||
bdb=no
|
||||
hdb=no
|
||||
ldbm=no
|
||||
for backend in `grep -e "^backend" /etc/ldap/slapd.conf | @AWK@ '{print $2}'`; do
|
||||
if [ "$backend" == "bdb" ]; then
|
||||
bdb=yes
|
||||
elif [ "$backend" == "hdb" ]; then
|
||||
hdb=yes
|
||||
elif [ "$backend" == "ldbm" ]; then
|
||||
ldbm=yes
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$bdb" == "yes" -o "$hdb" == "yes" ]; then
|
||||
if [ "$ldbm" == "no" ]; then
|
||||
msgBox "ldap action wizard" "It looks like the backend in your slapd.conf is set to BDB or HDB. If this is not the case, exit this wizard! From this point on, we will assume BDB or HDB backend, which might have disasterious consequences if this is incorrect."
|
||||
_RESTART=no
|
||||
ldap_create_file
|
||||
fi
|
||||
elif [ "$ldbm" == "yes" ]; then
|
||||
msgBox "ldap action wizard" "It looks like the backend in your slapd.conf is set to LDBM. Because of this, you will have less options (because it is not safe to use slapcat while slapd is running LDBM)."
|
||||
_RESTART=yes
|
||||
ldap_create_file
|
||||
else
|
||||
msgBox "ldap action wizard" "I couldn't find any supported backend in your slapd.conf. Bailing out."
|
||||
return
|
||||
fi
|
||||
}
|
111
handlers/ldap.in
111
handlers/ldap.in
@ -1,111 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# openldap backup handler script for backupninja
|
||||
#
|
||||
|
||||
getconf backupdir /var/backups/ldap
|
||||
getconf conf /etc/ldap/slapd.conf
|
||||
getconf databases all
|
||||
getconf compress yes
|
||||
getconf ldif yes
|
||||
getconf restart no
|
||||
getconf method ldapsearch
|
||||
getconf passwordfile
|
||||
getconf binddn
|
||||
getconf ldaphost
|
||||
getconf ssl yes
|
||||
getconf tls no
|
||||
|
||||
if [ $ssl = 'yes' ]; then
|
||||
URLBASE="ldaps"
|
||||
else
|
||||
URLBASE="ldap"
|
||||
fi
|
||||
|
||||
status="ok"
|
||||
|
||||
[ -f $conf ] || fatal "slapd config file ($conf) not found"
|
||||
[ -d $backupdir ] || mkdir -p $backupdir
|
||||
[ -d $backupdir ] || fatal "Backup directory '$backupdir'"
|
||||
|
||||
dbsuffixes=(`@AWK@ 'BEGIN {OFS=":"} /[:space:]*^database[:space:]*\w*/ {db=$2}; /^[:space:]*suffix[:space:]*\w*/ {if (db=="bdb"||db=="hdb"||db="ldbm") print db,$2}' $conf|@SED@ -e 's/[" ]//g'`)
|
||||
|
||||
## LDIF DUMP
|
||||
|
||||
if [ "$ldif" == "yes" ]; then
|
||||
dumpdir="$backupdir"
|
||||
[ -d $dumpdir ] || mkdir -p $dumpdir
|
||||
|
||||
if [ "$databases" == 'all' ]; then
|
||||
dbcount=`grep '^database' $conf | wc -l`
|
||||
let "dbcount = dbcount - 1"
|
||||
databases=`seq 0 $dbcount`;
|
||||
fi
|
||||
|
||||
for db in $databases; do
|
||||
if [ `expr index "$db" "="` == "0" ]; then
|
||||
# db is a number, get the suffix.
|
||||
dbsuffix=${dbsuffixes[$db]/*:/}
|
||||
else
|
||||
dbsuffix=$db
|
||||
fi
|
||||
# some databases don't have suffix (like monitor), skip these
|
||||
if [ "$dbsuffix" == "" ]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
if [ "$method" == "slapcat" ]; then
|
||||
execstr="$SLAPCAT -f $conf -b $dbsuffix"
|
||||
else
|
||||
LDAPARGS=""
|
||||
if [ "$tls" == "yes" ]; then
|
||||
LDAPARGS="-ZZ"
|
||||
fi
|
||||
if [ -n "$ldaphost" ]; then
|
||||
execstr="$LDAPSEARCH $LDAPARGS -H $URLBASE://$ldaphost -x -L -b ""$dbsuffix"" -D ""$binddn"" -y $passwordfile"
|
||||
else
|
||||
execstr="$LDAPSEARCH -H $URLBASE://$ldaphost -x -L -b ""$dbsuffix"" -D ""$binddn"" -y $passwordfile"
|
||||
fi
|
||||
[ -f "$passwordfile" ] || fatal "Password file $passwordfile not found. When method is set to ldapsearch, you must also specify a password file."
|
||||
debug "$execstr"
|
||||
fi
|
||||
if [ ! $test ]; then
|
||||
if [ "$restart" == "yes" ]; then
|
||||
debug "Shutting down ldap server..."
|
||||
/etc/init.d/slapd stop
|
||||
fi
|
||||
|
||||
ext=
|
||||
if [ "$compress" == "yes" ]; then
|
||||
ext=".gz"
|
||||
fi
|
||||
touch $dumpdir/$dbsuffix.ldif$ext
|
||||
if [ ! -f $dumpdir/$dbsuffix.ldif$ext ]; then
|
||||
fatal "Couldn't create ldif dump file: $dumpdir/$dbsuffix.ldif$ext"
|
||||
fi
|
||||
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="$execstr | $GZIP > $dumpdir/$dbsuffix.ldif.gz"
|
||||
else
|
||||
execstr="$execstr > $dumpdir/$dbsuffix.ldif"
|
||||
fi
|
||||
debug "$execstr"
|
||||
output=`su root -c "$execstr" 2>&1`
|
||||
code=$?
|
||||
if [ "$code" == "0" ]; then
|
||||
debug $output
|
||||
info "Successfully finished ldif export of $dbsuffix"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed ldif export of $dbsuffix"
|
||||
fi
|
||||
|
||||
if [ "$restart" == "yes" ]; then
|
||||
debug "Starting ldap server..."
|
||||
/etc/init.d/slapd start
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
return 0
|
@ -1,370 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
###############################################################
|
||||
#
|
||||
# This handler slowly creates a backup of each user's maildir
|
||||
# to a remote server. It is designed to be run with low overhead
|
||||
# in terms of cpu and bandwidth so it runs pretty slow.
|
||||
# Hardlinking is used to save storage space.
|
||||
#
|
||||
# This handler expects that your maildir directory structure is
|
||||
# either one of the following:
|
||||
#
|
||||
# 1. /$srcdir/[a-zA-Z0-9]/$user for example:
|
||||
# /var/maildir/a/anarchist
|
||||
# /var/maildir/a/arthur
|
||||
# ...
|
||||
# /var/maildir/Z/Zaphod
|
||||
# /var/maildir/Z/Zebra
|
||||
#
|
||||
# 2. or the following:
|
||||
# /var/maildir/domain.org/user1
|
||||
# /var/maildir/domain.org/user2
|
||||
# ...
|
||||
# /var/maildir/anotherdomain.org/user1
|
||||
# /var/maildir/anotherdomain.org/user2
|
||||
# ...
|
||||
#
|
||||
# if the configuration is setup to have keepdaily at 3,
|
||||
# keepweekly is 2, and keepmonthly is 1, then each user's
|
||||
# maildir backup snapshot directory will contain these files:
|
||||
# daily.1
|
||||
# daily.2
|
||||
# daily.3
|
||||
# weekly.1
|
||||
# weekly.2
|
||||
# monthly.1
|
||||
#
|
||||
# The basic algorithm is to rsync each maildir individually,
|
||||
# and to use hard links for retaining historical data.
|
||||
#
|
||||
# We handle each maildir individually because it becomes very
|
||||
# unweldy to hardlink and rsync many hundreds of thousands
|
||||
# of files at once. It is much faster to take on smaller
|
||||
# chunks at a time.
|
||||
#
|
||||
# For the backup rotation to work, destuser must be able to run
|
||||
# arbitrary bash commands on the desthost.
|
||||
#
|
||||
# Any maildir which is deleted from the source will be moved to
|
||||
# "deleted" directory in the destination. It is up to you to
|
||||
# periodically remove this directory or old maildirs in it.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
getconf rotate yes
|
||||
getconf remove yes
|
||||
getconf backup yes
|
||||
|
||||
getconf loadlimit 5
|
||||
getconf speedlimit 0
|
||||
getconf keepdaily 5
|
||||
getconf keepweekly 3
|
||||
getconf keepmonthly 1
|
||||
|
||||
getconf srcdir /var/maildir
|
||||
getconf destdir
|
||||
getconf desthost
|
||||
getconf destport 22
|
||||
getconf destuser
|
||||
getconf destid_file /root/.ssh/id_rsa
|
||||
|
||||
getconf multiconnection notset
|
||||
|
||||
failedcount=0
|
||||
# strip trailing /
|
||||
destdir=${destdir%/}
|
||||
srcdir=${srcdir%/}
|
||||
|
||||
[ -d $srcdir ] || fatal "source directory $srcdir doesn't exist"
|
||||
|
||||
[ "$multiconnection" == "notset" ] && fatal "The maildir handler uses a very different destination format. See the example .maildir for more information"
|
||||
|
||||
if [ $test ]; then
|
||||
testflags="--dry-run -v"
|
||||
fi
|
||||
|
||||
rsyncflags="$testflags -e 'ssh -p $destport -i $destid_file' -r -v --ignore-existing --delete --size-only --bwlimit=$speedlimit"
|
||||
excludes="--exclude '.Trash/\*' --exclude '.Mistakes/\*' --exclude '.Spam/\*'"
|
||||
|
||||
##################################################################
|
||||
### FUNCTIONS
|
||||
|
||||
function do_user() {
|
||||
local user=$1
|
||||
local btype=$2
|
||||
local userdir=${3%/}
|
||||
local source="$srcdir/$userdir/$user/"
|
||||
local target="$destdir/$userdir/$user/$btype.1"
|
||||
if [ ! -d $source ]; then
|
||||
warning "maildir $source not found"
|
||||
return
|
||||
fi
|
||||
|
||||
debug "syncing"
|
||||
ret=`$RSYNC -e "ssh -p $destport -i $destid_file" -r \
|
||||
--links --ignore-existing --delete --size-only --bwlimit=$speedlimit \
|
||||
--exclude '.Trash/*' --exclude '.Mistakes/*' --exclude '.Spam/*' \
|
||||
$source $destuser@$desthost:$target \
|
||||
2>&1`
|
||||
ret=$?
|
||||
# ignore 0 (success) and 24 (file vanished before it could be copied)
|
||||
if [ $ret != 0 -a $ret != 24 ]; then
|
||||
warning "rsync $user failed"
|
||||
warning " returned: $ret"
|
||||
let "failedcount = failedcount + 1"
|
||||
if [ $failedcount -gt 100 ]; then
|
||||
fatal "100 rsync errors -- something is not working right. bailing out."
|
||||
fi
|
||||
fi
|
||||
ssh -o PasswordAuthentication=no $desthost -l $destuser -i $destid_file "date +%c%n%s > $target/created"
|
||||
}
|
||||
|
||||
# remove any maildirs from backup which might have been deleted
|
||||
# and add new ones which have just been created.
|
||||
# (actually, it just moved them to the directory "deleted")
|
||||
|
||||
function do_remove() {
|
||||
local tmp1=`maketemp maildir-tmp-file`
|
||||
local tmp2=`maketemp maildir-tmp-file`
|
||||
|
||||
ssh -p $destport -i $destid_file $destuser@$desthost mkdir -p "$destdir/deleted"
|
||||
cd "$srcdir"
|
||||
for userdir in `ls -d1 */`; do
|
||||
ls -1 "$srcdir/$userdir" | sort > $tmp1
|
||||
ssh -p $destport -i $destid_file $destuser@$desthost ls -1 "$destdir/$userdir" | sort > $tmp2
|
||||
for deluser in `join -v 2 $tmp1 $tmp2`; do
|
||||
[ "$deluser" != "" ] || continue
|
||||
info "removing $destuser@$desthost:$destdir/$userdir$deluser/"
|
||||
ssh -p $destport -i $destid_file $destuser@$desthost mv "$destdir/$userdir$deluser/" "$destdir/deleted"
|
||||
ssh -p $destport -i $destid_file $destuser@$desthost "date +%c%n%s > '$destdir/deleted/$deluser/deleted_on'"
|
||||
done
|
||||
done
|
||||
rm $tmp1
|
||||
rm $tmp2
|
||||
}
|
||||
|
||||
function do_rotate() {
|
||||
[ "$rotate" == "yes" ] || return;
|
||||
local user=$1
|
||||
local userdir=${2%/}
|
||||
local backuproot="$destdir/$userdir/$user"
|
||||
(
|
||||
ssh -T -o PasswordAuthentication=no $desthost -l $destuser -i $destid_file <<EOF
|
||||
##### BEGIN REMOTE SCRIPT #####
|
||||
seconds_daily=86400
|
||||
seconds_weekly=604800
|
||||
seconds_monthly=2628000
|
||||
keepdaily=$keepdaily
|
||||
keepweekly=$keepweekly
|
||||
keepmonthly=$keepmonthly
|
||||
now=\`date +%s\`
|
||||
|
||||
if [ ! -d "$backuproot" ]; then
|
||||
echo "Debug: skipping rotate of $user. $backuproot doesn't exist."
|
||||
exit
|
||||
fi
|
||||
for rottype in daily weekly monthly; do
|
||||
seconds=\$((seconds_\${rottype}))
|
||||
|
||||
dir="$backuproot/\$rottype"
|
||||
if [ ! -d \$dir.1 ]; then
|
||||
echo "Debug: \$dir.1 does not exist, skipping."
|
||||
continue 1
|
||||
elif [ ! -f \$dir.1/created ]; then
|
||||
echo "Warning: \$dir.1/created does not exist. This backup may be only partially completed. Skipping rotation."
|
||||
continue 1
|
||||
fi
|
||||
|
||||
# Rotate the current list of backups, if we can.
|
||||
oldest=\`find $backuproot -maxdepth 1 -type d -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\`
|
||||
#echo "Debug: oldest \$oldest"
|
||||
[ "\$oldest" == "" ] && oldest=0
|
||||
for (( i=\$oldest; i > 0; i-- )); do
|
||||
if [ -d \$dir.\$i ]; then
|
||||
if [ -f \$dir.\$i/created ]; then
|
||||
created=\`tail -1 \$dir.\$i/created\`
|
||||
else
|
||||
created=0
|
||||
fi
|
||||
cutoff_time=\$(( now - (seconds*(i-1)) ))
|
||||
if [ ! \$created -gt \$cutoff_time ]; then
|
||||
next=\$(( i + 1 ))
|
||||
if [ ! -d \$dir.\$next ]; then
|
||||
echo "Debug: \$rottype.\$i --> \$rottype.\$next"
|
||||
mv \$dir.\$i \$dir.\$next
|
||||
date +%c%n%s > \$dir.\$next/rotated
|
||||
else
|
||||
echo "Debug: skipping rotation of \$dir.\$i because \$dir.\$next already exists."
|
||||
fi
|
||||
else
|
||||
echo "Debug: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
max=\$((keepdaily+1))
|
||||
if [ \( \$keepweekly -gt 0 -a -d $backuproot/daily.\$max \) -a ! -d $backuproot/weekly.1 ]; then
|
||||
echo "Debug: daily.\$max --> weekly.1"
|
||||
mv $backuproot/daily.\$max $backuproot/weekly.1
|
||||
date +%c%n%s > $backuproot/weekly.1/rotated
|
||||
fi
|
||||
|
||||
max=\$((keepweekly+1))
|
||||
if [ \( \$keepmonthly -gt 0 -a -d $backuproot/weekly.\$max \) -a ! -d $backuproot/monthly.1 ]; then
|
||||
echo "Debug: weekly.\$max --> monthly.1"
|
||||
mv $backuproot/weekly.\$max $backuproot/monthly.1
|
||||
date +%c%n%s > $backuproot/monthly.1/rotated
|
||||
fi
|
||||
|
||||
for rottype in daily weekly monthly; do
|
||||
max=\$((keep\${rottype}+1))
|
||||
dir="$backuproot/\$rottype"
|
||||
oldest=\`find $backuproot -maxdepth 1 -type d -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\`
|
||||
[ "\$oldest" == "" ] && oldest=0
|
||||
# if we've rotated the last backup off the stack, remove it.
|
||||
for (( i=\$oldest; i >= \$max; i-- )); do
|
||||
if [ -d \$dir.\$i ]; then
|
||||
if [ -d $backuproot/rotate.tmp ]; then
|
||||
echo "Debug: removing rotate.tmp"
|
||||
rm -rf $backuproot/rotate.tmp
|
||||
fi
|
||||
echo "Debug: moving \$rottype.\$i to rotate.tmp"
|
||||
mv \$dir.\$i $backuproot/rotate.tmp
|
||||
fi
|
||||
done
|
||||
done
|
||||
####### END REMOTE SCRIPT #######
|
||||
EOF
|
||||
) | (while read a; do passthru $a; done)
|
||||
|
||||
}
|
||||
|
||||
|
||||
function setup_remote_dirs() {
|
||||
local user=$1
|
||||
local backuptype=$2
|
||||
local userdir=${3%/}
|
||||
local dir="$destdir/$userdir/$user/$backuptype"
|
||||
local tmpdir="$destdir/$userdir/$user/rotate.tmp"
|
||||
(
|
||||
ssh -T -o PasswordAuthentication=no $desthost -l $destuser -i $destid_file <<EOF
|
||||
if [ ! -d $destdir ]; then
|
||||
echo "Fatal: Destination directory $destdir does not exist on host $desthost."
|
||||
exit 1
|
||||
elif [ -d $dir.1 ]; then
|
||||
if [ -f $dir.1/created ]; then
|
||||
echo "Warning: $dir.1 already exists. Overwriting contents."
|
||||
else
|
||||
echo "Warning: we seem to be resuming a partially written $dir.1"
|
||||
fi
|
||||
else
|
||||
if [ -d $tmpdir ]; then
|
||||
mv $tmpdir $dir.1
|
||||
if [ \$? == 1 ]; then
|
||||
echo "Fatal: could mv $destdir/rotate.tmp $dir.1 on host $desthost"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
mkdir --parents $dir.1
|
||||
if [ \$? == 1 ]; then
|
||||
echo "Fatal: could not create directory $dir.1 on host $desthost"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ -d $dir.2 ]; then
|
||||
echo "Debug: update links $backuptype.2 --> $backuptype.1"
|
||||
cp -alf $dir.2/. $dir.1
|
||||
#if [ \$? == 1 ]; then
|
||||
# echo "Fatal: could not create hard links to $dir.1 on host $desthost"
|
||||
# exit 1
|
||||
#fi
|
||||
fi
|
||||
fi
|
||||
[ -f $dir.1/created ] && rm $dir.1/created
|
||||
[ -f $dir.1/rotated ] && rm $dir.1/rotated
|
||||
exit 0
|
||||
EOF
|
||||
) | (while read a; do passthru $a; done)
|
||||
|
||||
if [ $? == 1 ]; then exit; fi
|
||||
}
|
||||
|
||||
function start_mux() {
|
||||
if [ "$multiconnection" == "yes" ]; then
|
||||
debug "Starting dummy ssh connection"
|
||||
ssh -p $destport -i $destid_file $destuser@$desthost sleep 1d &
|
||||
sleep 1
|
||||
fi
|
||||
}
|
||||
|
||||
function end_mux() {
|
||||
if [ "$multiconnection" == "yes" ]; then
|
||||
debug "Stopping dummy ssh connection"
|
||||
ssh -p $destport -i $destid_file $destuser@$desthost pkill sleep
|
||||
fi
|
||||
}
|
||||
|
||||
###
|
||||
##################################################################
|
||||
|
||||
# see if we can login
|
||||
debug "ssh -o PasswordAuthentication=no $desthost -l $destuser -i $destid_file 'echo -n 1'"
|
||||
if [ ! $test ]; then
|
||||
result=`ssh -o PasswordAuthentication=no $desthost -l $destuser -i $destid_file 'echo -n 1' 2>&1`
|
||||
if [ "$result" != "1" ]; then
|
||||
fatal "Can't connect to $desthost as $destuser using $destid_file."
|
||||
fi
|
||||
fi
|
||||
|
||||
end_mux
|
||||
start_mux
|
||||
|
||||
## SANITY CHECKS ##
|
||||
status=`ssh -p $destport -i $destid_file $destuser@$desthost "[ -d \"$destdir\" ] && echo 'ok'"`
|
||||
if [ "$status" != "ok" ]; then
|
||||
end_mux
|
||||
fatal "Destination directory $destdir doesn't exist!"
|
||||
exit
|
||||
fi
|
||||
|
||||
### REMOVE OLD MAILDIRS ###
|
||||
|
||||
if [ "$remove" == "yes" ]; then
|
||||
do_remove
|
||||
fi
|
||||
|
||||
### MAKE BACKUPS ###
|
||||
|
||||
if [ "$backup" == "yes" ]; then
|
||||
if [ $keepdaily -gt 0 ]; then btype=daily
|
||||
elif [ $keepweekly -gt 0 ]; then btype=weekly
|
||||
elif [ $keepmonthly -gt 0 ]; then btype=monthly
|
||||
else fatal "keeping no backups"; fi
|
||||
|
||||
if [ "$testuser" != "" ]; then
|
||||
cd "$srcdir/${user:0:1}"
|
||||
do_rotate $testuser
|
||||
setup_remote_dirs $testuser $btype
|
||||
do_user $testuser $btype
|
||||
else
|
||||
[ -d "$srcdir" ] || fatal "directory $srcdir not found."
|
||||
cd "$srcdir"
|
||||
for userdir in `ls -d1 */`; do
|
||||
[ -d "$srcdir/$userdir" ] || fatal "directory $srcdir/$userdir not found."
|
||||
cd "$srcdir/$userdir"
|
||||
debug $userdir
|
||||
for user in `ls -1`; do
|
||||
[ "$user" != "" ] || continue
|
||||
debug "$user $userdir"
|
||||
do_rotate $user $userdir
|
||||
setup_remote_dirs $user $btype $userdir
|
||||
do_user $user $btype $userdir
|
||||
done
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
end_mux
|
||||
|
@ -1,97 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS makecd:makecd_backup"
|
||||
wizardname="makecd action wizard"
|
||||
|
||||
declare -a makecd_excludes
|
||||
|
||||
makecd_wizard() {
|
||||
|
||||
inputBox "$wizardname" "specify a burner type cd or dvd:"
|
||||
[ $? = 1 ] && return
|
||||
burnertype="burnertype = $REPLY"
|
||||
|
||||
booleanBox "$wizardname" "Make iso image only? or burn"
|
||||
if [ $? = 0 ]; then
|
||||
isoonly="isoonly = yes"
|
||||
else
|
||||
isoonly="isoonly = no"
|
||||
fi
|
||||
|
||||
# backupdir
|
||||
inputBox "$wizardname" "Directory where to store the backups:"
|
||||
[ $? = 1 ] && return
|
||||
backupdir="backupdir = $REPLY"
|
||||
|
||||
inputBox "$wizardname" "what name to give to the image file?"
|
||||
[ $? = 1 ] && return
|
||||
imagefile="imagefile = $REPLY"
|
||||
|
||||
inputBox "$wizardname" "specify a burner device:"
|
||||
[ $? = 1 ] && return
|
||||
device="device = $REPLY"
|
||||
|
||||
# target - root of system to be included
|
||||
inputBox "$wizardname" "root of filesystem for burn:"
|
||||
[ $? = 1 ] && return
|
||||
target="target = $REPLY"
|
||||
|
||||
|
||||
# excludes
|
||||
|
||||
formBegin "$wizardname: excludes"
|
||||
for ((i=0; i < ${#makecd_excludes[@]} ; i++)); do
|
||||
formItem exclude ${makecd_excludes[$i]}
|
||||
done
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formDisplay
|
||||
[ $? = 1 ] && return;
|
||||
|
||||
unset makecd_excludes
|
||||
makecd_excludes=($REPLY)
|
||||
|
||||
get_next_filename $configdirectory/20.makecd
|
||||
cat >> $next_filename <<EOF
|
||||
|
||||
# TYP is cd or dvd AS WELL AS the disk inside!!
|
||||
$burnertype
|
||||
|
||||
# not yet supported
|
||||
system = no
|
||||
|
||||
# iso or burn to cd/dvd?
|
||||
$isoonly
|
||||
|
||||
# location for image file
|
||||
$backupdir
|
||||
|
||||
# image filename
|
||||
$imagefile
|
||||
|
||||
# cd/dvd burner device
|
||||
$device
|
||||
|
||||
# dirs/files to include in the backup
|
||||
$target
|
||||
|
||||
# directories/files to be excluded
|
||||
# exclude = /proc
|
||||
# exclude = /sys
|
||||
# exclude = /dev
|
||||
EOF
|
||||
|
||||
for ((j=0; j < ${#makecd_excludes[@]} ; j++)); do
|
||||
echo "exclude = ${makecd_excludes[$j]}" >> $next_filename
|
||||
done
|
||||
|
||||
chmod 600 $next_filename
|
||||
}
|
||||
|
@ -1,88 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# burncd handler script for backupninja
|
||||
#
|
||||
getconf backupdir /var/backups/makecd
|
||||
getconf exclude
|
||||
getconf target
|
||||
getconf burnertype cd
|
||||
getconf system no
|
||||
getconf isoonly yes
|
||||
getconf imagefile backup.iso
|
||||
getconf device
|
||||
getconf nicelevel 0
|
||||
|
||||
# define needed executables:
|
||||
MKISOFS="/usr/bin/genisoimage"
|
||||
GROWISOFS="/usr/bin/growisofs"
|
||||
CDRECORD="/usr/bin/wodim"
|
||||
CDRDAO="/usr/bin/cdrdao"
|
||||
DVDINFO="/usr/bin/dvd+rw-mediainfo"
|
||||
|
||||
# create backup dirs and check existence of progs.
|
||||
|
||||
[ -d $backupdir ] || mkdir -p $backupdir
|
||||
[ -d $backupdir ] || fatal "Backup directory '$backupdir'"
|
||||
[ -e "$target" ] || fatal "target does not exist "
|
||||
|
||||
[ -x "$MKISOFS" ] || debug 3 "echo executable $MKISOFS not present"
|
||||
[ -x "$GROWISOFS" ] || debug 3 "echo executable $GROWISOFS not present"
|
||||
[ -x "$CDRECORD" ] || debug 3 "echo executable $CDRECORD not present"
|
||||
[ -x "$CDRDAO" ] || debug 3 "echo executable $CDRDAO not present"
|
||||
|
||||
if [ "$isoonly" == "no" ]; then
|
||||
[ -e $device ] || fatal "No Burner device available"
|
||||
fi
|
||||
|
||||
outputfile="$backupdir/$imagefile"
|
||||
execstr="nice -n $nicelevel $MKISOFS --quiet -R -o $outputfile "
|
||||
|
||||
str=""
|
||||
# excludes
|
||||
for i in $exclude; do
|
||||
str=" -x ${i}$str"
|
||||
done
|
||||
|
||||
debug 0 "echo $str "
|
||||
execstr="${execstr} $str $target "
|
||||
debug 0 "echo $execstr "
|
||||
|
||||
output=` $execstr 2>&1 `
|
||||
code=$?
|
||||
if [ "$code" == "0" ]; then
|
||||
debug $output
|
||||
info "Successfully finished creation of iso"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to create iso"
|
||||
fi
|
||||
|
||||
if [ "$isoonly" == "no" ]; then
|
||||
|
||||
if [ "$burnertype" == "cd" ]; then
|
||||
# burning iso to CD
|
||||
$CDRECORD -v gracetime=2 dev=$device speed=8 -dao -data $outputfile
|
||||
code=$?
|
||||
if [ "$code" == "0" ]; then
|
||||
debug $output
|
||||
info "Successfully burned CD"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to create CD"
|
||||
fi
|
||||
fi
|
||||
if [ "$burnertype" == "dvd" ]; then
|
||||
# burning iso dvd
|
||||
$GROWISOFS -speed=2 -Z $device=$outputfile -use-the-force-luke=notray -use-the-force-luke=tty
|
||||
code=$?
|
||||
if [ "$code" == "0" ]; then
|
||||
debug $output
|
||||
info "Successfully burned DVD"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to create DVD"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
|
@ -1,217 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS mysql:mysql_database_backup"
|
||||
|
||||
do_mysql_vserver() {
|
||||
choose_one_vserver "$mysql_title"
|
||||
[ $? = 0 ] || return 1
|
||||
mysql_vsname="vsname = $REPLY"
|
||||
}
|
||||
|
||||
do_mysql_databases() {
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$mysql_title: databases"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
mysql_databases="databases = "
|
||||
for i in $REPLY; do
|
||||
[ -n "$i" ] && mysql_databases="$mysql_databases $i"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
do_mysql_password() {
|
||||
inputBox "$mysql_title" "specify a mysql user:"
|
||||
[ $? = 1 ] && return
|
||||
user=$REPLY
|
||||
inputBox "$mysql_title" "specify the mysql user's password:"
|
||||
[ $? = 1 ] && return
|
||||
password=$REPLY
|
||||
do_mysql_final "dbusername = $user\ndbpassword = $password"
|
||||
}
|
||||
|
||||
do_mysql_debian() {
|
||||
_DISABLE_HOTCOPY=yes
|
||||
do_mysql_final "configfile = /etc/mysql/debian.cnf"
|
||||
}
|
||||
|
||||
do_mysql_user() {
|
||||
inputBox "$mysql_title" "what system user does mysql backup use?"
|
||||
[ $? = 1 ] && return
|
||||
do_mysql_final "user = $REPLY"
|
||||
}
|
||||
|
||||
do_mysql_final() {
|
||||
if [ -z "$_DISABLE_HOTCOPY" ]; then
|
||||
checkBox "$mysql_title" "check options" \
|
||||
"sqldump" "create a backup using mysqldump (more compat)." no \
|
||||
"hotcopy" "create a backup using mysqlhotcopy (faster)." yes \
|
||||
"compress" "compress the sql output files" yes
|
||||
status=$?
|
||||
sqldump="sqldump = no"
|
||||
hotcopy="hotcopy = no"
|
||||
else
|
||||
checkBox "$mysql_title" "check options" \
|
||||
"compress" "compress the sql output files" yes
|
||||
status=$?
|
||||
sqldump="sqldump = yes"
|
||||
hotcopy="hotcopy = no"
|
||||
fi
|
||||
|
||||
[ $status = 1 ] && return;
|
||||
result="$REPLY"
|
||||
compress="compress = no"
|
||||
for opt in $result; do
|
||||
case $opt in
|
||||
'"sqldump"') sqldump="sqldump = yes";;
|
||||
'"hotcopy"') hotcopy="hotcopy = yes";;
|
||||
'"compress"') compress="compress = yes";;
|
||||
esac
|
||||
done
|
||||
get_next_filename $configdirectory/20.mysql
|
||||
|
||||
cat >> $next_filename <<EOF
|
||||
### backupninja MySQL config file ###
|
||||
|
||||
# hotcopy = < yes | no > (default = no)
|
||||
# make a backup of the actual database binary files using mysqlhotcopy.
|
||||
$hotcopy
|
||||
|
||||
# sqldump = < yes | no > (default = no)
|
||||
# make a backup using mysqldump. this creates text files with sql commands
|
||||
# sufficient to recontruct the database.
|
||||
#
|
||||
$sqldump
|
||||
|
||||
# sqldumpoptions = <options>
|
||||
# (default = --lock-tables --complete-insert --add-drop-table --quick --quote-names)
|
||||
# arguments to pass to mysqldump
|
||||
# sqldumpoptions = --add-drop-table --quick --quote-names
|
||||
|
||||
# compress = < yes | no > (default = yes)
|
||||
# if yes, compress the sqldump output.
|
||||
$compress
|
||||
|
||||
# dbhost = <host> (default = localhost)
|
||||
|
||||
EOF
|
||||
cat >> $next_filename <<EOF
|
||||
|
||||
# backupdir = <dir> (default: /var/backups/mysql)
|
||||
# where to dump the backups. hotcopy backups will be in a subdirectory
|
||||
# 'hotcopy' and sqldump backups will be in a subdirectory 'sqldump'
|
||||
$mysql_backupdir
|
||||
|
||||
# databases = <all | db1 db2 db3 > (default = all)
|
||||
# which databases to backup. should either be the word 'all' or a
|
||||
# space separated list of database names.
|
||||
$mysql_databases
|
||||
|
||||
EOF
|
||||
|
||||
if [ $host_or_vservers == vservers ]
|
||||
then
|
||||
cat >> $next_filename <<EOF
|
||||
#
|
||||
# vsname = <vserver> (no default)
|
||||
# vsname indicates which vserver to operate on, this is only used if
|
||||
# vserver is set to yes in /etc/backupninja.conf
|
||||
# NOTE: if you do not specify a vsname the host will be operated on
|
||||
# alsoNOTE: if operating on a vserver, $VROOTDIR will be
|
||||
# prepended to backupdir.
|
||||
EOF
|
||||
echo -e "$mysql_vsname\n" >> $next_filename
|
||||
fi
|
||||
|
||||
echo -e $@ >> $next_filename
|
||||
|
||||
chmod 600 $next_filename
|
||||
}
|
||||
|
||||
mysql_wizard() {
|
||||
|
||||
# Global variables
|
||||
mysql_title="MySQL action wizard"
|
||||
|
||||
# backup the host system or a Vserver?
|
||||
choose_host_or_one_vserver "$mysql_title"
|
||||
[ $? = 0 ] || return 1
|
||||
if [ $host_or_vservers == vservers ]
|
||||
then
|
||||
do_mysql_vserver
|
||||
[ $? = 0 ] || return 1
|
||||
fi
|
||||
|
||||
# backupdir
|
||||
if [ $host_or_vservers == vservers ]
|
||||
then
|
||||
inputBox "$mysql_title" "Directory where to store the backups:`echo \"\n(Relative to chosen vserver's root directory)\"`" "/var/backups/mysql"
|
||||
else
|
||||
inputBox "$mysql_title" "Directory where to store the backups" "/var/backups/mysql"
|
||||
fi
|
||||
[ $? = 1 ] && return
|
||||
mysql_backupdir="backupdir = $REPLY"
|
||||
|
||||
# databases
|
||||
booleanBox "$mysql_title" "Do you want to backup all of the databases? `echo \"\n\nIf not, you'll be offered to choose individual databases to backup.\"`"
|
||||
if [ $? = 0 ]; then
|
||||
mysql_databases="databases = all"
|
||||
else
|
||||
do_mysql_databases
|
||||
[ $? = 0 ] || return 1
|
||||
fi
|
||||
|
||||
while true; do
|
||||
_DISABLE_HOTCOPY=
|
||||
menuBoxHelpFile "$mysql_title" "choose a mysql authentication method:" \
|
||||
user "change to a linux user first." \
|
||||
password "manually specify mysql user and password." \
|
||||
debian "use default mysql user debian-sys-maint."
|
||||
status=$?
|
||||
if [ $status = 2 ]; then
|
||||
# show help.
|
||||
helptmp="/tmp/backupninja.help.$$"
|
||||
cat > $helptmp <<EOF
|
||||
To connect to mysql, backupninja must authenticate.
|
||||
There are three possible authentication methods:
|
||||
|
||||
USER
|
||||
With this method, you specify a system user. Backupninja will
|
||||
then become this user before running mysqldump or mysqlhotcopy.
|
||||
The result is that ~/.my.cnf is used for authentication.
|
||||
|
||||
PASSWORD
|
||||
With this method, you manually specify a mysql user and
|
||||
password in the backup action configuration.
|
||||
|
||||
DEBIAN
|
||||
With this method, we use the debian-sys-maint user which is
|
||||
already defined in /etc/mysql/debian.cnf. If you are running
|
||||
debian, this is recommended, because no further configuration
|
||||
is needed. The drawback is that this is incompatible with
|
||||
mysqlhotcopy: you must use mysqldump.
|
||||
EOF
|
||||
dialog --textbox $helptmp 0 0
|
||||
rm $helptmp
|
||||
fi
|
||||
|
||||
[ $status = 1 ] && return;
|
||||
result="$REPLY"
|
||||
case "$result" in
|
||||
"user") do_mysql_user;return;;
|
||||
"password") do_mysql_password;return;;
|
||||
"debian") do_mysql_debian;return;;
|
||||
esac
|
||||
done
|
||||
}
|
@ -1,320 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# mysql handler script for backupninja
|
||||
#
|
||||
|
||||
getconf backupdir /var/backups/mysql
|
||||
getconf databases all
|
||||
getconf ignores
|
||||
getconf nodata
|
||||
getconf dbhost localhost
|
||||
getconf hotcopy no
|
||||
getconf sqldump no
|
||||
getconf sqldumpoptions "--lock-tables --complete-insert --add-drop-table --quick --quote-names"
|
||||
getconf compress yes
|
||||
getconf vsname
|
||||
|
||||
# authentication:
|
||||
getconf user
|
||||
getconf dbusername
|
||||
getconf dbpassword
|
||||
getconf configfile /etc/mysql/debian.cnf
|
||||
|
||||
|
||||
# Decide if the handler should operate on a vserver or on the host.
|
||||
# In the former case, check that $vsname exists and is running.
|
||||
local usevserver=no
|
||||
local vroot
|
||||
if [ $vservers_are_available = yes ]; then
|
||||
if [ -n "$vsname" ]; then
|
||||
# does it exist ?
|
||||
if ! vservers_exist "$vsname" ; then
|
||||
fatal "The vserver given in vsname ($vsname) does not exist."
|
||||
fi
|
||||
# is it running ?
|
||||
vservers_running $vsname || fatal "The vserver $vsname is not running."
|
||||
# everything ok
|
||||
info "Using vserver '$vsname'."
|
||||
usevserver=yes
|
||||
vroot="$VROOTDIR/$vsname"
|
||||
else
|
||||
info "No vserver name specified, actions will be performed on the host."
|
||||
fi
|
||||
fi
|
||||
|
||||
## Prepare ignore part of the command
|
||||
## This only works for mysqldump at the moment
|
||||
|
||||
ignore=''
|
||||
for i in $ignores $nodata; do
|
||||
ignore="$ignore --ignore-table=$i"
|
||||
done
|
||||
|
||||
# create backup dirs, $vroot will be empty if no vsname was specified
|
||||
# and we will instead proceed to operate on the host
|
||||
[ -d $vroot$backupdir ] || mkdir -p $vroot$backupdir
|
||||
[ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir'"
|
||||
hotdir="$backupdir/hotcopy"
|
||||
dumpdir="$backupdir/sqldump"
|
||||
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
[ "$sqldump" == "no" -o -d $vroot$dumpdir ] || $VSERVER $vsname exec mkdir -p $dumpdir
|
||||
[ "$hotcopy" == "no" -o -d $vroot$hotdir ] || $VSERVER $vsname exec mkdir -p $hotdir
|
||||
else
|
||||
[ "$sqldump" == "no" -o -d $dumpdir ] || mkdir -p $dumpdir
|
||||
[ "$hotcopy" == "no" -o -d $hotdir ] || mkdir -p $hotdir
|
||||
fi
|
||||
|
||||
#######################################################################
|
||||
## AUTHENTICATION
|
||||
|
||||
#
|
||||
# one of three authentication methods:
|
||||
# 1. setting the user, so that /home/user/.my.cnf is used.
|
||||
# 2. specifying the user and password in the handler config,
|
||||
# which generates a temporary .my.cnf in /root/.my.cnf
|
||||
# 3. specify the config file with --defaults-extra-file
|
||||
# (this option DOESN'T WORK WITH MYSQLHOTCOPY)
|
||||
#
|
||||
|
||||
# create .my.cnf
|
||||
# only if dbusername and dbpassword specified.
|
||||
# we create a tmp file because we don't want to
|
||||
# specify the password on the command line.
|
||||
|
||||
defaultsfile=""
|
||||
|
||||
if [ "$dbusername" != "" -a "$dbpassword" != "" ]
|
||||
then
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
vhome=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'`
|
||||
home="$vroot$vhome"
|
||||
else
|
||||
home=`getent passwd "root" | @AWK@ -F: '{print $6}'`
|
||||
fi
|
||||
|
||||
[ -d $home ] || fatal "Can't find root's home directory ($home)."
|
||||
|
||||
mycnf="$home/.my.cnf"
|
||||
|
||||
if [ -f $mycnf ]
|
||||
then
|
||||
# rename temporarily
|
||||
tmpcnf="$home/my.cnf.disable"
|
||||
debug "mv $mycnf $tmpcnf"
|
||||
mv $mycnf $tmpcnf
|
||||
fi
|
||||
|
||||
oldmask=`umask`
|
||||
umask 077
|
||||
cat > $mycnf <<EOF
|
||||
# auto generated backupninja mysql conf
|
||||
[mysql]
|
||||
host=$dbhost
|
||||
user=$dbusername
|
||||
password="$dbpassword"
|
||||
|
||||
[mysqldump]
|
||||
host=$dbhost
|
||||
user=$dbusername
|
||||
password="$dbpassword"
|
||||
|
||||
[mysqlhotcopy]
|
||||
host=$dbhost
|
||||
user=$dbusername
|
||||
password="$dbpassword"
|
||||
EOF
|
||||
umask $oldmask
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
defaultsfile="--defaults-extra-file=$vhome/.my.cnf"
|
||||
else
|
||||
defaultsfile="--defaults-extra-file=$mycnf"
|
||||
fi
|
||||
fi
|
||||
|
||||
# if a user is not set, use $configfile, otherwise use $mycnf
|
||||
if [ "$user" == "" ]; then
|
||||
user=root;
|
||||
defaultsfile="--defaults-extra-file=$configfile"
|
||||
else
|
||||
userset=true;
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
vuserhome=`$VSERVER $vsname exec getent passwd "$user" | @AWK@ -F: '{print $6}'`
|
||||
if [ $? -eq 2 ]
|
||||
then
|
||||
fatal "User $user not found in /etc/passwd"
|
||||
fi
|
||||
userhome="$vroot$vuserhome"
|
||||
else
|
||||
userhome=`getent passwd "$user" | @AWK@ -F: '{print $6}'`
|
||||
if [ $? -eq 2 ]
|
||||
then
|
||||
fatal "User $user not found in /etc/passwd"
|
||||
fi
|
||||
fi
|
||||
|
||||
debug "User home set to: $userhome"
|
||||
[ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
|
||||
defaultsfile="--defaults-extra-file=$userhome/.my.cnf"
|
||||
debug "using $defaultsfile"
|
||||
fi
|
||||
|
||||
#######################################################################
|
||||
## HOT COPY
|
||||
|
||||
if [ "$hotcopy" == "yes" ]
|
||||
then
|
||||
info "Initializing hotcopy method"
|
||||
if [ "$databases" == "all" ]
|
||||
then
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
info "dbhost: $dbhost"
|
||||
execstr="$VSERVER $vsname exec $MYSQLHOTCOPY -h $dbhost --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
|
||||
else
|
||||
execstr="$MYSQLHOTCOPY --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
|
||||
fi
|
||||
debug "su $user -c \"$execstr\""
|
||||
if [ ! $test ]
|
||||
then
|
||||
output=`su $user -c "$execstr" 2>&1`
|
||||
code=$?
|
||||
if [ "$code" == "0" ]
|
||||
then
|
||||
debug $output
|
||||
info "Successfully finished hotcopy of all mysql databases"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to hotcopy all mysql databases"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
for db in $databases
|
||||
do
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
execstr="$VSERVER $vsname exec $MYSQLHOTCOPY --allowold $db $hotdir"
|
||||
else
|
||||
execstr="$MYSQLHOTCOPY --allowold $db $hotdir"
|
||||
fi
|
||||
debug 'su $user -c \"$execstr\"'
|
||||
if [ ! $test ]
|
||||
then
|
||||
output=`su $user -c "$execstr" 2>&1`
|
||||
code=$?
|
||||
if [ "$code" == "0" ]
|
||||
then
|
||||
debug $output
|
||||
info "Successfully finished hotcopy of mysql database $db"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to hotcopy mysql database $db"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################################################
|
||||
## SQL DUMP
|
||||
|
||||
if [ "$sqldump" == "yes" ]
|
||||
then
|
||||
info "Initializing SQL dump method"
|
||||
if [ "$databases" == "all" ]
|
||||
then
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
debug 'echo show databases | $VSERVER $vsname exec su $user -c \"$MYSQL $defaultsfile\" | grep -v Database'
|
||||
databases=`echo 'show databases' | $VSERVER $vsname exec su $user -c "$MYSQL $defaultsfile" | grep -v Database`
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
|
||||
fi
|
||||
else
|
||||
databases=$(su $user -c "$MYSQL $defaultsfile -N -B -e 'show databases'" | sed 's/|//g;/\+----/d')
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
for db in $databases
|
||||
do
|
||||
DUMP_BASE="$MYSQLDUMP $defaultsfile $sqldumpoptions"
|
||||
|
||||
# Dumping structure and data
|
||||
DUMP="$DUMP_BASE $ignore $db"
|
||||
|
||||
# If requested, dump only the table structure for this database
|
||||
if echo "$nodata" | grep -E '(^|[[:space:]])'"$db\." >/dev/null
|
||||
then
|
||||
# Get the structure of the tables, without data
|
||||
DUMP_STRUCT="$DUMP_BASE --no-data $db"
|
||||
for qualified_table in $nodata
|
||||
do
|
||||
table=$( expr match "$qualified_table" "$db\.\([^\w]*\)" )
|
||||
DUMP_STRUCT="$DUMP_STRUCT $table"
|
||||
done
|
||||
DUMP="( $DUMP; $DUMP_STRUCT )"
|
||||
fi
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
# Test to make sure mysqld is running, if it is not sqldump will not work
|
||||
$VSERVER $vsname exec su $user -c "$MYSQLADMIN $defaultsfile ping 2>&1 >/dev/null"
|
||||
if [ $? -ne 0 ]; then
|
||||
fatal "mysqld doesn't appear to be running!"
|
||||
fi
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="$VSERVER $vsname exec $DUMP | $GZIP > $vroot$dumpdir/${db}.sql.gz"
|
||||
else
|
||||
execstr="$VSERVER $vsname exec $DUMP -r $vroot$dumpdir/${db}.sql"
|
||||
fi
|
||||
else
|
||||
# Test to make sure mysqld is running, if it is not sqldump will not work
|
||||
su $user -c "$MYSQLADMIN $defaultsfile ping 2>&1 >/dev/null"
|
||||
if [ $? -ne 0 ]; then
|
||||
fatal "mysqld doesn't appear to be running!"
|
||||
fi
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="$DUMP | $GZIP > $dumpdir/${db}.sql.gz"
|
||||
else
|
||||
execstr="$DUMP -r $dumpdir/${db}.sql"
|
||||
fi
|
||||
fi
|
||||
debug "su $user -c \"$execstr\""
|
||||
if [ ! $test ]
|
||||
then
|
||||
output=`su $user -c "$execstr" 2>&1`
|
||||
code=$?
|
||||
if [ "$code" == "0" ]
|
||||
then
|
||||
debug $output
|
||||
info "Successfully finished dump of mysql database $db"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to dump mysql databases $db"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# clean up tmp config file
|
||||
if [ "$dbusername" != "" -a "$dbpassword" != "" ]
|
||||
then
|
||||
## clean up tmp config file
|
||||
debug "rm $mycnf"
|
||||
rm $mycnf
|
||||
if [ -f "$tmpcnf" ]
|
||||
then
|
||||
debug "mv $tmpcnf $mycnf"
|
||||
mv $tmpcnf $mycnf
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
@ -1,107 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS pgsql:postgresql_database_backup"
|
||||
|
||||
do_pgsql_vserver() {
|
||||
choose_one_vserver "$pgsql_title"
|
||||
[ $? = 0 ] || return 1
|
||||
pgsql_vsname="vsname = $REPLY"
|
||||
}
|
||||
|
||||
do_pgsql_databases() {
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$pgsql_title: databases"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formItem "Database:"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
pgsql_databases="databases = "
|
||||
for i in $REPLY; do
|
||||
[ -n "$i" ] && pgsql_databases="$pgsql_databases $i"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
pgsql_wizard() {
|
||||
|
||||
# constants
|
||||
pgsql_title="PostgreSQL action wizard"
|
||||
|
||||
# backup the host system or a Vserver?
|
||||
choose_host_or_one_vserver "$pgsql_title"
|
||||
[ $? = 0 ] || return 1
|
||||
if [ $host_or_vservers == vservers ]; then
|
||||
do_pgsql_vserver
|
||||
[ $? = 0 ] || return 1
|
||||
fi
|
||||
|
||||
# backupdir
|
||||
inputBox "$pgsql_title" "Directory where to store the backups:`[ -z \"$pgsql_vsname\" ] || echo \"\n(In respect to chosen vserver's root directory)\"`" "/var/backups/postgres"
|
||||
[ $? = 1 ] && return
|
||||
pgsql_backupdir="backupdir = $REPLY"
|
||||
|
||||
# databases
|
||||
booleanBox "$pgsql_title" "Do you want to backup the whole cluster? If not, you'll be offered to choose the databases to backup."
|
||||
if [ $? = 0 ]; then
|
||||
pgsql_databases="databases = all"
|
||||
else
|
||||
do_pgsql_databases
|
||||
[ $? = 0 ] || return 1
|
||||
fi
|
||||
|
||||
# compress
|
||||
booleanBox "$pgsql_title" "Do you want to compress the backups?"
|
||||
if [ $? = 0 ]; then
|
||||
pgsql_compress="compress = yes"
|
||||
else
|
||||
pgsql_compress="compress = no"
|
||||
fi
|
||||
|
||||
# write config file
|
||||
get_next_filename $configdirectory/20.pgsql
|
||||
cat >> $next_filename <<EOF
|
||||
### backupninja PostgreSQL config file ###
|
||||
|
||||
# vsname = <vserver> (no default)
|
||||
# what vserver to operate on, only used if vserver = yes in /etc/backupninja.conf
|
||||
# if you do not specify a vsname the host will be operated on
|
||||
# Note: if operating on a vserver, $VROOTDIR will be prepended to backupdir.
|
||||
EOF
|
||||
if [ $host_or_vservers == vservers ]; then
|
||||
echo -e "$pgsql_vsname\n" >> $next_filename
|
||||
fi
|
||||
|
||||
cat >> $next_filename <<EOF
|
||||
# backupdir = <dir> (default: /var/backups/postgres)
|
||||
# where to dump the backups
|
||||
$pgsql_backupdir
|
||||
|
||||
# databases = < all | db1 db2 db3 > (default = all)
|
||||
# which databases to backup. should either be the word 'all' or a
|
||||
# space separated list of database names.
|
||||
# Note: when using 'all', pg_dumpall is used instead of pg_dump, which means
|
||||
# that cluster-wide data (such as users and groups) are saved.
|
||||
$pgsql_databases
|
||||
|
||||
# compress = < yes | no > (default = yes)
|
||||
# if yes, compress the pg_dump/pg_dumpall output.
|
||||
$pgsql_compress
|
||||
|
||||
### You can also set the following variables in backupninja.conf:
|
||||
# PGSQLDUMP: pg_dump path (default: /usr/bin/pg_dump)
|
||||
# PGSQLDUMPALL: pg_dumpall path (default: /usr/bin/pg_dumpall)
|
||||
# PGSQLUSER: user running PostgreSQL (default: postgres)
|
||||
|
||||
EOF
|
||||
chmod 600 $next_filename
|
||||
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# PostgreSQL handler script for backupninja
|
||||
#
|
||||
|
||||
getconf backupdir /var/backups/postgres
|
||||
getconf databases all
|
||||
getconf compress yes
|
||||
getconf vsname
|
||||
|
||||
localhost=`hostname`
|
||||
|
||||
# Decide if the handler should operate on a vserver or on the host.
|
||||
# In the former case, check that $vsname exists and is running.
|
||||
local usevserver=no
|
||||
local vroot
|
||||
if [ $vservers_are_available = yes ]; then
|
||||
if [ -n "$vsname" ]; then
|
||||
# does it exist ?
|
||||
if ! vservers_exist "$vsname" ; then
|
||||
fatal "The vserver given in vsname ($vsname) does not exist."
|
||||
fi
|
||||
# is it running ?
|
||||
vservers_running $vsname || fatal "The vserver $vsname is not running."
|
||||
# everything ok
|
||||
info "Using vserver '$vsname'."
|
||||
usevserver=yes
|
||||
vroot="$VROOTDIR/$vsname"
|
||||
else
|
||||
info "No vserver name specified, actions will be performed on the host."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make sure that the system to backup has the needed executables
|
||||
if [ $usevserver = yes ]; then
|
||||
debug "Examining vserver '$vsname'."
|
||||
if [ "$databases" == "all" ]; then
|
||||
[ -x "$vroot`$VSERVER $vsname exec which $PGSQLDUMPALL`" ] || \
|
||||
fatal "Can't find $PGSQLDUMPALL in vserver $vsname."
|
||||
else
|
||||
[ -x "$vroot`$VSERVER $vsname exec which $PGSQLDUMP`" ] || \
|
||||
fatal "Can't find $PGSQLDUMP in vserver $vsname."
|
||||
fi
|
||||
else
|
||||
if [ "$databases" == "all" ]; then
|
||||
[ -x "`which $PGSQLDUMPALL`" ] || \
|
||||
fatal "Can't find $PGSQLDUMPALL."
|
||||
else
|
||||
[ -x "`which $PGSQLDUMP`" ] || \
|
||||
fatal "Can't find $PGSQLDUMP."
|
||||
fi
|
||||
fi
|
||||
|
||||
# create backup dir, the vroot variable will be empty if no vsname was specified
|
||||
# and will proceed to operate on the host
|
||||
[ -d $vroot$backupdir ] || (debug "mkdir -p $vroot$backupdir"; mkdir -p $vroot$backupdir)
|
||||
[ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir' does not exist, and could not be created."
|
||||
|
||||
# give backup dir the good uid and permissions
|
||||
# (in respect to the vserver, if $usevserver = yes)
|
||||
if [ $usevserver = yes ]; then
|
||||
pguid=`$VSERVER $vsname exec getent passwd $PGSQLUSER | @AWK@ -F: '{print $3}'`
|
||||
else
|
||||
pguid=`getent passwd $PGSQLUSER | @AWK@ -F: '{print $3}'`
|
||||
fi
|
||||
[ -n "$pguid" ] || \
|
||||
fatal "No user called $PGSQLUSER`[ $usevserver = no ] || echo \" on vserver $vsname\"`."
|
||||
debug "chown $pguid $vroot$backupdir"
|
||||
chown $pguid $vroot$backupdir
|
||||
debug "chmod 700 $vroot$backupdir"
|
||||
chmod 700 $vroot$backupdir
|
||||
|
||||
# if $databases = all, use pg_dumpall
|
||||
if [ "$databases" == "all" ]; then
|
||||
if [ $usevserver = yes ]; then
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${vsname}.sql.gz\""
|
||||
else
|
||||
execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${vsname}.sql\""
|
||||
fi
|
||||
else
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${localhost}-all.sql.gz\""
|
||||
else
|
||||
execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${localhost}-all.sql\""
|
||||
fi
|
||||
fi
|
||||
debug "$execstr"
|
||||
if [ ! $test ]; then
|
||||
output=`eval $execstr 2>&1`
|
||||
code=$?
|
||||
if [ "$code" == "0" ]; then
|
||||
debug $output
|
||||
info "Successfully finished dump of pgsql cluster"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to dump pgsql cluster"
|
||||
fi
|
||||
fi
|
||||
|
||||
# else use pg_dump on each specified database
|
||||
else
|
||||
for db in $databases; do
|
||||
if [ $usevserver = yes ]; then
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\""
|
||||
else
|
||||
execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | > $backupdir/${db}.sql\""
|
||||
fi
|
||||
else
|
||||
if [ "$compress" == "yes" ]; then
|
||||
execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\""
|
||||
else
|
||||
execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db > $backupdir/${db}.sql\""
|
||||
fi
|
||||
fi
|
||||
debug "$execstr"
|
||||
if [ ! $test ]; then
|
||||
output=`eval $execstr 2>&1`
|
||||
code=$?
|
||||
if [ "$code" == "0" ]; then
|
||||
debug $output
|
||||
info "Successfully finished dump of pgsql database ${db}"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed to dump pgsql database ${db}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
return 0
|
||||
|
@ -1,407 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS rdiff:incremental_remote_filesystem_backup"
|
||||
|
||||
declare -a rdiff_includes
|
||||
declare -a rdiff_excludes
|
||||
declare -a rdiff_vsincludes
|
||||
declare -a rdiff_vsexcludes
|
||||
|
||||
# FUNCTIONS
|
||||
|
||||
do_rdiff_host_includes() {
|
||||
set -o noglob
|
||||
# choose the files to backup
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$rdiff_title - host system: includes"
|
||||
for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do
|
||||
formItem include ${rdiff_includes[$i]}
|
||||
done
|
||||
formItem include
|
||||
formItem include
|
||||
formItem include
|
||||
formDisplay
|
||||
[ $? = 0 ] || return
|
||||
unset rdiff_includes
|
||||
rdiff_includes=($REPLY)
|
||||
done
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
do_rdiff_vserver() {
|
||||
# choose the vservers to backup (into $selected_vservers)
|
||||
choose_one_or_more_vservers "$rdiff_title"
|
||||
[ $? = 0 ] || return 1
|
||||
|
||||
set -o noglob
|
||||
# choose the files to backup
|
||||
REPLY=
|
||||
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$rdiff_title - vsincludes (backup these directories from every vserver)"
|
||||
[ -z "$rdiff_vsincludes" ] && rdiff_vsincludes="$rdiff_default_includes"
|
||||
|
||||
for i in $rdiff_vsincludes; do
|
||||
formItem include "$i"
|
||||
done
|
||||
formItem include ""
|
||||
formItem include ""
|
||||
formItem include ""
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
rdiff_vsincludes=($REPLY)
|
||||
done
|
||||
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
do_rdiff_excludes() {
|
||||
set -o noglob
|
||||
formBegin "$rdiff_title: excludes"
|
||||
for ((i=0; i < ${#rdiff_excludes[@]} ; i++))
|
||||
do
|
||||
formItem exclude ${rdiff_excludes[$i]}
|
||||
done
|
||||
formItem exclude
|
||||
formItem exclude
|
||||
formDisplay
|
||||
[ $? = 0 ] || return
|
||||
unset rdiff_excludes
|
||||
rdiff_excludes=($REPLY)
|
||||
set +o noglob
|
||||
}
|
||||
|
||||
do_rdiff_src() {
|
||||
choose_host_or_vservers_or_both "$rdiff_title"
|
||||
[ $? = 0 ] || return 1
|
||||
case $host_or_vservers in
|
||||
'host')
|
||||
do_rdiff_host_includes
|
||||
[ $? = 0 ] || return 1
|
||||
;;
|
||||
'vservers')
|
||||
do_rdiff_vserver
|
||||
[ $? = 0 ] || return 1
|
||||
;;
|
||||
'both')
|
||||
do_rdiff_host_includes
|
||||
[ $? = 0 ] || return 1
|
||||
do_rdiff_vserver
|
||||
[ $? = 0 ] || return 1
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
do_rdiff_excludes
|
||||
[ $? = 0 ] || return 1
|
||||
_src_done="(DONE)"
|
||||
setDefault dest
|
||||
}
|
||||
|
||||
do_rdiff_dest() {
|
||||
declare -a tmp_array
|
||||
|
||||
set -o noglob
|
||||
REPLY=
|
||||
while [ -z "$REPLY" -o -z "$rdiff_directory" -o -z "$rdiff_host" -o -z "$rdiff_user" ]
|
||||
do
|
||||
formBegin "$rdiff_title - destination: last three items are required"
|
||||
formItem "keep" "$rdiff_keep"
|
||||
formItem "dest_directory" "$rdiff_directory"
|
||||
formItem "dest_host" "$rdiff_host"
|
||||
formItem "dest_user" "$rdiff_user"
|
||||
formItem "dest_type" "$rdiff_type"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return
|
||||
tmp_array=($REPLY)
|
||||
rdiff_keep=${tmp_array[0]}
|
||||
rdiff_directory=${tmp_array[1]}
|
||||
rdiff_host=${tmp_array[2]}
|
||||
rdiff_user=${tmp_array[3]}
|
||||
rdiff_type=${tmp_array[4]}
|
||||
done
|
||||
set +o noglob
|
||||
|
||||
_dest_done="(DONE)"
|
||||
setDefault conn
|
||||
}
|
||||
|
||||
do_rdiff_ssh_con() {
|
||||
local remote_status="ok"
|
||||
|
||||
IFS=$' \t\n'
|
||||
if [ "$_dest_done" = "" ]; then
|
||||
msgBox "$rdiff_title: error" "You must first configure the destination."
|
||||
return
|
||||
elif [ "$rdiff_type" = "" ]; then
|
||||
msgBox "$rdiff_title: error" "You must first configure the destination backup type."
|
||||
return
|
||||
elif [ "$rdiff_user" = "" ]; then
|
||||
msgBox "$rdiff_title: error" "You must first configure the destination user."
|
||||
return
|
||||
elif [ "$rdiff_host" = "" ]; then
|
||||
msgBox "$rdiff_title: error" "You must first configure the destination host."
|
||||
return
|
||||
else
|
||||
booleanBox "$rdiff_title" "This step will create a ssh key for the local root user with no passphrase (if one does not already exist), and attempt to copy root's public ssh key to authorized_keys file of $rdiff_user@$rdiff_host. This will allow the local root to make unattended backups to $rdiff_user@$rdiff_host.\n\n\nAre you sure you want to continue?"
|
||||
[ $? = 0 ] || return
|
||||
fi
|
||||
|
||||
if [ ! -f /root/.ssh/id_dsa.pub -a ! -f /root/.ssh/id_rsa.pub ]; then
|
||||
echo "Creating local root's ssh key"
|
||||
ssh-keygen -t dsa -f /root/.ssh/id_dsa -N ""
|
||||
echo "Done. hit return to continue"
|
||||
read
|
||||
fi
|
||||
|
||||
ssh -o PreferredAuthentications=publickey $rdiff_host -l $rdiff_user "exit" 2> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Copying root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host. When prompted, specify the password for user $rdiff_user@$rdiff_host."
|
||||
ssh-copy-id -i /root/.ssh/id_[rd]sa.pub $rdiff_user@$rdiff_host
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAILED: Couldn't copy root's public ssh key to authorized_keys of $rdiff_user@$rdiff_host."
|
||||
ssh $rdiff_user@$rdiff_host 'test -w .ssh || test -w .'
|
||||
result=$?
|
||||
echo "Hit return to continue."
|
||||
read
|
||||
case $result in
|
||||
0 ) msgBox "$rdiff_title: error" "Directories are writable: Probably just a typo the first time." ;;
|
||||
1 ) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but unable to write. Check ownership and modes of ~$rdiff_user on $rdiff_host." ;;
|
||||
255 ) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host." ;;
|
||||
* ) msgBox "$rdiff_title: error" "Unexpected error." ;;
|
||||
esac
|
||||
return
|
||||
else
|
||||
echo "Done. hit return to continue"
|
||||
read
|
||||
fi
|
||||
else
|
||||
echo "root@localhost is already in authorized_keys of $rdiff_user@$rdiff_host."
|
||||
echo "Hit return to continue."
|
||||
read
|
||||
fi
|
||||
|
||||
# test to see if the remote rdiff backup directory exists and is writable
|
||||
echo "Testing to see if remote rdiff backup directory exists and is writable"
|
||||
ssh $rdiff_user@$rdiff_host "test -d ${rdiff_directory}"
|
||||
if [ $? = 0 ]; then
|
||||
ssh $rdiff_user@$rdiff_host "test -w $rdiff_directory"
|
||||
if [ $? != 0 ]; then
|
||||
msgBox "destination directory is not writable!" "The remote destination directory is not writable by the user you specified. Please fix the permissions on the directory and then try again."
|
||||
remote_status=failed
|
||||
fi
|
||||
else
|
||||
booleanBox "Remote directory does not exist" "The destination backup directory does not exist, do you want me to create it for you?"
|
||||
if [ $? = 0 ]; then
|
||||
ssh $rdiff_user@$rdiff_host "mkdir -p ${rdiff_directory}"
|
||||
result=$?
|
||||
case $result in
|
||||
0) msgBox "$rdiff_title: success" "Creation of the remote destination directory was a success!";;
|
||||
1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to create the destination directory, check the directory permissions."
|
||||
remote_status=failed;;
|
||||
255) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host."
|
||||
remote_status=failed;;
|
||||
*) msgBox "$rdiff_title: error" "Unexpected error."
|
||||
remote_status=failed;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$remote_status" = "ok" ]; then
|
||||
do_rdiff_con
|
||||
fi
|
||||
}
|
||||
|
||||
do_rdiff_con() {
|
||||
echo "Checking for local install of rdiff-backup"
|
||||
require_packages rdiff-backup
|
||||
|
||||
echo "Testing to make sure destination has rdiff-backup installed and is compatible."
|
||||
remote_result=`/usr/bin/rdiff-backup --test-server $rdiff_user@$rdiff_host::/ 2>&1 >&-`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo $remote_result | grep -q "command not found"
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ "$rdiff_user" = "root" ]; then
|
||||
booleanBox "install rdiff-backup?" "It seems like the remote machine does not have rdiff-backup installed, I can attempt to install rdiff-backup on the remote machine.\n\n\nDo you want me to attempt this now?"
|
||||
if [ $? = 0 ]; then
|
||||
ssh $rdiff_user@$rdiff_host 'apt-get install rdiff-backup'
|
||||
result=$?
|
||||
echo "Hit return to continue."
|
||||
read
|
||||
case $result in
|
||||
0) msgBox "$rdiff_title: success" "Installation of rdiff-backup was a success!"
|
||||
do_rdiff_con;;
|
||||
1) msgBox "$rdiff_title: error" "Connected successfully to $rdiff_user@$rdiff_host, but was unable to install the package for some reason.";;
|
||||
255) msgBox "$rdiff_title: error" "Failed to connect to $rdiff_user@$rdiff_host. Check hostname, username, and password. Also, make sure sshd is running on the destination host.";;
|
||||
*) msgBox "$rdiff_title: error" "Unexpected error.";;
|
||||
esac
|
||||
return
|
||||
fi
|
||||
else
|
||||
booleanBox "install rdiff-backup" "Please install rdiff-backup on the remote machine, this cannot be done automatically, as the remote user in your configuration is not root. \n\nIf you have installed rdiff-backup on the remote machine and you are getting this error, then there is a version incompatibility between that version and the local version.\n\nPlease resolve this problem and then try connecting again.\n\n\n\nTry connecting again?"
|
||||
if [ $? = 0 ]; then
|
||||
do_rdiff_con
|
||||
else
|
||||
return
|
||||
fi
|
||||
fi
|
||||
else
|
||||
msgBox "incompatible versions of rdiff-backup" "It looks like rdiff-backup is installed on the remote machine, but it may be an incompatible version with the one installed locally, or something else is amiss.\n\nPlease resolve this problem and then try connecting again.\n\n\nTry connecting again?"
|
||||
if [ $? = 0 ]; then
|
||||
do_rdiff_con
|
||||
else
|
||||
return
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "SUCCESS: Everything looks good!"
|
||||
echo "Hit return to continue."
|
||||
read
|
||||
fi
|
||||
|
||||
_con_done="(DONE)"
|
||||
setDefault finish
|
||||
}
|
||||
|
||||
do_rdiff_finish() {
|
||||
get_next_filename $configdirectory/90.rdiff
|
||||
cat > $next_filename <<EOF
|
||||
# options = --force
|
||||
# when = everyday at 02
|
||||
|
||||
[source]
|
||||
type = local
|
||||
keep = $rdiff_keep
|
||||
|
||||
# A few notes about includes and excludes:
|
||||
# 1. include, exclude and vsinclude statements support globbing with '*'
|
||||
# 2. Symlinks are not dereferenced. Moreover, an include line whose path
|
||||
# contains, at any level, a symlink to a directory, will only have the
|
||||
# symlink backed-up, not the target directory's content. Yes, you have to
|
||||
# dereference yourself the symlinks, or to use 'mount --bind' instead.
|
||||
# Example: let's say /home is a symlink to /mnt/crypt/home ; the following
|
||||
# line will only backup a "/home" symlink ; neither /home/user nor
|
||||
# /home/user/Mail will be backed-up :
|
||||
# include = /home/user/Mail
|
||||
# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to
|
||||
# write :
|
||||
# include = /mnt/crypt/home/user/Mail
|
||||
# 3. All the excludes come after all the includes. The order is not otherwise
|
||||
# taken into account.
|
||||
|
||||
# files to include in the backup
|
||||
EOF
|
||||
## includes ##
|
||||
if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
|
||||
set -o noglob
|
||||
for ((i=0; i < ${#rdiff_includes[@]} ; i++)); do
|
||||
echo "include = ${rdiff_includes[$i]}" >> $next_filename
|
||||
done
|
||||
set +o noglob
|
||||
fi
|
||||
|
||||
if [ "$host_or_vservers" == vservers -o "$host_or_vservers" == both ]; then
|
||||
cat >> $next_filename <<EOF
|
||||
#
|
||||
# If vservers = yes in /etc/backupninja.conf then the following variables can
|
||||
# be used:
|
||||
# vsnames = all | <vserver1> <vserver2> ... (default = all)
|
||||
# vsinclude = <path>
|
||||
# vsinclude = <path>
|
||||
# ...
|
||||
# Any path specified in vsinclude is added to the include list for each vserver
|
||||
# listed in vsnames (or all if vsnames = all, which is the default).
|
||||
#
|
||||
# For example, vsinclude = /home will backup the /home directory in every
|
||||
# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this
|
||||
# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
|
||||
# and /vservers/baz/home.
|
||||
# Vservers paths are derived from $VROOTDIR.
|
||||
|
||||
EOF
|
||||
set -o noglob
|
||||
echo -e "vsnames = $selected_vservers\n" >> $next_filename
|
||||
for i in $rdiff_vsincludes; do
|
||||
echo "vsinclude = $i" >> $next_filename
|
||||
done
|
||||
set +o noglob
|
||||
fi
|
||||
|
||||
## excludes ##
|
||||
set -o noglob
|
||||
for ((i=0; i < ${#rdiff_excludes[@]} ; i++)); do
|
||||
echo exclude = ${rdiff_excludes[$i]} >> $next_filename
|
||||
done
|
||||
set +o noglob
|
||||
cat >> $next_filename <<EOF
|
||||
|
||||
######################################################
|
||||
## destination section
|
||||
## (where the files are copied to)
|
||||
|
||||
[dest]
|
||||
type = remote
|
||||
directory = $rdiff_directory
|
||||
host = $rdiff_host
|
||||
user = $rdiff_user
|
||||
EOF
|
||||
|
||||
chmod 600 $next_filename
|
||||
}
|
||||
|
||||
rdiff_main_menu() {
|
||||
while true; do
|
||||
srcitem="choose files to include & exclude $_src_done"
|
||||
destitem="configure backup destination $_dest_done"
|
||||
conitem="set up ssh keys and test remote connection $_con_done"
|
||||
advitem="edit advanced settings $_adv_done"
|
||||
menuBox "$rdiff_title" "choose a step:" \
|
||||
src "$srcitem" \
|
||||
dest "$destitem" \
|
||||
conn "$conitem" \
|
||||
finish "finish and create config file"
|
||||
[ $? = 0 ] || return
|
||||
result="$REPLY"
|
||||
case "$result" in
|
||||
"src") do_rdiff_src;;
|
||||
"dest") do_rdiff_dest;;
|
||||
"conn") do_rdiff_ssh_con;;
|
||||
"adv") do_rdiff_adv;;
|
||||
"finish")
|
||||
if [[ "$_con_done$_dest_done$_src_done" != "(DONE)(DONE)(DONE)" ]]; then
|
||||
msgBox "$rdiff_title" "You cannot create the configuration file until the other steps are completed."
|
||||
else
|
||||
do_rdiff_finish
|
||||
return
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
rdiff_wizard() {
|
||||
|
||||
# Global variables
|
||||
rdiff_title="rdiff-backup action wizard"
|
||||
_src_done=
|
||||
_dest_done=
|
||||
_con_done=
|
||||
_adv_done=
|
||||
rdiff_keep=60D
|
||||
rdiff_directory=/backup/`hostname`
|
||||
rdiff_type=remote
|
||||
rdiff_user=
|
||||
rdiff_host=
|
||||
|
||||
# Global variables whose '*' shall not be expanded
|
||||
set -o noglob
|
||||
rdiff_includes=(/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*)
|
||||
rdiff_excludes=(/home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads)
|
||||
rdiff_vsincludes=
|
||||
set +o noglob
|
||||
|
||||
rdiff_main_menu
|
||||
}
|
||||
|
@ -1,257 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# rdiff-backup handler script for backupninja
|
||||
# requires rdiff-backup
|
||||
#
|
||||
|
||||
### FUNCTIONS ###
|
||||
|
||||
function test_connection() {
|
||||
# given a user and host,
|
||||
# tests the connection.
|
||||
# if user or host is missing, returns 0
|
||||
# (ie, assume it's a local connection).
|
||||
if [ $# -lt 2 ]; then
|
||||
debug "(local is assumed to be a good connection)"
|
||||
return 0
|
||||
fi
|
||||
local user=$1
|
||||
local host=$2
|
||||
debug "ssh $sshoptions -o PasswordAuthentication=no $host -l $user 'echo -n 1'"
|
||||
local ret=`ssh $sshoptions -o PasswordAuthentication=no $host -l $user 'echo -n host is alive'`
|
||||
if echo $ret | grep "host is alive"; then
|
||||
debug "Connected to $host as $user successfully"
|
||||
else
|
||||
fatal "Can't connect to $host as $user."
|
||||
fi
|
||||
}
|
||||
|
||||
function get_version() {
|
||||
# given no arguments, returns the local version.
|
||||
# given a user and host, returns the remote version.
|
||||
# if user or host is missing, returns the local version.
|
||||
if [ "$#" -lt 2 ]; then
|
||||
debug "$RDIFFBACKUP -V"
|
||||
echo `$RDIFFBACKUP -V`
|
||||
else
|
||||
local user=$1
|
||||
local host=$2
|
||||
debug "ssh $sshoptions $host -l $user '$RDIFFBACKUP -V'"
|
||||
echo `ssh $sshoptions $host -l $user "$RDIFFBACKUP -V | grep rdiff-backup"`
|
||||
fi
|
||||
}
|
||||
|
||||
function check_consistency() {
|
||||
local section=$1
|
||||
local type=$2
|
||||
local user=$3
|
||||
local host=$4
|
||||
if [ "$type" == "local" ]; then
|
||||
if [ "$user" != "" ]; then
|
||||
warning "User should not be specified for local $section."
|
||||
fi
|
||||
if [ "$host" != "" ]; then
|
||||
warning "Host should not be specified for local $section."
|
||||
fi
|
||||
fi
|
||||
if [ "$type" == "remote" ]; then
|
||||
if [ "$user" == "" ]; then
|
||||
fatal "User must be specified for remote $section."
|
||||
fi
|
||||
if [ "host" == "" ]; then
|
||||
fatal "Host must be specifed for remote $section."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function check_cstream() {
|
||||
local cstream=$1
|
||||
if [ ! -x $cstream ]; then
|
||||
fatal "Can't find your cstream binary (trying: $cstream). If you use bwlimit you must have cstream installed."
|
||||
fi
|
||||
}
|
||||
|
||||
### GET CONFIG ###
|
||||
|
||||
getconf options
|
||||
getconf testconnect yes
|
||||
getconf nicelevel 0
|
||||
getconf bwlimit
|
||||
getconf ignore_version no
|
||||
|
||||
setsection source
|
||||
getconf type; sourcetype=$type
|
||||
getconf user; sourceuser=$user
|
||||
getconf host; sourcehost=$host
|
||||
check_consistency "source" "$type" "$user" "$host"
|
||||
getconf label
|
||||
getconf keep 60
|
||||
getconf include
|
||||
getconf vsnames all
|
||||
getconf vsinclude
|
||||
getconf exclude
|
||||
|
||||
setsection dest
|
||||
getconf directory; destdir=$directory
|
||||
# strip trailing /
|
||||
destdir=${destdir%/}
|
||||
getconf type; desttype=$type
|
||||
getconf user; destuser=$user
|
||||
getconf host; desthost=$host
|
||||
getconf sshoptions
|
||||
check_consistency "destination" "$type" "$user" "$host"
|
||||
|
||||
if [ -n "$sshoptions" ] && echo $options | grep -qv "remote-schema"; then
|
||||
options="$options --remote-schema 'ssh -C $sshoptions %s rdiff-backup --server'"
|
||||
fi
|
||||
|
||||
### CHECK CONFIG ###
|
||||
|
||||
# If vservers are configured, check that the ones listed in $vsnames do exist.
|
||||
local usevserver=no
|
||||
if [ $vservers_are_available = yes ]; then
|
||||
if [ "$vsnames" = all ]; then
|
||||
vsnames="$found_vservers"
|
||||
else
|
||||
if ! vservers_exist "$vsnames" ; then
|
||||
fatal "At least one of the vservers listed in vsnames ($vsnames) does not exist."
|
||||
fi
|
||||
fi
|
||||
if [ -n "$vsinclude" ]; then
|
||||
info "Using vservers '$vsnames'"
|
||||
usevserver=yes
|
||||
fi
|
||||
else
|
||||
[ -z "$vsinclude" ] || warning 'vservers support disabled in backupninja.conf, vsincludes configuration lines will be ignored'
|
||||
fi
|
||||
|
||||
# check the connection at the source and destination
|
||||
[ -n "$test" ] || test=0
|
||||
if [ "$testconnect" = "yes" ] || [ "${test}" -eq 1 ]; then
|
||||
test_connection $sourceuser $sourcehost
|
||||
test_connection $destuser $desthost
|
||||
fi
|
||||
|
||||
if [ "$ignore_version" != "yes" ]; then
|
||||
# see that rdiff-backup has the same version at the source and destination
|
||||
sourceversion=`get_version $sourceuser $sourcehost`
|
||||
destversion=`get_version $destuser $desthost`
|
||||
if [ "$sourceversion" != "$destversion" ]; then
|
||||
fatal "rdiff-backup does not have the same version at the source and at the destination."
|
||||
fi
|
||||
fi
|
||||
|
||||
# source specific checks
|
||||
case $sourcetype in
|
||||
remote ) execstr_sourcepart="$sourceuser@$sourcehost::/" ;;
|
||||
local ) execstr_sourcepart="/" ;;
|
||||
* ) fatal "sourcetype '$sourcetype' is neither local nor remote" ;;
|
||||
esac
|
||||
|
||||
# destination specific checks
|
||||
[ "$destdir" != "" ] || fatal "Destination directory not set"
|
||||
case $desttype in
|
||||
remote ) execstr_destpart="$destuser@$desthost::$destdir/$label" ;;
|
||||
local ) execstr_destpart="$destdir/$label" ;;
|
||||
* ) fatal "desttype '$desttype' is neither local nor remote" ;;
|
||||
esac
|
||||
|
||||
### REMOVE OLD BACKUPS ###
|
||||
|
||||
if [ "$keep" != yes ]; then
|
||||
|
||||
if [ "`echo $keep | tr -d 0-9`" == "" ]; then
|
||||
# add D if no other date unit is specified
|
||||
keep="${keep}D"
|
||||
fi
|
||||
|
||||
removestr="$RDIFFBACKUP $options --force --remove-older-than $keep "
|
||||
if [ "$desttype" == "remote" ]; then
|
||||
removestr="${removestr}${destuser}@${desthost}::"
|
||||
fi
|
||||
removestr="${removestr}${destdir}/${label}";
|
||||
|
||||
debug "$removestr"
|
||||
if [ $test = 0 ]; then
|
||||
output="`su -c "$removestr" 2>&1`"
|
||||
if [ $? = 0 ]; then
|
||||
debug $output
|
||||
info "Removing backups older than $keep days succeeded."
|
||||
else
|
||||
warning $output
|
||||
warning "Failed removing backups older than $keep."
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Add cstream
|
||||
|
||||
if [ ! -z $bwlimit ]; then
|
||||
check_cstream $CSTREAM;
|
||||
if [ "$desttype" = "remote" ]; then
|
||||
RDIFFBACKUP="$RDIFFBACKUP --remote-schema 'cstream -t $bwlimit | ssh %s \''rdiff-backup --server\'''"
|
||||
elif [ "$sourcetype" = "remote" ]; then
|
||||
RDIFFBACKUP="$RDIFFBACKUP --remote-schema 'ssh %s \''rdiff-backup --server\'' | cstream -t $bwlimit'"
|
||||
else
|
||||
fatal "You specified a bandwidth limit but neither your source nor destination types are remote."
|
||||
fi
|
||||
fi
|
||||
|
||||
### EXECUTE ###
|
||||
|
||||
execstr="$RDIFFBACKUP $options --print-statistics "
|
||||
|
||||
set -o noglob
|
||||
|
||||
symlinks_warning="Maybe you have mixed symlinks and '*' in this statement, which is not supported."
|
||||
|
||||
# TODO: order the includes and excludes
|
||||
# excludes
|
||||
for i in $exclude; do
|
||||
str="${i//__star__/*}"
|
||||
execstr="${execstr}--exclude '$str' "
|
||||
done
|
||||
# includes
|
||||
for i in $include; do
|
||||
[ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
|
||||
str="${i//__star__/*}"
|
||||
execstr="${execstr}--include '$str' "
|
||||
done
|
||||
|
||||
# vsinclude
|
||||
if [ $usevserver = yes ]; then
|
||||
for vserver in $vsnames; do
|
||||
for vi in $vsinclude; do
|
||||
str="${vi//__star__/*}"
|
||||
str="$VROOTDIR/$vserver$str"
|
||||
if [ -n "$str" ]; then
|
||||
execstr="${execstr}--include '$str' "
|
||||
else
|
||||
warning "vsinclude statement '${vi//__star__/*}' will be ignored for VServer $vserver. $symlinks_warning"
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
set +o noglob
|
||||
|
||||
# exclude everything else
|
||||
[ "$include" != "" -o "$vsinclude" != "" ] && execstr="${execstr}--exclude '/*' "
|
||||
|
||||
# include client-part and server-part
|
||||
execstr="${execstr}$execstr_sourcepart $execstr_destpart"
|
||||
|
||||
debug "$execstr"
|
||||
if [ $test = 0 ]; then
|
||||
output=`nice -n $nicelevel su -c "$execstr" 2>&1`
|
||||
if [ $? = 0 ]; then
|
||||
debug $output
|
||||
info "Successfully finished backing up source $label"
|
||||
else
|
||||
warning $output
|
||||
warning "Failed backup up source $label"
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
@ -1,350 +0,0 @@
|
||||
#
|
||||
# backupninja handler to do incremental backups using
|
||||
# rsync and hardlinks, based on
|
||||
#
|
||||
# http://www.mikerubel.org/computers/rsync_snapshots/
|
||||
#
|
||||
# feedback: rhatto at riseup.net | gpl
|
||||
# lot of enhancements grabbed from "rsnap" handler by paulv at bikkel.org
|
||||
#
|
||||
# Config file options
|
||||
# -------------------
|
||||
#
|
||||
# [general]
|
||||
# log = rsync log file
|
||||
# partition = partition where the backup lives
|
||||
# fscheck = set to 1 if fsck should run on $partition after the backup is made
|
||||
# read_only = set to 1 if $partition is mounted read-only
|
||||
# mountpoint = backup partition mountpoint or backup main folder
|
||||
# backupdir = folder relative do $mountpoint where the backup should be stored
|
||||
# days = number of backup increments (min = 5)
|
||||
# lockfile = lockfile to be kept during backup execution
|
||||
# nicelevel = rsync command nice level
|
||||
# enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly
|
||||
# tmp = temp folder
|
||||
#
|
||||
# [source]
|
||||
# from = local or remote
|
||||
# host = source hostname or ip, if remote backup
|
||||
# testconnect = when "yes", test the connection for a remote source before backup
|
||||
# include = include folder on backup
|
||||
# exclude = exclude folder on backup
|
||||
# ssh = ssh command line (remote only)
|
||||
# rsync = rsync program
|
||||
# rsync_options = rsync command options
|
||||
# exclude_vserver = vserver-name (valid only if vservers = yes on backupninja.conf)
|
||||
# numericids = when set to 1, use numeric ids instead of user/group mappings on rsync
|
||||
# compress = if set to 1, compress data on rsync (remote source only)
|
||||
# bandwidthlimit = set a badnwidth limit in kbps (remote source only)
|
||||
# remote_rsync = remote rsync program (remote source only)
|
||||
#
|
||||
# [services]
|
||||
# initscripts = absolute path where scripts are located
|
||||
# service = script name to be stoped at the begining of the backup and started at its end
|
||||
#
|
||||
# You can also specify some system comands if you don't want the default system values:
|
||||
#
|
||||
# [system]
|
||||
# rm = rm command
|
||||
# cp = cp command
|
||||
# touch = touch command
|
||||
# mv = mv command
|
||||
# fsck = fsck command
|
||||
#
|
||||
# You dont need to manually specify vservers using "include = /vservers".
|
||||
# They are automatically backuped if vserver is set to "yes" on you backupninja.conf.
|
||||
#
|
||||
|
||||
# config file evaluation
|
||||
|
||||
setsection system
|
||||
getconf rm rm
|
||||
getconf cp cp
|
||||
getconf touch touch
|
||||
getconf mv mv
|
||||
getconf fsck fsck
|
||||
|
||||
setsection general
|
||||
getconf log /var/log/backup/rsync.log
|
||||
getconf partition
|
||||
getconf fscheck
|
||||
getconf read_only
|
||||
getconf mountpoint
|
||||
getconf backupdir
|
||||
getconf rotate
|
||||
getconf days
|
||||
getconf lockfile
|
||||
getconf nicelevel 0
|
||||
getconf enable_mv_timestamp_bug no
|
||||
getconf tmp /tmp
|
||||
|
||||
setsection source
|
||||
getconf from local
|
||||
getconf testconnect no
|
||||
getconf rsync $RSYNC
|
||||
getconf rsync_options "-av --delete"
|
||||
getconf ssh ssh
|
||||
getconf user
|
||||
getconf host
|
||||
getconf include
|
||||
getconf exclude
|
||||
getconf exclude_vserver
|
||||
getconf numericids 0
|
||||
getconf compress 0
|
||||
getconf bandwidthlimit
|
||||
getconf remote_rsync rsync
|
||||
|
||||
setsection services
|
||||
getconf initscripts
|
||||
getconf service
|
||||
|
||||
# function definitions
|
||||
|
||||
function rotate {
|
||||
|
||||
if [[ "$2" < 4 ]]; then
|
||||
error "Rotate: minimum of 4 rotations"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d $1.$2 ]; then
|
||||
$nice $mv /$1.$2 /$1.tmp
|
||||
fi
|
||||
|
||||
for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do
|
||||
if [ -d $1.$n ]; then
|
||||
dest=`echo "$n + 1" | bc`
|
||||
$nice $mv /$1.$n /$1.$dest
|
||||
$touch /$1.$dest
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -d $1.tmp ]; then
|
||||
$nice $mv /$1.tmp /$1.0
|
||||
fi
|
||||
|
||||
if [ -d $1.1 ]; then
|
||||
$nice $cp -alf /$1.1/. /$1.0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function move_files {
|
||||
|
||||
ref=$tmp/makesnapshot-mymv-$$;
|
||||
$touch -r $1 $ref;
|
||||
$mv $1 $2;
|
||||
$touch -r $ref $2;
|
||||
$rm $ref;
|
||||
|
||||
}
|
||||
|
||||
backupdir="$mountpoint/$backupdir"
|
||||
|
||||
# does $backupdir exists?
|
||||
|
||||
if [ ! -d "$backupdir" ]; then
|
||||
error "Backupdir $backupdir does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# setup number of increments
|
||||
|
||||
if [ -z "$days" ]; then
|
||||
keep="4"
|
||||
else
|
||||
keep="`echo $days - 1 | bc -l`"
|
||||
fi
|
||||
|
||||
# lockfile setup
|
||||
|
||||
if [ ! -z "$lockfile" ]; then
|
||||
$touch $lockfile || warning "Could not create lockfile $lockfile"
|
||||
fi
|
||||
|
||||
# nicelevel setup
|
||||
|
||||
if [ ! -z "$nicelevel" ]; then
|
||||
nice="nice -n $nicelevel"
|
||||
else
|
||||
nice=""
|
||||
fi
|
||||
|
||||
# connection test
|
||||
|
||||
if [ "$from" == "remote" ] && [ "$testconnect" == "yes" ]; then
|
||||
debug "$ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'"
|
||||
result=`ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'`
|
||||
if [ "$result" != "1" ]; then
|
||||
fatal "Can't connect to $host as $user."
|
||||
else
|
||||
debug "Connected to $srchost successfully"
|
||||
fi
|
||||
fi
|
||||
|
||||
# rsync options for local sources
|
||||
|
||||
if [ "$from" == "local" ]; then
|
||||
|
||||
rsync_local_options="$rsync_options"
|
||||
|
||||
if [ ! -z "$numericids" ]; then
|
||||
rsync_local_options="$rsync_local_options --numeric-ids "
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# rsync options for remote sources
|
||||
|
||||
if [ "$from" == "remote" ]; then
|
||||
|
||||
rsync_remote_options="$rsync_options --rsync-path=$remote_rsync"
|
||||
|
||||
if [ "$compress" == "1" ]; then
|
||||
rsync_remote_options="$rsync_remote_options --compress"
|
||||
fi
|
||||
|
||||
if [ ! -z "$bandwidthlimit" ]; then
|
||||
rsync_remote_options="$rsync_remote_options --bwlimit=$bandwidthlimit"
|
||||
fi
|
||||
|
||||
if [ ! -z "$numericids" ]; then
|
||||
rsync_remote_options="$rsync_remote_options --numeric-ids"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# set mv procedure
|
||||
|
||||
if [ $enable_mv_timestamp_bug == "yes" ]; then
|
||||
mv=move_files
|
||||
fi
|
||||
|
||||
# set excludes
|
||||
|
||||
for path in $exclude; do
|
||||
EXCLUDES="$EXCLUDES --exclude=$path"
|
||||
done
|
||||
|
||||
# stop services
|
||||
|
||||
if [ ! -z "$service" ]; then
|
||||
for daemon in $service; do
|
||||
info "Stopping service $daemon..."
|
||||
$initscripts/$daemon stop
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Starting backup at `date`" >> $log
|
||||
|
||||
# mount backup destination folder as read-write
|
||||
|
||||
if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
|
||||
if [ -d "$mountpoint" ]; then
|
||||
mount -o remount,rw $mountpoint
|
||||
if (($?)); then
|
||||
error "Could not mount $mountpoint"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# add vservers to included folders
|
||||
|
||||
if [ "$vservers_are_available" == "yes" ]; then
|
||||
|
||||
# sane permission on backup
|
||||
mkdir -p $backupdir/$VROOTDIR
|
||||
chmod 000 $backupdir/$VROOTDIR
|
||||
|
||||
for candidate in $found_vservers; do
|
||||
candidate="`basename $candidate`"
|
||||
found_excluded_vserver="0"
|
||||
for excluded_vserver in $exclude_vserver; do
|
||||
if [ "$excluded_vserver" == "$candidate" ]; then
|
||||
found_excluded_vserver="1"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$found_excluded_vserver" == "0" ]; then
|
||||
include="$include $VROOTDIR/$candidate"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# the backup procedure
|
||||
|
||||
for SECTION in $include; do
|
||||
|
||||
section="`basename $SECTION`"
|
||||
|
||||
if [ ! -d "$backupdir/$SECTION/$section.0" ]; then
|
||||
mkdir -p $backupdir/$SECTION/$section.0
|
||||
fi
|
||||
|
||||
info "Rotating $backupdir/$SECTION/$section..."
|
||||
echo "Rotating $backupdir/$SECTION/$section..." >> $log
|
||||
rotate $backupdir/$SECTION/$section $keep
|
||||
info "Syncing $SECTION on $backupdir/$SECTION/$section.0..."
|
||||
|
||||
if [ "$from" == "local" ]; then
|
||||
debug $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/
|
||||
$nice $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ >> $log
|
||||
if [ "$?" != "0" ]; then
|
||||
warning "Rsync error when trying to transfer $SECTION"
|
||||
fi
|
||||
elif [ "$from" == "remote" ]; then
|
||||
if [ -z "$user" ] || [ -z "$host" ]; then
|
||||
error "Config file error: either user or host was not specified"
|
||||
exit 1
|
||||
else
|
||||
debug $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0
|
||||
$nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 >> $log
|
||||
if [ "$?" != "0" ]; then
|
||||
warning "Rsync error when trying to transfer $SECTION"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
error "Invalid source $from"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$touch $backupdir/$SECTION/$section.0
|
||||
|
||||
done
|
||||
|
||||
# remount backup destination as read-only
|
||||
|
||||
if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
|
||||
mount -o remount,ro $mountpoint
|
||||
fi
|
||||
|
||||
# check partition for errors
|
||||
|
||||
if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then
|
||||
umount $mountpoint
|
||||
if (($?)); then
|
||||
warning "Could not umount $mountpoint to run fsck"
|
||||
else
|
||||
$nice $fsck -v -y $partition >> $log
|
||||
mount $mountpoint
|
||||
fi
|
||||
fi
|
||||
|
||||
# restart services
|
||||
|
||||
if [ ! -z "$service" ]; then
|
||||
for daemon in $service; do
|
||||
info "Starting service $daemon..."
|
||||
$initscripts/$daemon start
|
||||
done
|
||||
fi
|
||||
|
||||
# removes the lockfile
|
||||
|
||||
if [ ! -z "$lockfile" ]; then
|
||||
$rm $lockfile || warning "Could not remove lockfile $lockfile"
|
||||
fi
|
||||
|
||||
echo "Finnishing backup at `date`" >> $log
|
||||
|
@ -1,7 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# shell script handler for backupninja
|
||||
# runs the file /etc/backup.d/scriptname.sh
|
||||
#
|
||||
|
||||
[ $test ] || ( . $1 )
|
@ -1,77 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# this handler will backup subversion repostitories.
|
||||
#
|
||||
|
||||
getconf src /var/lib/svn
|
||||
getconf dest /var/backups/svn
|
||||
getconf tmp /var/backups/svn.tmp
|
||||
getconf HOTBACKUP "/usr/bin/svnadmin hotcopy"
|
||||
getconf vsname
|
||||
|
||||
error=0
|
||||
|
||||
# Decide if the handler should operate on a vserver or on the host.
|
||||
# In the former case, check that $vsname exists and is running.
|
||||
local usevserver=no
|
||||
local vroot
|
||||
if [ $vservers_are_available = yes ]; then
|
||||
if [ -n "$vsname" ]; then
|
||||
# does it exist ?
|
||||
if ! vservers_exist "$vsname" ; then
|
||||
fatal "The vserver given in vsname ($vsname) does not exist."
|
||||
fi
|
||||
# is it running ?
|
||||
vservers_running $vsname || fatal "The vserver $vsname is not running."
|
||||
# everything ok
|
||||
info "Using vserver '$vsname'."
|
||||
usevserver=yes
|
||||
vroot="$VROOTDIR/$vsname"
|
||||
else
|
||||
info "No vserver name specified, actions will be performed on the host."
|
||||
fi
|
||||
fi
|
||||
|
||||
cd $vroot$src
|
||||
for repo in `find . -name svnserve.conf`
|
||||
do
|
||||
repo=`dirname $repo`
|
||||
repo=`dirname $repo`
|
||||
|
||||
ret=`mkdir -p $vroot$tmp/$repo 2>&1`
|
||||
code=$?
|
||||
if [ "$ret" ]; then
|
||||
debug "$ret"
|
||||
fi
|
||||
if [ $code != 0 ]; then
|
||||
error "command failed mkdir -p $vroot$tmp/$repo"
|
||||
fi
|
||||
|
||||
if [ $usevserver = yes ]
|
||||
then
|
||||
ret=`$VSERVER $vsname exec $HOTBACKUP $src/$repo $tmp/$repo 2>&1`
|
||||
else
|
||||
ret=`$HOTBACKUP $src/$repo $tmp/$repo 2>&1`
|
||||
fi
|
||||
code=$?
|
||||
if [ "$ret" ]; then
|
||||
debug "$ret"
|
||||
fi
|
||||
if [ $code != 0 ]; then
|
||||
error "command failed -- $HOTBACKUP $vroot$src/$repo $vroot$tmp/$repo"
|
||||
error=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $error -eq 1 ]; then
|
||||
echo "Error: because of earlier errors, we are leaving svn backups in $vroot$tmp instead of $vroot$dest"
|
||||
else
|
||||
if [ -d $vroot$dest -a -d $vroot$tmp ]; then
|
||||
rm -rf $vroot$dest
|
||||
fi
|
||||
if [ -d $vroot$tmp ]; then
|
||||
mv $vroot$tmp $vroot$dest
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,53 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS sys:general_hardware_and_system_info"
|
||||
|
||||
sys_wizard() {
|
||||
require_packages hwinfo debconf-utils
|
||||
checkBox "new sys action" "check options" \
|
||||
"packages" "list of all installed packages." on \
|
||||
"partitions" "the partition table of all disks." on \
|
||||
"sfdisk" "use sfdisk to get partition information." on \
|
||||
"hardware" "detailed hardware information" on \
|
||||
"luksheaders" "Luks headers of all Luks partitions." off \
|
||||
"lvm" "LVM metadata for all volume groups." off
|
||||
[ $? = 1 ] && return;
|
||||
result="$REPLY"
|
||||
packages="packages = no"
|
||||
partitions="partitions = no"
|
||||
sfdisk="dosfdisk = no"
|
||||
hardware="hardware = no"
|
||||
luksheaders="luksheaders = no"
|
||||
lvm="lvm = no"
|
||||
for opt in $result; do
|
||||
case $opt in
|
||||
'"packages"') packages="packages = yes";;
|
||||
'"partitions"') partitions="partitions = yes";;
|
||||
'"sfdisk"') sfdisk="dosfdisk = yes";;
|
||||
'"hardware"') hardware="hardware = yes";;
|
||||
'"luksheaders"') luksheaders="luksheaders = yes";;
|
||||
'"lvm"') lvm="lvm = yes";;
|
||||
esac
|
||||
done
|
||||
get_next_filename $configdirectory/10.sys
|
||||
cat > $next_filename <<EOF
|
||||
$packages
|
||||
$partitions
|
||||
$sfdisk
|
||||
$hardware
|
||||
$luksheaders
|
||||
$lvm
|
||||
|
||||
# packagesfile = /var/backups/dpkg-selections.txt
|
||||
# selectionsfile = /var/backups/debconfsel.txt
|
||||
# partitionsfile = /var/backups/partitions.__star__.txt
|
||||
# hardwarefile = /var/backups/hardware.txt
|
||||
# luksheadersfile = /var/backups/luksheader.__star__.bin
|
||||
|
||||
# If vservers = yes in /etc/backupninja.conf then the following variables can
|
||||
# be used:
|
||||
# vsnames = all | <vserver1> <vserver2> ... (default = all)
|
||||
EOF
|
||||
chmod 600 $next_filename
|
||||
}
|
||||
|
682
handlers/sys.in
682
handlers/sys.in
@ -1,682 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# this handler will save various reports of vital system information.
|
||||
# by default, all the reports are saved in /var/backups.
|
||||
#
|
||||
# (1) a capture of the debconf package selection states. This file
|
||||
# can be used to restore the answers to debconf questions for
|
||||
# packages that you will be installing through (2) below. To
|
||||
# do this, run: "debconf-set-selections < debconfsel.txt"
|
||||
#
|
||||
# (2) a list of all the packages installed and removed.
|
||||
# this file can be used to restore the state of installed packages
|
||||
# by running "dpkg --set-selections < dpkg-selections.txt and
|
||||
# then run "apt-get -u dselect-upgrade". If you have the
|
||||
# debconf-set-selections file from (1), you should restore those first.
|
||||
#
|
||||
# (3) the partition table of all disks.
|
||||
# this partition table can be used to format another disk of
|
||||
# the same size. this can be handy if using software raid and
|
||||
# you have a disk go bad. just replace the disk and partition it
|
||||
# by running "sfdisk /dev/sdb < partitions.sdb.txt"
|
||||
# (MAKE SURE YOU PARTITION THE CORRECT DISK!!!)
|
||||
#
|
||||
# (4) hardware information.
|
||||
# write to a text file the important things which hwinfo can gleen.
|
||||
#
|
||||
# (5) the Luks header of every Luks block device, if option luksheaders
|
||||
# is enabled.
|
||||
# in case you (have to) scramble such a Luks header (for some time),
|
||||
# and restore it later by running "dd if=luksheader.sda2.bin of=/dev/sda2"
|
||||
# (MAKE SURE YOU PASS THE CORRECT DEVICE AS of= !!!)
|
||||
#
|
||||
# (6) LVM metadata for every detected volume group, if "lvm = yes"
|
||||
#
|
||||
|
||||
if [ -f /etc/debian_version ]
|
||||
then
|
||||
os=debian
|
||||
debug "Debian detected"
|
||||
osversion="/etc/debian_version"
|
||||
elif [ -f /etc/redhat-release ]
|
||||
then
|
||||
os=redhat
|
||||
debug "Redhat detected"
|
||||
osversion="/etc/redhat-release"
|
||||
else
|
||||
warning "Unknown OS detected!"
|
||||
fi
|
||||
|
||||
getconf parentdir /var/backups
|
||||
getconf packages yes
|
||||
getconf dosfdisk yes
|
||||
getconf dohwinfo yes
|
||||
|
||||
if [ ! -d $parentdir ]; then
|
||||
mkdir -p $parentdir
|
||||
fi
|
||||
|
||||
if [ $os = "debian" ]
|
||||
then
|
||||
getconf packagesfile $parentdir/dpkg-selections.txt
|
||||
getconf packagemgr `which dpkg`
|
||||
getconf packagemgroptions ' --get-selections *'
|
||||
getconf selectionsfile $parentdir/debconfsel.txt
|
||||
getconf debconfgetselections `which debconf-get-selections`
|
||||
elif [ $os = "redhat" ]
|
||||
then
|
||||
getconf packagesfile $parentdir/rpmpackages.txt
|
||||
getconf packagemgr `which rpm`
|
||||
getconf packagemgroptions ' -qa '
|
||||
|
||||
getconf SYSREPORT `which sysreport`
|
||||
getconf sysreport_options ' -norpm '
|
||||
else
|
||||
getconf packagesfile $parentdir/unknownOS.txt
|
||||
fi
|
||||
packagemgroptions="${packagemgroptions//__star__/*}"
|
||||
|
||||
getconf partitions yes
|
||||
getconf partitionsfile $parentdir/partitions.__star__.txt
|
||||
|
||||
getconf hardware yes
|
||||
getconf hardwarefile $parentdir/hardware.txt
|
||||
|
||||
getconf sysreport yes
|
||||
getconf sysreportfile $parentdir/sysreport.txt
|
||||
|
||||
getconf SFDISK `which sfdisk`
|
||||
getconf HWINFO `which hwinfo`
|
||||
getconf sfdisk_options ""
|
||||
getconf hwinfo_options ""
|
||||
|
||||
getconf CRYPTSETUP `which cryptsetup`
|
||||
getconf DD `which dd`
|
||||
getconf luksheaders no
|
||||
getconf luksheadersfile $parentdir/luksheader.__star__.bin
|
||||
|
||||
getconf VGS `which vgs`
|
||||
getconf VGCFGBACKUP `which vgcfgbackup`
|
||||
getconf lvm no
|
||||
|
||||
getconf vsnames all
|
||||
|
||||
# If vservers are configured, check that the ones listed in $vsnames are running.
|
||||
local usevserver=no
|
||||
if [ $vservers_are_available = yes ]; then
|
||||
if [ "$vsnames" = all ]; then
|
||||
vsnames="$found_vservers"
|
||||
fi
|
||||
if ! vservers_running "$vsnames" ; then
|
||||
fatal "At least one of the vservers listed in vsnames ($vsnames) is not running."
|
||||
fi
|
||||
info "Using vservers '$vsnames'"
|
||||
usevserver=yes
|
||||
fi
|
||||
|
||||
## SANITY CHECKS #########################
|
||||
|
||||
if [ "$luksheaders" == "yes" ]; then
|
||||
if [ ! -x "$DD" ]; then
|
||||
warning "can't find dd, skipping backup of Luks headers."
|
||||
luksheaders="no"
|
||||
fi
|
||||
if [ ! -x "$CRYPTSETUP" ]; then
|
||||
warning "can't find cryptsetup, skipping backup of Luks headers."
|
||||
luksheaders="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$lvm" == "yes" ]; then
|
||||
if [ ! -x "$VGS" ]; then
|
||||
warning "can't find vgs, skipping backup of LVM metadata"
|
||||
lvm="no"
|
||||
fi
|
||||
if [ ! -x "$VGCFGBACKUP" ]; then
|
||||
warning "can't find vgcfgbackup, skipping backup of LVM metadata"
|
||||
lvm="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
## PACKAGES ##############################
|
||||
|
||||
#
|
||||
# here we grab a list of the packages installed and removed.
|
||||
#
|
||||
|
||||
if [ "$packages" == "yes" ]; then
|
||||
|
||||
if [ $usevserver = yes ]; then
|
||||
info "vserver root directory set to: $VROOTDIR"
|
||||
for vserver in $vsnames; do
|
||||
info "examining vserver: $vserver"
|
||||
# is it running ?
|
||||
vservers_running $vserver
|
||||
if [ $? -ne 0 ]; then
|
||||
warning "The vserver $vserver is not running."
|
||||
continue
|
||||
fi
|
||||
# is $packagemgr available inside $vserver ?
|
||||
if [ ! -x "${VROOTDIR}/${vserver}${packagemgr}" ]; then
|
||||
warning "can't find $packagemgr in vserver $vserver, skipping installed packages report."
|
||||
else
|
||||
# don't expand * since it can be used in $packagemgroptions
|
||||
set -o noglob
|
||||
debug "$VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile"
|
||||
$VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile || fatal "can not save $packagemgr info to $packagesfile"
|
||||
set +o noglob
|
||||
fi
|
||||
# is $debconfgetselections available inside $vserver ?
|
||||
found=no
|
||||
# case #1: it is available on the host, is it available inside $vserver ?
|
||||
if [ -n "$debconfgetselections" ]; then
|
||||
[ -x "${VROOTDIR}/${vserver}${debconfgetselections}" ] && found=yes
|
||||
# case #2: it is not available on the host, is it available inside $vserver ?
|
||||
else
|
||||
[ -n "`$VSERVER $vserver exec which debconf-get-selections`" ] && found=yes
|
||||
fi
|
||||
if [ "$found" != yes ]; then
|
||||
warning "can't find debconf-get-selections in vserver $vserver, skipping package selection states. You may want to install the debconf-utils package."
|
||||
else
|
||||
debug "$VSERVER $vserver exec $debconfgetselections > $VROOTDIR/$vserver$selectionsfile"
|
||||
$VSERVER $vserver exec $debconfgetselections > $VROOTDIR/$vserver$selectionsfile || fatal "can not save debconf-get-selections info to $selectionsfile"
|
||||
fi
|
||||
unset found
|
||||
done
|
||||
fi
|
||||
|
||||
# We want to perform this on the host as well
|
||||
if [ -z "$packagemgr" -o ! -x "$packagemgr" ]; then
|
||||
warning "can't find ${packagemgr}, skipping installed packages report."
|
||||
else
|
||||
# don't expand * since it can be used in $packagemgroptions
|
||||
set -o noglob
|
||||
debug "$packagemgr $packagemgroptions > $packagesfile"
|
||||
$packagemgr $packagemgroptions > $packagesfile || fatal "can not save $packagemgr info to $packagesfile"
|
||||
set +o noglob
|
||||
fi
|
||||
if [ -z "$debconfgetselections" ]; then
|
||||
warning "can't find debconf-get-selections, skipping package selection states. You might want to install the debconf-utils package."
|
||||
else
|
||||
debug "$debconfgetselections > $selectionsfile"
|
||||
$debconfgetselections > $selectionsfile || fatal "can not save $debconfgetselections info to $selectionsfile"
|
||||
fi
|
||||
fi
|
||||
|
||||
## System report ##############################
|
||||
|
||||
#
|
||||
# here we grab a bunch of system stuff for a report
|
||||
#
|
||||
|
||||
export STATUS
|
||||
|
||||
HASHES="#################################################################"
|
||||
DASHES="-----------------------------------------------------------------"
|
||||
|
||||
cat /dev/null > $sysreportfile || fatal "can not write to $sysreportfile"
|
||||
|
||||
|
||||
catiffile () {
|
||||
echo $HASHES >> $sysreportfile
|
||||
echo "# $STATUS" >> $sysreportfile
|
||||
echo $HASHES >> $sysreportfile
|
||||
if [ -f $1 ]; then
|
||||
echo "file: $1" >> $sysreportfile
|
||||
echo $DASHES >> $sysreportfile
|
||||
cat $1 >> $sysreportfile 2>&1 || info "reading of $1 failed"
|
||||
fi
|
||||
if [ -d $1 ]; then
|
||||
echo "directory: $1" >> $sysreportfile
|
||||
echo $DASHES >> $sysreportfile
|
||||
for file in `find $1 -maxdepth 3 -noleaf -type f`
|
||||
do
|
||||
catiffile $file
|
||||
done
|
||||
fi
|
||||
echo $DASHES >> $sysreportfile
|
||||
}
|
||||
|
||||
catifexec () {
|
||||
if [ -x $1 ]; then
|
||||
echo $HASHES >> $sysreportfile
|
||||
echo "# $STATUS" >> $sysreportfile
|
||||
echo $HASHES >> $sysreportfile
|
||||
$* >> $sysreportfile 2>&1 || info "executing of $1 failed"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
STATUS="Determining $os version:"
|
||||
catiffile $osversion
|
||||
|
||||
STATUS="Determinding your current hostname: "
|
||||
catifexec "/bin/hostname"
|
||||
|
||||
STATUS="Getting the date:"
|
||||
catifexec "/bin/date"
|
||||
|
||||
STATUS="Checking your systems current uptime and load average:"
|
||||
catifexec "/usr/bin/uptime"
|
||||
|
||||
STATUS="Checking available memory:"
|
||||
catifexec "/usr/bin/free"
|
||||
|
||||
STATUS="Checking free disk space:"
|
||||
catifexec "/bin/df" "-al"
|
||||
|
||||
STATUS="Collecting what services run at what run level:"
|
||||
if [ $os = "redhat" ]; then
|
||||
catifexec "/sbin/chkconfig" "--list"
|
||||
STATUS="Collecting information about /etc/rc.d:"
|
||||
catiffile "/bin/ls /etc/rc.d/rc*.d/"
|
||||
|
||||
elif [ $os = "debian" ]; then
|
||||
for level in 0 1 2 3 4 5 6 S; do
|
||||
echo "Level: $level" >> $sysreportfile
|
||||
for f in /etc/rc${level}.d/*; do
|
||||
# Remove /etc/Knn or Snn from beginning
|
||||
ff=$(echo $f | @SED@ 's_/etc/rc..d/[KS][0-9][0-9]__')
|
||||
if [ $f != $ff ]; then
|
||||
echo $ff >> $sysreportfile
|
||||
fi
|
||||
done
|
||||
echo "" >> $sysreportfile
|
||||
done
|
||||
fi
|
||||
|
||||
STATUS="Getting bootloader information:"
|
||||
catifexec "/bin/ls" "-alR /boot"
|
||||
|
||||
# This covers sparc, alpha, and intel (respectively)
|
||||
# updated for grub -mpg
|
||||
if [ -f /etc/silo.conf ]; then
|
||||
STATUS="Collecting information about the boot process (silo):"
|
||||
catiffile "/etc/silo.conf"
|
||||
fi
|
||||
if [ -f /etc/milo.conf ]; then
|
||||
STATUS="Collecting information about the boot process (milo):"
|
||||
catiffile "/etc/milo.conf"
|
||||
fi
|
||||
if [ -f /etc/lilo.conf ]; then
|
||||
STATUS="Collecting information about the boot process (lilo):"
|
||||
catiffile "/etc/lilo.conf"
|
||||
catifexec "/sbin/lilo" "-q"
|
||||
fi
|
||||
if [ -d /boot/grub -a -f /boot/grub/grub.conf -a -f /boot/grub/device.map ]; then
|
||||
STATUS="Collecting information about the boot process (grub.conf):"
|
||||
catiffile "/boot/grub/grub.conf"
|
||||
STATUS="Collecting information about the boot process (grub.map):"
|
||||
catiffile "/boot/grub/device.map"
|
||||
fi
|
||||
if [ -f /etc/cluster.conf -o -f /etc/cluster.xml ] ; then
|
||||
STATUS="Gathering information on cluster setup"
|
||||
# 2.1 AS
|
||||
if [ -f /etc/cluster.conf ] ; then
|
||||
catiffile "/etc/cluster.conf"
|
||||
fi
|
||||
# Taroon
|
||||
if [ -f /etc/cluster.xml ] ; then
|
||||
catiffile "/etc/cluster.xml"
|
||||
fi
|
||||
fi
|
||||
|
||||
STATUS="Gathering sysctl information (sysctl -a):"
|
||||
catiffile "sysctl -a 2>/dev/null"
|
||||
STATUS="Gathering sysctl information (/etc/sysctl.conf):"
|
||||
catiffile "/etc/sysctl.conf"
|
||||
|
||||
STATUS="Gathering IP information (/sbin/ifconfig):"
|
||||
catifexec "/sbin/ifconfig" "-a"
|
||||
|
||||
STATUS="Gathering additional IP information (/bin/ip addr list):"
|
||||
catifexec "/bin/ip" "addr list"
|
||||
|
||||
STATUS="Checking network routes:"
|
||||
catifexec "/sbin/route" "-n"
|
||||
|
||||
STATUS="Collecting Name Service Switch config information:"
|
||||
catiffile "/etc/nsswitch.conf"
|
||||
|
||||
STATUS="Collecting information about system authentication (pam):"
|
||||
catiffile "/etc/pam.conf"
|
||||
catiffile "/etc/pam.d"
|
||||
|
||||
echo
|
||||
echo "Getting information about the kernel."
|
||||
echo
|
||||
STATUS="Getting kernel version:"
|
||||
catifexec "/bin/uname" "-a"
|
||||
STATUS="Checking module information:"
|
||||
catifexec "/sbin/lsmod"
|
||||
for x in $(/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null
|
||||
) ; do
|
||||
STATUS="Checking module information $x:"
|
||||
catifexec "/sbin/modinfo" "$x"
|
||||
done
|
||||
|
||||
STATUS="Gathering information about your filesystems:"
|
||||
catiffile "/proc/filesystems"
|
||||
|
||||
STATUS="Gathering information about your system stat:"
|
||||
catiffile "/proc/stat"
|
||||
|
||||
STATUS="Gathering information about your partitions:"
|
||||
catiffile "/proc/partitions"
|
||||
|
||||
STATUS="Gathering information about your ksyms:"
|
||||
catiffile "/proc/kallsyms"
|
||||
|
||||
STATUS="Gathering information about slabinfo:"
|
||||
catiffile "/proc/slabinfo"
|
||||
|
||||
# Added support to cover for the new modules.conf layout in Red Hat 7
|
||||
STATUS="Collecting information regarding kernel modules"
|
||||
VER=`uname -r`
|
||||
catiffile "/lib/modules/$VER/modules.dep"
|
||||
if [ -f /etc/conf.modules ]; then
|
||||
STATUS="Collecting information regarding kernel modules (conf.modules)"
|
||||
catiffile "/etc/conf.modules"
|
||||
fi
|
||||
if [ -f /etc/modules.conf ]; then
|
||||
STATUS="Collecting information regarding kernel modules (modules.conf)"
|
||||
catiffile "/etc/modules.conf"
|
||||
fi
|
||||
if [ -f /etc/modprobe.conf ]; then
|
||||
STATUS="Collecting information regarding kernel modules (modeprobe.conf)"
|
||||
catiffile "/etc/modprobe.conf"
|
||||
fi
|
||||
|
||||
# dkms status
|
||||
if [ -x /usr/sbin/dkms ] ; then
|
||||
STATUS="Gathering current status of modules, versions and kernels (dkms):"
|
||||
catifexec "/usr/sbin/dkms" "status"
|
||||
fi
|
||||
|
||||
if [ -f /etc/sysconfig/isdncard ] ; then
|
||||
STATUS="Gathering information about ISDN:"
|
||||
catiffile "/etc/sysconfig/isdncard"
|
||||
fi
|
||||
|
||||
STATUS="Collecting information from the proc directory:"
|
||||
catiffile "/proc/pci"
|
||||
|
||||
STATUS="Getting kernel command line"
|
||||
catiffile "/proc/cmdline"
|
||||
|
||||
STATUS="Gathering information about your CPU:"
|
||||
catiffile "/proc/cpuinfo"
|
||||
|
||||
STATUS="Gathering information about your Ram:"
|
||||
catiffile "/proc/meminfo"
|
||||
|
||||
STATUS="Gathering information about your ioports:"
|
||||
catiffile "/proc/ioports"
|
||||
|
||||
STATUS="Gathering information about your interrupts:"
|
||||
catiffile "/proc/interrupts"
|
||||
|
||||
STATUS="Gathering information about your scsi devices:"
|
||||
catiffile "/proc/scsi"
|
||||
|
||||
STATUS="Gathering information about your dma:"
|
||||
catiffile "/proc/dma"
|
||||
|
||||
STATUS="Gathering information about your devices (/proc/devices):"
|
||||
catiffile "/proc/devices"
|
||||
|
||||
STATUS="Gathering information about your rtc:"
|
||||
catiffile "/proc/rtc"
|
||||
|
||||
STATUS="Gathering information about your ide drivers:"
|
||||
catiffile "/proc/ide"
|
||||
|
||||
STATUS="Gathering information about your bus:"
|
||||
catifexec "/usr/bin/lspci"
|
||||
catiffile "/proc/bus"
|
||||
|
||||
echo
|
||||
echo "Getting disk and filesystem information."
|
||||
echo
|
||||
|
||||
STATUS="Collecting information from /etc/fstab:"
|
||||
catiffile "/etc/fstab"
|
||||
|
||||
STATUS="Collecting disk partition information:"
|
||||
catifexec "/sbin/fdisk" "-l"
|
||||
|
||||
STATUS="Checking mounted file systems (mount) "
|
||||
catifexec "/bin/mount"
|
||||
|
||||
STATUS="Checking mounted file systems (/proc/mounts)"
|
||||
catiffile "/proc/mounts"
|
||||
|
||||
STATUS="Collecting Software RAID information (/proc/mdstat)"
|
||||
catiffile "/proc/mdstat"
|
||||
|
||||
STATUS="Collecting Software RAID information (/etc/raidtab)"
|
||||
catiffile "/etc/raidtab"
|
||||
|
||||
STATUS="Collecting Software RAID information (/etc/mdadm.conf)"
|
||||
catiffile "/etc/mdadm.conf"
|
||||
|
||||
STATUS="Collecting Software RAID information (/sbin/mdadm -Q)"
|
||||
catifexec "/sbin/mdadm" "-Q" "--detail" '/dev/md?*'
|
||||
|
||||
STATUS="Collecting Automount information (auto.master)"
|
||||
catiffile "/etc/auto.master"
|
||||
|
||||
STATUS="Collecting Automount information (auto.misc)"
|
||||
catiffile "/etc/auto.misc"
|
||||
|
||||
STATUS="Collecting Automount information (auto.net)"
|
||||
catiffile "/etc/auto.net"
|
||||
|
||||
STATUS="Collecting LVM information:"
|
||||
if [ $os = "redhat" ]; then
|
||||
catifexec "/usr/sbin/vgdisplay" "-vv"
|
||||
elif [ $os = "debian" ]; then
|
||||
catifexec "/sbin/vgdisplay" "-vv"
|
||||
fi
|
||||
|
||||
STATUS="Collecting device-mapper (dm) information:"
|
||||
catifexec '/sbin/dmsetup' 'info'
|
||||
|
||||
STATUS="Collecting SCSI Tape information (/etc/stinit.def)"
|
||||
catiffile "/etc/stinit.def"
|
||||
|
||||
if [ -x /sbin/lsusb ] ; then
|
||||
STATUS="Collecting USB devices list (lsusb):"
|
||||
catifexec "/sbin/lsusb"
|
||||
fi
|
||||
|
||||
if [ -x /usr/bin/lshal ] ; then
|
||||
STATUS="Collecting global devices list (lshal):"
|
||||
catifexec "/usr/bin/lshal"
|
||||
fi
|
||||
|
||||
|
||||
STATUS="Gathering information on SELinux setup"
|
||||
catifexec "/usr/bin/selinuxconfig"
|
||||
catifexec "/usr/sbin/sestatus"
|
||||
if [ $os = "redhat" ]; then
|
||||
catifexec "rpm" "-q -V selinux-policy-targeted"
|
||||
catifexec "rpm" "-q -V selinux-policy-strict"
|
||||
fi
|
||||
|
||||
if [ $usevserver = yes ]; then
|
||||
STATUS="Gathering vserver information"
|
||||
catiffile "/proc/virtual"
|
||||
fi
|
||||
|
||||
if [ "$partitions" == "yes" ]; then
|
||||
if [ "$dosfdisk" == "yes" ]; then
|
||||
if [ ! -x "$SFDISK" ]; then
|
||||
warning "can't find sfdisk, skipping sfdisk report."
|
||||
partitions="no"
|
||||
fi
|
||||
fi
|
||||
if [ "$dohwinfo" == "yes" ]; then
|
||||
if [ ! -x "$HWINFO" ]; then
|
||||
warning "can't find hwinfo, skipping partition report."
|
||||
partitions="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$hardware" == "yes" ]; then
|
||||
if [ ! -x "$HWINFO" ]; then
|
||||
warning "can't find hwinfo, skipping hardware report."
|
||||
hardware="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
## HARDWARE #############################
|
||||
|
||||
#
|
||||
# here we use hwinfo to dump a table listing all the
|
||||
# information we can find on the hardware of this machine
|
||||
#
|
||||
|
||||
if [ "$hardware" == "yes" ]; then
|
||||
if [ "dohwinfo" == "yes" ]; then
|
||||
if [ -f $hardwarefile ]; then
|
||||
rm $hardwarefile
|
||||
fi
|
||||
touch $hardwarefile
|
||||
echo -e "\n\n====================== summary ======================\n" >> $hardwarefile
|
||||
debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile"
|
||||
$HWINFO --short --cpu --network --disk --pci >> $hardwarefile
|
||||
for flag in cpu network bios pci; do
|
||||
echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile
|
||||
$HWINFO --$flag >> $hardwarefile
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
## PARTITIONS #############################
|
||||
|
||||
# here we use sfdisk to dump a listing of all the partitions.
|
||||
# these files can be used to directly partition a disk of the same size.
|
||||
|
||||
if [ "$partitions" == "yes" ]; then
|
||||
if [ "$dosfdisk" == "yes" ]; then
|
||||
devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1`
|
||||
if [ "$devices" == "" ]; then
|
||||
warning "No harddisks found"
|
||||
fi
|
||||
for dev in $devices; do
|
||||
debug "$SFDISK will try to backup partition tables for device $dev"
|
||||
[ -b $dev ] || continue
|
||||
label=${dev#/dev/}
|
||||
label=${label//\//-}
|
||||
outputfile=${partitionsfile//__star__/$label}
|
||||
debug "$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null"
|
||||
$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
warning "The partition table for $dev could not be saved."
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ "$dohwinfo" == "yes" ]; then
|
||||
debug "Using $HWINFO to get all available disk information"
|
||||
echo -e "\n\n====================== $disk ======================\n" >> $hardwarefile
|
||||
$HWINFO --disk >> $hardwarefile
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$luksheaders" == "yes" ]; then
|
||||
devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1`
|
||||
[ -n "$devices" ] || warning "No block device found"
|
||||
targetdevices=""
|
||||
for dev in $devices; do
|
||||
[ -b $dev ] || continue
|
||||
debug "$CRYPTSETUP isLuks $dev"
|
||||
$CRYPTSETUP isLuks $dev
|
||||
[ $? -eq 0 ] && targetdevices="$targetdevices $dev"
|
||||
done
|
||||
for dev in $targetdevices; do
|
||||
label=${dev#/dev/}
|
||||
label=${label//\//-}
|
||||
outputfile=${luksheadersfile//__star__/$label}
|
||||
# the following sizes are expressed in terms of 512-byte sectors
|
||||
debug "Let us find out the Luks header size for $dev"
|
||||
debug "$CRYPTSETUP luksDump \"$dev\" | grep '^Payload offset:' | @AWK@ '{print $3}'"
|
||||
headersize=`$CRYPTSETUP luksDump "$dev" | grep '^Payload offset:' | @AWK@ '{print $3}'`
|
||||
if [ $? -ne 0 ]; then
|
||||
warning "Could not compute the size of Luks header, skipping device $dev"
|
||||
continue
|
||||
elif [ -z "$headersize" -o -n "`echo \"$headersize\" | sed 's/[0-9]*//g'`" ]; then
|
||||
warning "The computed size of Luks header is not an integer, skipping device $dev"
|
||||
continue
|
||||
fi
|
||||
debug "Let us backup the Luks header of device $dev"
|
||||
debug "$DD if=\"${dev}\" of=\"${outputfile}\" bs=512 count=\"${headersize}\""
|
||||
output=`$DD if="${dev}" of="${outputfile}" bs=512 count="${headersize}" 2>&1`
|
||||
exit_code=$?
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
debug $output
|
||||
info "The Luks header of $dev was saved to $outputfile."
|
||||
else
|
||||
debug $output
|
||||
fatal "The Luks header of $dev could not be saved."
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
## LVM ####################################
|
||||
|
||||
# returns 0 on success, 1 on error, 2 if not tried
|
||||
# outputs error message if error, reason if not tried
|
||||
function doLvmBackup () {
|
||||
local lvmdir="$1"
|
||||
if [ ! -d "$lvmdir" ]; then
|
||||
if ! mkdir "$lvmdir"; then
|
||||
echo "could not create $lvmdir"
|
||||
return 2
|
||||
else
|
||||
info "successfully created $lvmdir"
|
||||
fi
|
||||
fi
|
||||
if [ ! -w "$lvmdir" ]; then
|
||||
echo "can not write to directory $lvmdir"
|
||||
return 2
|
||||
fi
|
||||
debug "Let's try to gather the list of LVM volume groups"
|
||||
debug "$VGS --options vg_name --noheadings | @SED@ 's/^[ ]*//' | @SED@ 's/[ ]*$//' | tr '\n' ' '"
|
||||
vgs=`$VGS --options vg_name --noheadings | @SED@ 's/^[ ]*//' | @SED@ 's/[ ]*$//' | tr '\n' ' '`
|
||||
debug "Let's try to backup LVM metadata for detected volume groups: $vgs"
|
||||
debug "$VGCFGBACKUP --file \"${lvmdir}\"/\'%s\' $vgs"
|
||||
output=`$VGCFGBACKUP --file "${lvmdir}"/'%s' $vgs`
|
||||
exit_code=$?
|
||||
debug $output
|
||||
case $exit_code in
|
||||
0)
|
||||
info "LVM metadata was saved to $lvmdir for volume groups: $vgs"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "LVM metadata could not be saved for at least one of these volume groups: $vgs"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ "$lvm" == "yes" ]; then
|
||||
output=`doLvmBackup "${parentdir}/lvm"`
|
||||
exit_code=$?
|
||||
case $exit_code in
|
||||
0) # success. info message has already been displayed
|
||||
true
|
||||
;;
|
||||
1) # error
|
||||
fatal "$output"
|
||||
;;
|
||||
2) # could not even try
|
||||
fatal "LVM metadata backup was not tried: $output"
|
||||
;;
|
||||
*) # should never happen
|
||||
fatal "Unhandled error ($exit_code) while trying to backup LVM metadata, please report a bug"
|
||||
;;
|
||||
esac
|
||||
fi
|
@ -1,94 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
HELPERS="$HELPERS tar:tar_backup"
|
||||
|
||||
tar_wizard() {
|
||||
tar_title="Tar action wizard"
|
||||
|
||||
backupname=`hostname --fqdn`
|
||||
|
||||
inputBox "$tar_title" "When to run this action?" "everyday at 01"
|
||||
[ $? = 1 ] && return
|
||||
tar_when_run="when = $REPLY"
|
||||
|
||||
inputBox "$tar_title" "\"Name\" of backups" "$backupname"
|
||||
[ $? = 1 ] && return
|
||||
tar_backupname="backupname = $REPLY"
|
||||
backupname="$REPLY"
|
||||
|
||||
inputBox "$tar_title" "Directory where to store the backups" "/net/backups/$backupname"
|
||||
[ $? = 1 ] && return
|
||||
tar_backupdir="backupdir = $REPLY"
|
||||
|
||||
radioBox "$tar_title" "Compression" \
|
||||
"none" "do not filter trough" off \
|
||||
"compress" "filter trough compress" off \
|
||||
"gzip" "filter trough gzip" off \
|
||||
"bzip" "filter trough bzip" on
|
||||
[ $? = 1 ] && return;
|
||||
result="$REPLY"
|
||||
tar_compress="compress = $REPLY "
|
||||
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$tar_title: Includes"
|
||||
formItem "Include:" /etc
|
||||
formItem "Include:" /home
|
||||
formItem "Include:" /usr/local
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formItem "Include:"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
tar_includes="includes = "
|
||||
for i in $REPLY; do
|
||||
[ -n "$i" ] && tar_includes="$tar_includes $i"
|
||||
done
|
||||
done
|
||||
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
formBegin "$tar_title: Excludes"
|
||||
formItem "Exclude:" /tmp
|
||||
formItem "Exclude:" /proc
|
||||
formItem "Exclude:" /sys
|
||||
formItem "Exclude:" /dev
|
||||
formItem "Exclude:" /srv
|
||||
formItem "Exclude:" /media
|
||||
formItem "Exclude:" /misc
|
||||
formItem "Exclude:" /net
|
||||
formItem "Exclude:" /selinux
|
||||
formItem "Exclude:"
|
||||
formItem "Exclude:"
|
||||
formDisplay
|
||||
[ $? = 0 ] || return 1
|
||||
tar_excludes="excludes = "
|
||||
for i in $REPLY; do
|
||||
[ -n "$i" ] && tar_excludes="$tar_excludes $i"
|
||||
done
|
||||
done
|
||||
|
||||
# Save the config
|
||||
get_next_filename $configdirectory/10.tar
|
||||
cat > $next_filename <<EOF
|
||||
$tar_when_run
|
||||
$tar_backupname
|
||||
$tar_backupdir
|
||||
$tar_compress
|
||||
$tar_includes
|
||||
$tar_excludes
|
||||
|
||||
# tar binary - have to be GNU tar
|
||||
#TAR=/bin/tar
|
||||
#DATE /bin/date
|
||||
#DATEFORMAT "%Y.%m.%d-%H%M"
|
||||
|
||||
EOF
|
||||
chmod 600 $next_filename
|
||||
}
|
||||
|
@ -1,79 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# tar handler script for backupninja
|
||||
|
||||
getconf backupname `hostname --fqdn`
|
||||
getconf backupdir /var/backups/`hostname --fqdn`
|
||||
getconf compress bzip
|
||||
getconf includes "/etc /home /usr/local"
|
||||
getconf excludes "/tmp /proc /dev /sys /net /misc /media /srv /selinux"
|
||||
|
||||
getconf TAR `which tar`
|
||||
getconf EXTENSION tar
|
||||
getconf DATE `which date`
|
||||
getconf DATEFORMAT "%Y.%m.%d-%H%M"
|
||||
|
||||
# See if vservers are configured
|
||||
if [ "$vservers" = "yes" ]
|
||||
then
|
||||
warning "vservers enabled, but tar does not support it!"
|
||||
fi
|
||||
|
||||
if [ ! -d "$backupdir" ]
|
||||
then
|
||||
mkdir -p "$backupdir" || fatal "Can not make directory $backupdir"
|
||||
fi
|
||||
|
||||
if [ ! -w "$backupdir" ]
|
||||
then
|
||||
fatal "Directory $backupdir is not writable"
|
||||
fi
|
||||
|
||||
## DO IT #################################################
|
||||
#
|
||||
# here we grab a list of the packages installed and removed.
|
||||
#
|
||||
|
||||
case $compress in
|
||||
"compress")
|
||||
compress_option="-Z"
|
||||
EXTENSION="tar.compress"
|
||||
;;
|
||||
"gzip")
|
||||
compress_option="-z"
|
||||
EXTENSION="tgz"
|
||||
;;
|
||||
"bzip")
|
||||
compress_option="-j"
|
||||
EXTENSION="tar.bz2"
|
||||
;;
|
||||
"none")
|
||||
compress_option=""
|
||||
;;
|
||||
*)
|
||||
warning "Unknown compress filter ($tar_compress)"
|
||||
compress_option=""
|
||||
EXTENSION="tgz"
|
||||
;;
|
||||
esac
|
||||
|
||||
exclude_options=""
|
||||
for i in $excludes
|
||||
do
|
||||
exclude_options="$exclude_options --exclude $i"
|
||||
done
|
||||
|
||||
debug "Running backup: " $TAR -c -p -v $compress_option $exclude_options \
|
||||
-f "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`".$EXTENSION" \
|
||||
$includes
|
||||
|
||||
$TAR -c -p -v $compress_option $exclude_options \
|
||||
-f "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`".$EXTENSION" \
|
||||
$includes \
|
||||
> "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`.list \
|
||||
2> "$backupdir/$backupname-"`$DATE "+$DATEFORMAT"`.err
|
||||
|
||||
[ $? -ne 0 ] && fatal "Tar backup failed"
|
||||
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# this handler will backup trac environments (based on the svn handler)
|
||||
#
|
||||
# http://trac.edgewall.com/
|
||||
#
|
||||
|
||||
getconf src /var/lib/trac
|
||||
getconf dest /var/backups/trac
|
||||
getconf tmp /var/backups/trac.tmp
|
||||
|
||||
cd $src
|
||||
for repo in `find . -name VERSION`
|
||||
do
|
||||
|
||||
repo=`dirname $repo`
|
||||
if [ "$repo" == "." ]
|
||||
then
|
||||
repo=""
|
||||
fi
|
||||
|
||||
# Just make the parent directory for $tmp/$repo
|
||||
parentdir=`dirname $tmp/$repo`
|
||||
ret=`mkdir -p $parentdir 2>&1`
|
||||
code=$?
|
||||
if [ "$ret" ]; then
|
||||
debug "$ret"
|
||||
fi
|
||||
if [ $code != 0 ]; then
|
||||
error "command failed mkdir -p $parentdir"
|
||||
fi
|
||||
|
||||
ret=`trac-admin $src/$repo hotcopy $tmp/$repo 2>&1`
|
||||
code=$?
|
||||
if [ "$ret" ]; then
|
||||
debug "$ret"
|
||||
fi
|
||||
if [ $code != 0 ]; then
|
||||
error "command failed -- trac-admin $src/$repo hotcopy $tmp/$repo"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -d $dest -a -d $tmp ]; then
|
||||
rm -rf $dest
|
||||
fi
|
||||
if [ -d $tmp ]; then
|
||||
mv $tmp $dest
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# vim: filetype=sh
|
220
handlers/wget
220
handlers/wget
@ -1,220 +0,0 @@
|
||||
#
|
||||
# backupninja handler to do incremental backups using
|
||||
# wget and hardlinks, based on rsync handler
|
||||
#
|
||||
# feedback: rhatto at riseup.net | gpl
|
||||
#
|
||||
# Config file options
|
||||
# -------------------
|
||||
#
|
||||
# [general]
|
||||
# log = wget log file
|
||||
# partition = partition where the backup lives
|
||||
# fscheck = set to 1 if fsck should run on $partition after the backup is made
|
||||
# read_only = set to 1 if $partition is mounted read-only
|
||||
# mountpoint = backup partition mountpoint or backup main folder
|
||||
# backupdir = folder relative do $mountpoint where the backup should be stored
|
||||
# days = number of backup increments (min = 5)
|
||||
# lockfile = lockfile to be kept during backup execution
|
||||
# nicelevel = wget command nice level
|
||||
# enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly
|
||||
# tmp = temp folder
|
||||
#
|
||||
# [source]
|
||||
# wget = wget program
|
||||
# wget_options = wget command options
|
||||
# url = remote data url
|
||||
# bandwidthlimit = set a badnwidth limit in kbps (remote source only)
|
||||
#
|
||||
# [destination]
|
||||
# folder = local folder
|
||||
#
|
||||
# You can also specify some system comands if you don't want the default system values:
|
||||
#
|
||||
# [system]
|
||||
# rm = rm command
|
||||
# cp = cp command
|
||||
# touch = touch command
|
||||
# mv = mv command
|
||||
# fsck = fsck command
|
||||
#
|
||||
# TODO: Daily, weekly and monthly snapshot rotation (like the one present on maildir handler).
|
||||
#
|
||||
|
||||
# config file evaluation
|
||||
|
||||
setsection system
|
||||
getconf rm rm
|
||||
getconf cp cp
|
||||
getconf touch touch
|
||||
getconf mv mv
|
||||
getconf fsck fsck
|
||||
|
||||
setsection general
|
||||
getconf log /var/log/backup/wget.log
|
||||
getconf partition
|
||||
getconf fscheck
|
||||
getconf read_only
|
||||
getconf mountpoint
|
||||
getconf backupdir
|
||||
getconf rotate
|
||||
getconf days
|
||||
getconf lockfile
|
||||
getconf nicelevel 0
|
||||
getconf enable_mv_timestamp_bug no
|
||||
getconf tmp /tmp
|
||||
|
||||
setsection source
|
||||
getconf wget wget
|
||||
getconf wget_options
|
||||
getconf url
|
||||
getconf bandwidthlimit
|
||||
|
||||
setsection destination
|
||||
getconf folder
|
||||
|
||||
# function definitions
|
||||
|
||||
function rotate {
|
||||
|
||||
if [[ "$2" < 4 ]]; then
|
||||
error "Rotate: minimum of 4 rotations"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d $1.$2 ]; then
|
||||
$nice $mv /$1.$2 /$1.tmp
|
||||
fi
|
||||
|
||||
for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do
|
||||
if [ -d $1.$n ]; then
|
||||
dest=`echo "$n + 1" | bc`
|
||||
$nice $mv /$1.$n /$1.$dest
|
||||
$touch /$1.$dest
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -d $1.tmp ]; then
|
||||
$nice $mv /$1.tmp /$1.0
|
||||
fi
|
||||
|
||||
if [ -d $1.1 ]; then
|
||||
$nice $cp -alf /$1.1/. /$1.0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function move_files {
|
||||
|
||||
ref=$tmp/makesnapshot-mymv-$$;
|
||||
$touch -r $1 $ref;
|
||||
$mv $1 $2;
|
||||
$touch -r $ref $2;
|
||||
$rm $ref;
|
||||
|
||||
}
|
||||
|
||||
backupdir="$mountpoint/$backupdir"
|
||||
|
||||
# does $backupdir exists?
|
||||
|
||||
if [ ! -d "$backupdir" ]; then
|
||||
error "Backupdir $backupdir does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# setup number of increments
|
||||
|
||||
if [ -z "$days" ]; then
|
||||
keep="4"
|
||||
else
|
||||
keep="`echo $days - 1 | bc -l`"
|
||||
fi
|
||||
|
||||
# lockfile setup
|
||||
|
||||
if [ ! -z "$lockfile" ]; then
|
||||
$touch $lockfile || warning "Could not create lockfile $lockfile"
|
||||
fi
|
||||
|
||||
# nicelevel setup
|
||||
|
||||
if [ ! -z "$nicelevel" ]; then
|
||||
nice="nice -n $nicelevel"
|
||||
else
|
||||
nice=""
|
||||
fi
|
||||
|
||||
# set mv procedure
|
||||
|
||||
if [ $enable_mv_timestamp_bug == "yes" ]; then
|
||||
mv=move_files
|
||||
fi
|
||||
|
||||
# set excludes
|
||||
|
||||
for path in $exclude; do
|
||||
EXCLUDES="$EXCLUDES --exclude=$path"
|
||||
done
|
||||
|
||||
echo "Starting backup at `date`" >> $log
|
||||
|
||||
# mount backup destination folder as read-write
|
||||
|
||||
if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
|
||||
if [ -d "$mountpoint" ]; then
|
||||
mount -o remount,rw $mountpoint
|
||||
if (($?)); then
|
||||
error "Could not mount $mountpoint"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# the backup procedure
|
||||
|
||||
if [ ! -d "$backupdir/$folder/$folder.0" ]; then
|
||||
mkdir -p $backupdir/$folder/$folder.0
|
||||
fi
|
||||
|
||||
info "Rotating $backupdir/$folder/$folder..."
|
||||
echo "Rotating $backupdir/$folder/$folder..." >> $log
|
||||
rotate $backupdir/$folder/$folder $keep
|
||||
info "Wget'ing $SECTION on $backupdir/$folder/$folder.0..."
|
||||
|
||||
if [ ! -z "$badnwidth" ]; then
|
||||
limit_rate="--limit-rate=$badnwidth""k"
|
||||
fi
|
||||
|
||||
cd $backupdir/$folder/$folder.0
|
||||
wget $wget_options $limit-rate -r -c -N -e robots=off $url
|
||||
cd -
|
||||
|
||||
$touch $backupdir/$folder/$folder.0
|
||||
|
||||
# remount backup destination as read-only
|
||||
|
||||
if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
|
||||
mount -o remount,ro $mountpoint
|
||||
fi
|
||||
|
||||
# check partition for errors
|
||||
|
||||
if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then
|
||||
umount $mountpoint
|
||||
if (($?)); then
|
||||
warning "Could not umount $mountpoint to run fsck"
|
||||
else
|
||||
$nice $fsck -v -y $partition >> $log
|
||||
mount $mountpoint
|
||||
fi
|
||||
fi
|
||||
|
||||
# removes the lockfile
|
||||
|
||||
if [ ! -z "$lockfile" ]; then
|
||||
$rm $lockfile || warning "Could not remove lockfile $lockfile"
|
||||
fi
|
||||
|
||||
echo "Finnishing backup at `date`" >> $log
|
||||
|
@ -1,29 +0,0 @@
|
||||
pkglib_SCRIPTS = easydialog parseini tools vserver
|
||||
|
||||
CLEANFILES = $(pkglib_SCRIPTS)
|
||||
|
||||
EXTRA_DIST = easydialog.in parseini.in tools.in vserver.in
|
||||
|
||||
edit = sed \
|
||||
-e "s,@CFGDIR\@,$(CFGDIR),g" \
|
||||
-e "s,@BASH\@,$(BASH),g" \
|
||||
-e "s,@AWK\@,$(AWK),g" \
|
||||
-e "s,@SED\@,$(SED),g" \
|
||||
-e "s,@MKTEMP\@,$(MKTEMP),g" \
|
||||
-e "s,@libdir\@,$(pkglibdir),g"
|
||||
|
||||
easydialog: $(srcdir)/easydialog.in
|
||||
rm -f easydialog
|
||||
$(edit) easydialog.in > easydialog
|
||||
|
||||
parseini: $(srcdir)/parseini.in
|
||||
rm -f parseini
|
||||
$(edit) parseini.in > parseini
|
||||
|
||||
tools: $(srcdir)/tools.in
|
||||
rm -f tools
|
||||
$(edit) tools.in > tools
|
||||
|
||||
vserver: $(srcdir)/vserver.in
|
||||
rm -f vserver
|
||||
$(edit) vserver.in > vserver
|
@ -1,267 +0,0 @@
|
||||
#!@BASH@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
# copyright 2002 lmoore@tump.com under the terms of the GNU LGPL.
|
||||
# additions 2005 collective@riseup.net
|
||||
|
||||
# whiptail has trouble being called in the foo=$(whiptail ...) fashion for
|
||||
# some reason. this is very annoying. this means that we need to use
|
||||
# temporary files to store the answers from the input and list based boxes
|
||||
# and then read the answers into a REPLY variable. that just really
|
||||
# stinks, oh well, that's what you get when you have a weak link
|
||||
# implementation...
|
||||
#
|
||||
# inputBox and passwordBox could be refactored to use a common function
|
||||
|
||||
test -z "$WIDTH" && WIDTH=0
|
||||
test -z "$HEIGHT" && HEIGHT=0
|
||||
BACKTITLE=""
|
||||
DIALOG=dialog
|
||||
HELP=
|
||||
|
||||
setApplicationTitle() {
|
||||
BACKTITLE=$*
|
||||
}
|
||||
|
||||
setHelp() {
|
||||
HELP="$@"
|
||||
}
|
||||
|
||||
setDimension() {
|
||||
WIDTH=$1
|
||||
HEIGHT=$2
|
||||
}
|
||||
|
||||
booleanBox() {
|
||||
$DIALOG --backtitle "$BACKTITLE" --title "$1" \
|
||||
`[ "$3" == no ] && echo '--defaultno'` --yesno "$2" $HEIGHT $WIDTH
|
||||
}
|
||||
|
||||
msgBox() {
|
||||
$DIALOG --backtitle "$BACKTITLE" --title "$1" \
|
||||
--msgbox "$2" $HEIGHT $WIDTH
|
||||
}
|
||||
|
||||
gaugeBox() {
|
||||
$DIALOG --backtitle "$BACKTITLE" --title "$1" \
|
||||
--gauge "$2" $HEIGHT $WIDTH 0
|
||||
}
|
||||
|
||||
inputBox() {
|
||||
local temp=$(@MKTEMP@ -t backupninja.XXXXXX) || exit 1
|
||||
trap "rm -f $temp" 0
|
||||
REPLY=
|
||||
$DIALOG --backtitle "$BACKTITLE" --title "$1" \
|
||||
--inputbox "$2" $HEIGHT $WIDTH "$3" 2> $temp
|
||||
local status=$?
|
||||
[ $status = 0 ] && REPLY=$(cat $temp)
|
||||
rm -f $temp
|
||||
return $status
|
||||
}
|
||||
|
||||
# Xdialog and {dialog,whiptail} use different mechanism to "qoute" the
|
||||
# values from a checklist. {dialog,whiptail} uses standard double quoting
|
||||
# while Xdialog uses a "/" as the separator. the slash is arguably better,
|
||||
# but the double quoting is more standard. anyway, this function can be
|
||||
# overridden to allow a derived implementation to change it's quoting
|
||||
# mechanism to the standard double-quoting one. it receives two
|
||||
# arguements, the file that has the data and the box type.
|
||||
_listReplyHook() {
|
||||
cat $1
|
||||
}
|
||||
|
||||
# this is the base implementation of all the list based boxes, it works
|
||||
# out nicely that way. the real function just passes it's arguments to
|
||||
# this function with an extra argument specifying the actual box that
|
||||
# needs to be rendered.
|
||||
_genericListBox() {
|
||||
local box=$1
|
||||
shift 1
|
||||
local title=$1
|
||||
local text=$2
|
||||
shift 2
|
||||
local temp=$(@MKTEMP@ -t backupninja.XXXXXX) || exit 1
|
||||
trap "rm -f $temp" 0
|
||||
REPLY=
|
||||
$DIALOG $HELP $_DEFAULT --backtitle "$BACKTITLE" --title "$title" \
|
||||
$box "$text" $HEIGHT $WIDTH 10 \
|
||||
"$@" 2> $temp
|
||||
local status=$?
|
||||
[ $status = 0 ] && REPLY=$(_listReplyHook $temp $box)
|
||||
rm -f $temp
|
||||
_DEFAULT=
|
||||
return $status
|
||||
}
|
||||
|
||||
setDefault() {
|
||||
_DEFAULT="--default-item $1"
|
||||
}
|
||||
|
||||
menuBox() {
|
||||
_genericListBox --menu "$@"
|
||||
}
|
||||
|
||||
## a menu box with additional help info displayed
|
||||
## at the bottom of the window when an item is selected
|
||||
menuBoxHelp() {
|
||||
HELP="--item-help"
|
||||
_genericListBox --menu "$@"
|
||||
status=$?
|
||||
HELP=
|
||||
return $status
|
||||
}
|
||||
|
||||
## a menu box with an addition button 'help'
|
||||
menuBoxHelpFile() {
|
||||
HELP="--help-button"
|
||||
_genericListBox --menu "$@"
|
||||
status=$?
|
||||
HELP=
|
||||
return $status
|
||||
}
|
||||
|
||||
checkBox() {
|
||||
_genericListBox --checklist "$@"
|
||||
}
|
||||
|
||||
radioBox() {
|
||||
_genericListBox --radiolist "$@"
|
||||
}
|
||||
|
||||
textBox() {
|
||||
$DIALOG --backtitle "$BACKTITLE" --title "$1" --textbox "$2" $HEIGHT $WIDTH
|
||||
}
|
||||
|
||||
passwordBox() {
|
||||
local temp=$(@MKTEMP@ -t backupninja.XXXXXX) || exit 1
|
||||
trap "rm -f $temp" 0
|
||||
REPLY=
|
||||
$DIALOG --backtitle "$BACKTITLE" --title "$1" \
|
||||
--passwordbox "$2" $HEIGHT $WIDTH 2> $temp
|
||||
local status=$?
|
||||
[ $status = 0 ] && REPLY=$(cat $temp)
|
||||
rm -f $temp
|
||||
return $status
|
||||
}
|
||||
|
||||
|
||||
#########################################################
|
||||
## begin-item-display style lists
|
||||
##
|
||||
## these lists are built by calling fuctions multiple times.
|
||||
## this can make it easier to build your list in a loop
|
||||
##
|
||||
|
||||
listBegin() {
|
||||
_menu_title=$1
|
||||
_menu_msg=$2
|
||||
_menu_items=0
|
||||
_menu_text=
|
||||
_menu_labels=
|
||||
_menu_status=
|
||||
}
|
||||
|
||||
listItem() {
|
||||
_menu_labels[$_menu_items]=$1
|
||||
_menu_text[$_menu_items]=$2
|
||||
_menu_status[$_menu_items]=$3 # available only for checklist
|
||||
let "_menu_items += 1"
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## takes one of:
|
||||
## menu, checklist, radiolist
|
||||
##
|
||||
listDisplay() {
|
||||
boxtype=$1
|
||||
local temp=$(@MKTEMP@ -t backupninja.XXXXXX) || exit 1
|
||||
trap "rm -f $temp" 0
|
||||
|
||||
local label
|
||||
local text
|
||||
local status
|
||||
(
|
||||
echo -ne " $HELP $_DEFAULT "
|
||||
echo -ne " --backtitle '$BACKTITLE' "
|
||||
echo -ne " --title '$_menu_title' "
|
||||
echo -ne " --$boxtype '$_menu_msg' "
|
||||
echo -ne " $HEIGHT $WIDTH 10 "
|
||||
for ((i=0; i < $_menu_items ; i++)); do
|
||||
label=${_menu_labels[$i]}
|
||||
text=${_menu_text[$i]}
|
||||
status=${_menu_status[$i]}
|
||||
echo -ne " $label '$text' $status "
|
||||
done
|
||||
) | xargs $DIALOG 2> $temp
|
||||
|
||||
local status=$?
|
||||
REPLY=""
|
||||
[ $status = 0 ] && REPLY=`cat $temp`
|
||||
rm -f $temp
|
||||
_DEFAULT=
|
||||
return $status
|
||||
}
|
||||
|
||||
####################################################
|
||||
## FORM
|
||||
|
||||
_form_gap=2
|
||||
formBegin() {
|
||||
_form_title=$1
|
||||
_form_items=0
|
||||
_form_labels=
|
||||
_form_text=
|
||||
}
|
||||
|
||||
formItem() {
|
||||
_form_labels[$_form_items]=$1
|
||||
_form_text[$_form_items]=$2
|
||||
let "_form_items += 1"
|
||||
}
|
||||
|
||||
formDisplay() {
|
||||
local temp=$(@MKTEMP@ -t backupninja.XXXXXX) || exit 1
|
||||
|
||||
max_length=0
|
||||
for ((i=0; i < ${#_form_labels[@]} ; i++)); do
|
||||
label=${_form_labels[$i]}
|
||||
length=`expr length $label`
|
||||
if [ $length -gt $max_length ]; then
|
||||
max_length=$length
|
||||
fi
|
||||
done
|
||||
let "max_length += 2"
|
||||
|
||||
local xpos=1
|
||||
(
|
||||
echo -n -e "--form '$_form_title' 0 0 20"
|
||||
for ((i=0; i < $_form_items ; i++)); do
|
||||
label=${_form_labels[$i]}
|
||||
text=${_form_text[$i]}
|
||||
echo -n -e " $label $xpos 1 '$text' $xpos $max_length 30 30"
|
||||
let "xpos += _form_gap"
|
||||
done
|
||||
) | xargs $DIALOG 2> $temp
|
||||
local status=$?
|
||||
|
||||
##
|
||||
## the exit status is meaningless, it is always 0.
|
||||
## i can't figure out how to get the exit status of dialog
|
||||
## if we do "dialog `arg code`" or "dialog $args", then the quotes
|
||||
## get messed up and dialog won't run.
|
||||
## if we do "(arg code) | xargs dialog", then the exit status is
|
||||
## swallowed by xargs. xargs should return different exit status
|
||||
## depending on the exit status of the command run, but i have
|
||||
## never been able to get that to work.
|
||||
##
|
||||
|
||||
REPLY=
|
||||
if [ $status = 0 ]; then
|
||||
IFS=$''
|
||||
REPLY=`cat $temp`
|
||||
IFS=$' \t\n'
|
||||
fi
|
||||
rm -f $temp
|
||||
return $status
|
||||
}
|
130
lib/parseini.in
130
lib/parseini.in
@ -1,130 +0,0 @@
|
||||
# -*- mode: awk; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# parseini --- parses 'ini' style configuration files.
|
||||
#
|
||||
# Usage:
|
||||
# awk -f parseini S=<section> P=<param> <ini file>
|
||||
#
|
||||
# if section is an empty string, then we use the default section
|
||||
#
|
||||
# example ini file:
|
||||
#
|
||||
# fruit = apple
|
||||
# fruit = pear
|
||||
# multiline = this is a multiline \
|
||||
# parameter
|
||||
#
|
||||
# # this is a comment
|
||||
# [colors]
|
||||
# red = yes
|
||||
# green = no
|
||||
# blue = maybe
|
||||
#
|
||||
# [ocean]
|
||||
# fish = red
|
||||
# fish = blue
|
||||
#
|
||||
# example usage:
|
||||
# > awk -f parseini S=ocean P=fish testfile.ini
|
||||
# would return:
|
||||
# red
|
||||
# blue
|
||||
#
|
||||
|
||||
BEGIN {
|
||||
readlines = 1
|
||||
implied = 1
|
||||
}
|
||||
|
||||
# remove lines starting with #, but not #!
|
||||
/^#[^!]/ {next}
|
||||
|
||||
# skip blank
|
||||
/^[ \r\t]*$/ {next}
|
||||
|
||||
# we want to read the lines of the matched section
|
||||
# and disable for other sections
|
||||
/^\[.+\][ \r\t]*$/ {
|
||||
continueline = 0
|
||||
if (S && implied) {
|
||||
nline = 0
|
||||
implied = 0
|
||||
}
|
||||
if (S && match($0, "^\\[" S "\\][ \n]*")) {
|
||||
# we found the section, so start reading.
|
||||
readlines = 1
|
||||
}
|
||||
else {
|
||||
# no section, so stop reading lines
|
||||
if (readlines) readlines = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
# when reading, store lines.
|
||||
|
||||
{
|
||||
if (!readlines) next
|
||||
line[nline++] = $0
|
||||
if ($0 ~ /\\[ \r\t]*$/)
|
||||
continueline = 1
|
||||
else
|
||||
continueline = 0
|
||||
}
|
||||
|
||||
# process the read lines lines, matching parameters
|
||||
|
||||
END {
|
||||
# if section is set but implied is still true
|
||||
# then we never found the section, so use everything
|
||||
if (S && implied) {
|
||||
nline = 0
|
||||
}
|
||||
|
||||
# if have P then find P in read lines and get values
|
||||
if (P) {
|
||||
MATCH = "^[ \r\t]*" P "[ \r\t]*="
|
||||
continueline = 0
|
||||
for (x = 0; x < nline; ++x) {
|
||||
v = line[x]
|
||||
if (continueline) {
|
||||
sub(/[ \r\t]+$/, "", v)
|
||||
if (v ~ /\\$/) {
|
||||
v = substr(v, 1, length(v)-1)
|
||||
sub(/[ \r\t]+$/, "", v)
|
||||
}
|
||||
if (v) value[nvalue++] = v
|
||||
}
|
||||
else if (v ~ MATCH) {
|
||||
sub(MATCH, "", v)
|
||||
sub(/^[ \r\t]+/, "", v)
|
||||
sub(/[ \r\t]+$/, "", v)
|
||||
if (v ~ /\\$/) {
|
||||
continueline = 1
|
||||
v = substr(v, 1, length(v)-1)
|
||||
sub(/[ \r\t]+$/, "", v)
|
||||
}
|
||||
if (v) value[nvalue++] = v
|
||||
}
|
||||
}
|
||||
# copy parameter definition to output array
|
||||
nline = nvalue
|
||||
for (x = 0; x < nvalue; ++x)
|
||||
line[x] = value[x]
|
||||
}
|
||||
|
||||
# trim all leading & trailing whitespace;
|
||||
# except for leading whitespace in continuation lines,
|
||||
|
||||
for (x = 0; x < nline; ++x) {
|
||||
sub(/^[ \r\t]+/, "", line[x])
|
||||
sub(/[ \r\t]+$/, "", line[x])
|
||||
}
|
||||
|
||||
# output the final result
|
||||
for (x = 0; x < nline; ++x)
|
||||
print line[x]
|
||||
|
||||
if (nline) exit 0
|
||||
else exit 1
|
||||
}
|
48
lib/tools.in
48
lib/tools.in
@ -1,48 +0,0 @@
|
||||
#!@BASH@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
# This file contains functions shared between ninjahelper and backupninja.
|
||||
|
||||
#####################################################
|
||||
## MISC FUNCTIONS
|
||||
|
||||
#
|
||||
# create a temporary file in a secure way.
|
||||
#
|
||||
function maketemp() {
|
||||
local tempfile=`mktemp /tmp/$1.XXXXXXXX`
|
||||
echo $tempfile
|
||||
}
|
||||
|
||||
#####################################################
|
||||
## CONFIG-FILE RELATED FUNCTIONS
|
||||
|
||||
function setfile() {
|
||||
CURRENT_CONF_FILE=$1
|
||||
}
|
||||
|
||||
function setsection() {
|
||||
CURRENT_SECTION=$1
|
||||
}
|
||||
|
||||
#
|
||||
# sets a global var with name equal to $1
|
||||
# to the value of the configuration parameter $1
|
||||
# $2 is the default.
|
||||
#
|
||||
function getconf() {
|
||||
CURRENT_PARAM=$1
|
||||
ret=`@AWK@ -f $libdirectory/parseini S=$CURRENT_SECTION P=$CURRENT_PARAM $CURRENT_CONF_FILE`
|
||||
# if nothing is returned, set the default
|
||||
if [ "$ret" == "" -a "$2" != "" ]; then
|
||||
ret="$2"
|
||||
fi
|
||||
|
||||
# replace * with %, so that it is not globbed.
|
||||
ret="${ret//\\*/__star__}"
|
||||
|
||||
# this is weird, but single quotes are needed to
|
||||
# allow for returned values with spaces. $ret is still expanded
|
||||
# because it is in an 'eval' statement.
|
||||
eval $1='$ret'
|
||||
}
|
250
lib/vserver.in
250
lib/vserver.in
@ -1,250 +0,0 @@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
#####################################################
|
||||
## VSERVERS RELATED FUNCTIONS FOR NINJAHELPER
|
||||
##
|
||||
## Depends on:
|
||||
## - easydialog library
|
||||
## - $conffile
|
||||
##
|
||||
## Global variables used and modified here:
|
||||
## - $vservers_are_available (yes/no)
|
||||
## - $found_vservers (list)
|
||||
## - $selected_vservers (list)
|
||||
## - $host_or_vservers (host/vservers/both)
|
||||
##
|
||||
|
||||
##
|
||||
## Get vservers-related variables.
|
||||
## Then, if Vservers are enabled, check that:
|
||||
## - VROOTDIR is valid;
|
||||
## - at least one vserver can be found.
|
||||
## If, and only if, the above conditions are all true:
|
||||
## - set $vservers_are_available to 'yes';
|
||||
## - set $found_vservers to the list of all vservers found on the system.
|
||||
## This function has to be run once before a new helper is run.
|
||||
## If the argument is "nodialog", use the backupninja's message functions
|
||||
## instead of easydialog.
|
||||
##
|
||||
init_vservers() {
|
||||
local arg=$1
|
||||
# get global variables from the conffile
|
||||
setfile $conffile
|
||||
getconf vservers no
|
||||
getconf VSERVERINFO /usr/sbin/vserver-info
|
||||
getconf VSERVER /usr/sbin/vserver
|
||||
getconf VROOTDIR `if [ -x "$VSERVERINFO" ]; then $VSERVERINFO info SYSINFO | grep '^ *vserver-Rootdir' | @AWK@ '{print $2}'; fi`
|
||||
# canonicalize VROOTDIR
|
||||
[ -z "$VROOTDIR" ] || VROOTDIR=`readlink --canonicalize $VROOTDIR`
|
||||
# init this library's global variables
|
||||
vservers_are_available=no
|
||||
found_vservers=
|
||||
selected_vservers=
|
||||
host_or_vservers=host
|
||||
# check vservers real availability
|
||||
if [ $vservers = yes ]; then
|
||||
if [ ! -x "$VSERVERINFO" ]; then
|
||||
`if [ "$arg" = nodialog ]; then echo fatal; else echo "msgBox warning"; fi` \
|
||||
"vservers enabled in $conffile, but vserver-info command was not found. Please set the VSERVERINFO configuration variable to its full path."
|
||||
return
|
||||
fi
|
||||
if [ ! -x "$VSERVER" ]; then
|
||||
`if [ "$arg" = nodialog ]; then echo fatal; else echo "msgBox warning"; fi` \
|
||||
"vservers enabled in $conffile, but vserver command was not found. Please set the VSERVER configuration variable to its full path."
|
||||
return
|
||||
fi
|
||||
if [ -z "$VROOTDIR" ]; then
|
||||
`if [ "$arg" = nodialog ]; then echo fatal; else echo "msgBox warning"; fi` \
|
||||
"vservers enabled in $conffile, but VROOTDIR is not set and could not be guessed."
|
||||
return
|
||||
fi
|
||||
if [ ! -d "$VROOTDIR" ]; then
|
||||
`if [ "$arg" = nodialog ]; then echo fatal; else echo "msgBox warning"; fi` \
|
||||
"vservers enabled in $conffile, but VROOTDIR ($VROOTDIR) does not exist.";
|
||||
return
|
||||
fi
|
||||
found_vservers=`ls $VROOTDIR | grep -E -v "lost\+found|ARCHIVES" | tr "\n" " "`
|
||||
if [ -z "$found_vservers" ]; then
|
||||
`if [ "$arg" = nodialog ]; then echo warning; else echo "msgBox warning"; fi` \
|
||||
"vservers enabled in $conffile, but no vserver was found in $VROOTDIR.";
|
||||
return
|
||||
fi
|
||||
vservers_are_available=yes
|
||||
fi
|
||||
}
|
||||
|
||||
##
|
||||
## If all the arguments are existing vservers names, returns 0.
|
||||
## Else, returns 1. Also returns 1 if no argument is given.
|
||||
##
|
||||
vservers_exist() {
|
||||
[ $# -ge 1 ] || return 1
|
||||
local args="$1"
|
||||
local vserver i found
|
||||
for vserver in $args ; do
|
||||
found=no
|
||||
for i in $found_vservers ; do
|
||||
if [ $vserver = $i ]; then
|
||||
found=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ $found = yes ] || return 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
##
|
||||
## If all the arguments are running vservers names, returns 0.
|
||||
## Else, returns 1. Also returns 1 if no argument is given.
|
||||
##
|
||||
vservers_running() {
|
||||
[ $# -ge 1 ] || return 1
|
||||
local args="$1"
|
||||
local vserver
|
||||
for vserver in $args ; do
|
||||
$VSERVERINFO -q $vserver RUNNING || return 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
##
|
||||
## If the argument is the name of a vserver selected by the current helper,
|
||||
## echoes 'on' and returns 0.
|
||||
## Else, echoes 'off' and returns 1.
|
||||
##
|
||||
vserver_is_selected() {
|
||||
local vserver=$1
|
||||
local vserver_is_selected=1
|
||||
local i
|
||||
for i in $selected_vservers ; do
|
||||
[ "$vserver" == "$i" ] && vserver_is_selected=0
|
||||
done
|
||||
if [ $vserver_is_selected = 0 ]; then
|
||||
echo on
|
||||
else
|
||||
echo off
|
||||
fi
|
||||
return $vserver_is_selected
|
||||
}
|
||||
|
||||
##
|
||||
## Have the user choose one Vserver among the existing ones.
|
||||
## Set $selected_vservers to the chosen one's name.
|
||||
## Returns 1 if cancelled or if Vservers are not available.
|
||||
##
|
||||
choose_one_vserver() {
|
||||
[ "$vservers_are_available" == "yes" ] || return 1
|
||||
local title=$1
|
||||
local i=
|
||||
local vserver=
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
[ -n "$selected_vservers" ] && setDefault $selected_vservers
|
||||
listBegin "$title" "Choose at least one Linux-Vserver to backup:"
|
||||
for vserver in $found_vservers; do
|
||||
listItem "$vserver" "Backup $vserver vserver"
|
||||
done
|
||||
listDisplay menu
|
||||
[ $? = 0 ] || return 1
|
||||
done
|
||||
selected_vservers=$REPLY
|
||||
}
|
||||
|
||||
##
|
||||
## If Vservers are not enabled, set host_or_vservers='host' and then return
|
||||
## Else, have the user choose if he/she wants to perform the backup on the host
|
||||
## system or on one Vserver.
|
||||
## Set, respectively, $host_or_vservers to 'host' or 'vservers'.
|
||||
## Returns 1 if cancelled.
|
||||
##
|
||||
choose_host_or_one_vserver() {
|
||||
if [ "$vservers_are_available" != "yes" ]
|
||||
then
|
||||
host_or_vservers='host'
|
||||
return
|
||||
fi
|
||||
local title=$1
|
||||
# if there is one, set the previously chosen item as the default
|
||||
[ -n "$host_or_vservers" ] && setDefault $host_or_vservers
|
||||
menuBox "$title - src" "Do you want to operate on the host system and/or on vservers?" \
|
||||
"host" "Host system" \
|
||||
"vserver" "One Vserver"
|
||||
[ $? = 0 ] || return 1
|
||||
case $REPLY in
|
||||
"host")
|
||||
host_or_vservers='host'
|
||||
;;
|
||||
"vserver")
|
||||
host_or_vservers='vservers'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
##
|
||||
## If Vservers are not enabled, set host_or_vservers='host' and then return
|
||||
## Else, have the user choose the target he/she wants to perform the backup on:
|
||||
## - host system only;
|
||||
## - some vservers only;
|
||||
## - both the host system and some vservers.
|
||||
## Set, respectively, $host_or_vservers to 'host', 'vservers', or 'both'
|
||||
## Returns 1 if cancelled.
|
||||
##
|
||||
choose_host_or_vservers_or_both() {
|
||||
if [ "$vservers_are_available" != "yes" ]
|
||||
then
|
||||
host_or_vservers='host'
|
||||
return
|
||||
fi
|
||||
local title=$1
|
||||
# if there is one, set the previously chosen item as the default
|
||||
[ -n "$host_or_vservers" ] && setDefault $host_or_vservers
|
||||
menuBox "$title - src" "Do you want to operate on the host system and/or on vservers?" \
|
||||
"host" "Host system only" \
|
||||
"vservers" "Vservers only" \
|
||||
"both" "Host system and Vservers"
|
||||
[ $? = 0 ] || return 1
|
||||
case $REPLY in
|
||||
"host")
|
||||
host_or_vservers='host'
|
||||
;;
|
||||
"vservers")
|
||||
host_or_vservers='vservers'
|
||||
;;
|
||||
"both")
|
||||
host_or_vservers='both'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
##
|
||||
## Have the user choose among "all vservers" and a not-empty subset of these.
|
||||
## Set $selected_vservers to 'all' or to a space-separated name list.
|
||||
## Returns 1 if cancelled or if Vservers are not available.
|
||||
##
|
||||
choose_one_or_more_vservers() {
|
||||
[ "$vservers_are_available" == "yes" ] || return 1
|
||||
local title=$1
|
||||
local i=
|
||||
# UI
|
||||
booleanBox "$title" "Do you want to backup all vservers?" ` [ -z "$selected_vservers" -o "$selected_vservers" == "all" ] || echo no`
|
||||
if [ $? = 0 ]; then
|
||||
selected_vservers="all"
|
||||
else
|
||||
# choose among the existing vservers
|
||||
local vserver=
|
||||
local vserver_was_selected=
|
||||
REPLY=
|
||||
while [ -z "$REPLY" ]; do
|
||||
listBegin "$title" "Choose at least one Linux-Vserver to backup:"
|
||||
# list existing vservers, preselecting the previously selected ones
|
||||
for vserver in $found_vservers; do
|
||||
listItem "$vserver" "Backup $vserver vserver" `vserver_is_selected $vserver`
|
||||
done
|
||||
listDisplay checklist
|
||||
[ $? = 0 ] || return 1
|
||||
done
|
||||
# remove quotes around each vserver name
|
||||
selected_vservers=`echo $REPLY | tr -d '"'`
|
||||
fi
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
|
||||
man_MANS = backup.d.5 backupninja.conf.5 backupninja.1 ninjahelper.1
|
||||
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
107
man/backup.d.5
107
man/backup.d.5
@ -1,107 +0,0 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH BACKUP.D 5 "October 10, 2005" "riseup" "backupninja package"
|
||||
.SH NAME
|
||||
BACKUP.D \- Action configuration files for \fBbackupninja(1)\fP.
|
||||
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.br
|
||||
.SH SYNOPSIS
|
||||
.B "/etc/backup.d/* "
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
|
||||
To preform the actual backup actions, backupninja processes each action configuration file in
|
||||
/etc/backup.d according to the file's suffix.
|
||||
|
||||
.IP .sh 10
|
||||
run this file as a shell script.
|
||||
.IP .rdiff
|
||||
backup action for rdiff-backup.
|
||||
.IP .dup
|
||||
backup action for duplicity.
|
||||
.IP .maildir
|
||||
backup action for slow, incremental rsyncs of tens of thousands of maildirs.
|
||||
.IP .mysql
|
||||
backup action for safe MySQL dumps.
|
||||
.IP .pgsql
|
||||
backup action for safe PostgreSQL dumps.
|
||||
.IP .ldap
|
||||
backup action for safe OpenLdap dumps.
|
||||
.IP .sys
|
||||
backup action for general system reports and hardware information.
|
||||
.IP .svn
|
||||
backup action for safe backups of subversion repositories.
|
||||
.IP .trac
|
||||
backup action for safe backups of trac repositories.
|
||||
.IP .makecd
|
||||
backup action for burning backups to CD/DVD or creating ISOs.
|
||||
|
||||
.TP
|
||||
These files must be owned by root and must not be world or group readable/writable. Support for additional configuration types can be added by dropping bash scripts with the name of the suffix into /usr/share/backupninja.
|
||||
.TP
|
||||
The configuration files are processed in alphabetical order. However, it is suggested that you name the config files in "sysvinit style."
|
||||
.TP
|
||||
For example:
|
||||
10-local.ldap.disabled
|
||||
15-runthisfirst.sh
|
||||
20-runthisnext.mysql
|
||||
90-runthislast.rdiff
|
||||
.TP
|
||||
Typically, you will put a '.rdiff' config file last, so that any database dumps you make are included in the filesystem backup. Action configurations which end with .disabled are skipped.
|
||||
.TP
|
||||
Example templates for the action configuration files can be found in /usr/share/doc/backupninja/examples. You can also use \fBninjahelper(1)\fP, a console based "wizard" for creating backup actions.
|
||||
|
||||
.SH SCHEDULING
|
||||
|
||||
By default, each configuration file is processed everyday at 01:00 (1 AM). This can be changed by specifying the 'when' option in a backup action's config file or in the global configuration file. Special value 'manual' will disable scheduling for the backup action. It is possible to run the backup action manually by invoking \fBninjahelper(1)\fP with --run command line argument.
|
||||
|
||||
For example:
|
||||
when = sundays at 02:00
|
||||
when = 30th at 22
|
||||
when = 30 at 22:00
|
||||
when = everyday at 01
|
||||
when = Tuesday at 05:00
|
||||
when = hourly
|
||||
when = manual
|
||||
|
||||
These values for "when" are invalid:
|
||||
when = tuesday at 2am
|
||||
when = tuesday at 2
|
||||
when = tues at 02
|
||||
|
||||
A configuration file will be processed at the time(s) specified by the "when" option. If multiple "when" options are present, then they all apply. If two configurations files are scheduled to run in the same hour, then we fall back on the alphabetical ordering specified above. The "when" must occur before any sections in the action configuration file.
|
||||
|
||||
.SH FILE FORMAT
|
||||
|
||||
The file format of the action configuration files is "ini style." Sections are created by using square bracket. Long lines are connected with a backslash. For example:
|
||||
|
||||
# this is a comment
|
||||
[fishes]
|
||||
fish = red
|
||||
fish = blue
|
||||
[fruit]
|
||||
apple = yes
|
||||
pear = no thanks \\
|
||||
i will not have a pear.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR backupninja (1),
|
||||
.BR ninjahelper (1),
|
||||
.BR backupninja.conf (5),
|
||||
.br
|
||||
.SH AUTHOR
|
||||
BACKUPNINJA was written by the riseup.net collective.
|
@ -1,137 +0,0 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH BACKUPNINJA 1 "October 10, 2005" "riseup" "backupninja package"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
BACKUPNINJA \- A lightweight, extensible meta-backup system
|
||||
.br
|
||||
.I
|
||||
"a silent flower blossom death strike to lost data."
|
||||
.SH SYNOPSIS
|
||||
.B "backupninja [ \-h ] [ \-d ] [ \-n ] [ \-t ] [ \-f filename ] [ \-\-run filename ]"
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.B Backupninja
|
||||
allows you to coordinate system backups by dropping a few
|
||||
simple configuration files into /etc/backup.d/. Most programs you
|
||||
might use for making backups don't have their own configuration file
|
||||
format. Backupninja provides a centralized way to configure and
|
||||
coordinate many different backup utilities.
|
||||
.PP
|
||||
|
||||
.SH FEATURES
|
||||
.IP - 2
|
||||
easy to read ini style configuration files.
|
||||
.IP -
|
||||
you can drop in scripts to handle new types of backups.
|
||||
.IP -
|
||||
backup actions can be scheduled.
|
||||
.IP -
|
||||
you can choose when status report emails are mailed to you (always, on warning, on error, never).
|
||||
.IP -
|
||||
console-based wizard (ninjahelper) makes it easy to create backup action configuration files.
|
||||
.IP -
|
||||
passwords are never sent via the command line to helper programs.
|
||||
.IP -
|
||||
in order to backup a db or sql database, you cannot simply copy database files. backupninja helps you safely export the data to a format which you can backup.
|
||||
.IP -
|
||||
works with Linux-Vservers.
|
||||
|
||||
.B Backup types include:
|
||||
.IP - 2
|
||||
secure, remote, incremental filesytem backup (via rdiff-backup). incremental data is compressed. permissions are retained even with an unpriviledged backup user.
|
||||
.IP -
|
||||
basic system and hardware information.
|
||||
.IP -
|
||||
encrypted remote backups (via duplicity).
|
||||
.IP -
|
||||
safe backup of MySQL, PostgreSQL, OpenLDAP, and subversion databases.
|
||||
.IP -
|
||||
burn CD/DVDs or create ISOs.
|
||||
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invoke bold face and italics,
|
||||
.\" respectively.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-h, \-\-help
|
||||
Show summary of options
|
||||
.TP
|
||||
.B \-d, \-\-debug
|
||||
Run in debug mode, where all log messages are output to the current shell.
|
||||
.TP
|
||||
.B \-f, \-\-conffile CONF_FILE
|
||||
Use CONF_FILE for the main configuration instead of /etc/backupninja.conf
|
||||
.TP
|
||||
.B \-t, \-\-test
|
||||
Run in test mode, no actions are actually taken.
|
||||
.TP
|
||||
.B \-n, \-\-now
|
||||
Perform actions now, instead of when they might be scheduled.
|
||||
.TP
|
||||
.B \-\-run ACTION_FILE
|
||||
Runs the action configuration ACTION_FILE and exits.
|
||||
|
||||
.SH CONFIGURATION
|
||||
|
||||
General settings are configured in /etc/backupninja.conf. In this file you
|
||||
can set the log level and change the default directory locations. See \fBbackupninja.conf(5)\fP.
|
||||
|
||||
To preform the actual backup actions, backupninja processes each action configuration file in
|
||||
/etc/backup.d according to the file's suffix. See \fBbackup.d(5)\fP.
|
||||
|
||||
.SH EXAMPLE USAGE
|
||||
.TP
|
||||
Backupninja can be used to impliment whatever backup strategy you choose. It is intended, however, to be used like so:
|
||||
.TP
|
||||
First, databases are safely copied or exported to /var/backups. Often, you cannot make a file backup of a database while it is in use, hence the need to use special tools to make a safe copy or export into /var/backups.
|
||||
.TP
|
||||
Then, vital parts of the file system, including /var/backups, are nightly pushed to a remote, off-site, hard disk (using rdiff-backup). The local user is root, but the remote user is not privileged. Hopefully, the remote filesystem is encrypted.
|
||||
.TP
|
||||
In order for this to work (ie for diff-backup to run unattended), you must create ssh keys on the source server and copy the public key to the remote user's authorized keys file. For example:
|
||||
.br
|
||||
root@srchost# ssh-keygen -t dsa
|
||||
.br
|
||||
root@srchost# ssh-copy-id -i /root/.ssh/id_dsa.pub backup@desthost
|
||||
.TP
|
||||
Now, you should be able to ssh from user 'root' on srchost to user 'backup' on desthost without specifying a password. When prompted for a password by ssh-keygen, just leave it blank by hitting return. The "wizard" \fBninjahelper(1)\fP will walk you through these steps.
|
||||
|
||||
.SH FILES
|
||||
.PD 0
|
||||
\fB/usr/sbin/backupninja\fP main script
|
||||
.br
|
||||
\fB/etc/backupninja.conf\fP main configuration file; general options
|
||||
.br
|
||||
\fB/etc/cron.d/backupninja\fP runs main script hourly
|
||||
.br
|
||||
\fB/etc/logrotate.d/backupninja\fP rotates backupninja.log
|
||||
.br
|
||||
\fB/etc/backup.d\fP directory for configuration files
|
||||
.br
|
||||
\fB/usr/share/backupninja\fP directory for handler scripts
|
||||
.br
|
||||
\fB/usr/share/doc/backupninja/examples\fP example action configuration files.
|
||||
.br
|
||||
.PD
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR ninjahelper (1),
|
||||
.BR backupninja.conf (5),
|
||||
.BR backup.d (5),
|
||||
.br
|
||||
.SH AUTHOR
|
||||
BACKUPNINJA was written by the riseup.net collective.
|
@ -1,134 +0,0 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH BACKUPNINJA.CONF 5 "November 19, 2005" "riseup" "backupninja package"
|
||||
.SH NAME
|
||||
BACKUPNINJA.CONF \- Configuration file(s) for \fBbackupninja (1)\fP.
|
||||
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.br
|
||||
.SH SYNOPSIS
|
||||
.B "/etc/backupninja.conf "
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.B backupninja.conf
|
||||
is the general configuration file. In this file you can set the log level and change the default directory locations. You can force a different general configuration file with "backupninja -f /path/to/conf".
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
.B loglevel
|
||||
How verbose to make the logs.
|
||||
.br
|
||||
5 = Debugging messages
|
||||
.br
|
||||
4 = Informational messages
|
||||
.br
|
||||
3 = Warnings
|
||||
.br
|
||||
2 = Errors
|
||||
.br
|
||||
1 = Fatal errors
|
||||
|
||||
.TP
|
||||
.B reportemail
|
||||
Send a summary of the backup status to this email address
|
||||
|
||||
.TP
|
||||
.B reportsuccess
|
||||
If set to 'yes', a report email will be generated even if all modules reported success.
|
||||
|
||||
.TP
|
||||
.B reportwarning
|
||||
If set to 'yes', a report email will be generated even if there was no error.
|
||||
|
||||
.TP
|
||||
.B logfile
|
||||
The path of the logfile.
|
||||
|
||||
.TP
|
||||
.B configdirectory
|
||||
The directory where all the backup action configuration files live.
|
||||
|
||||
.TP
|
||||
.B scriptdirectory
|
||||
Where backupninja handler scripts are found
|
||||
|
||||
.TP
|
||||
.B usecolors
|
||||
If set to 'yes', use colors in the log file and debug output.
|
||||
|
||||
.TP
|
||||
.B when
|
||||
When to process each configuration file. The value used here will
|
||||
be applied for each configuration file. It is possibile to override
|
||||
this "when" in each each configuration file, see also section
|
||||
"Scheduling" in backup.d(5).
|
||||
|
||||
For example:
|
||||
|
||||
when = sundays at 02:00
|
||||
when = 30th at 22
|
||||
when = 30 at 22:00
|
||||
when = everyday at 01 <-- the default
|
||||
when = Tuesday at 05:00
|
||||
|
||||
These values for 'when' are equivalent:
|
||||
|
||||
when = tuesday at 05:30
|
||||
when = TUESDAYS at 05
|
||||
|
||||
These values for 'when' are invalid:
|
||||
|
||||
when = tuesday at 2am
|
||||
when = tuesday at 2
|
||||
when = tues at 02
|
||||
|
||||
.TP
|
||||
.B vservers
|
||||
If you are using Linux-Vservers (http://linux-vserver.org), there are some
|
||||
special capabilities that different handlers have to make vserver backups easier.
|
||||
See the example configuration files for each handler to configure the vserver specific
|
||||
variables.
|
||||
|
||||
.SH DEFAULTS
|
||||
|
||||
loglevel = 4
|
||||
.br
|
||||
reportemail = root
|
||||
.br
|
||||
reportsuccess = yes
|
||||
.br
|
||||
reportwarning = yes
|
||||
.br
|
||||
logfile = /var/log/backupninja.log
|
||||
.br
|
||||
configdirectory = /etc/backup.d
|
||||
.br
|
||||
scriptdirectory = /usr/share/backupninja
|
||||
.br
|
||||
usecolors = yes
|
||||
.br
|
||||
when = everyday at 01:00
|
||||
.br
|
||||
vservers = no
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR backupninja (1),
|
||||
.BR ninjahelper (1),
|
||||
.BR backup.d (5),
|
||||
.br
|
||||
.SH AUTHOR
|
||||
BACKUPNINJA was written by the riseup.net collective.
|
@ -1,62 +0,0 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH NINJAHELPER 1 "january 19, 2006" "riseup" "backupninja package"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
NINJAHELPER \- A menu driven curses-based interface to walk you through
|
||||
backupninja configuration.
|
||||
.br
|
||||
.SH SYNOPSIS
|
||||
.B "ninjahelper"
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.B Ninjahelper
|
||||
is an helper script to walk you through configuration of the backup
|
||||
tasks for backupninja. It is a curses based "wizard" with an intuitive
|
||||
menu-driven interface.
|
||||
.PP
|
||||
.SH ADDING NEW HELPERS
|
||||
.br
|
||||
To add an additional 'wizard' to ninjahelper, follow these steps:
|
||||
.IP (1)
|
||||
create a file in the handlers directory (eg. /usr/share/backupninja) using
|
||||
the .helper extention. For example, if you wish to create a helper for the
|
||||
handler "blue", create the file /usr/share/backupninja/blue.helper.
|
||||
.IP (2)
|
||||
next, add your helper to the global HELPERS variable and define the main
|
||||
function for your helper (the function name is always <helper>_wizard). To
|
||||
use the blue.helper as an example:
|
||||
HELPERS="$HELPERS blue:description_of_this_helper"
|
||||
blue_wizard() {
|
||||
... do work here ...
|
||||
}
|
||||
.IP (3)
|
||||
look at the existing helpers to see how they are written. Try to re-use
|
||||
functions, such as the dialog functions that are defined in easydialog.sh,
|
||||
or the vserver functions defined in lib/vserver.
|
||||
.IP (4)
|
||||
test, re-test, and test again. Try to break the helper by going backwards,
|
||||
try to think like someone who has no idea how to configure your handler
|
||||
would think, try to make your helper as simple as possible. Walk like a cat,
|
||||
become your shadow, don't let your senses betray you.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR backupninja (1),
|
||||
.BR backupninja.conf (5),
|
||||
.BR backup.d (5),
|
||||
.br
|
||||
.SH AUTHOR
|
||||
BACKUPNINJA was written by the riseup.net collective.
|
@ -1,34 +0,0 @@
|
||||
# tyhle vygenerujeme ...
|
||||
sbin_SCRIPTS = backupninja ninjahelper
|
||||
|
||||
# a proto je taky musíme smazat ...
|
||||
CLEANFILES = $(sbin_SCRIPTS)
|
||||
|
||||
EXTRA_DIST = backupninja.in ninjahelper.in ninjareport.in
|
||||
|
||||
edit = sed \
|
||||
-e "s,@CFGDIR\@,$(CFGDIR),g" \
|
||||
-e "s,@BASH\@,$(BASH),g" \
|
||||
-e "s,@AWK\@,$(AWK),g" \
|
||||
-e "s,@SED\@,$(SED),g" \
|
||||
-e 's,@datadir\@,$(pkgdatadir),g' \
|
||||
-e "s,@libdir\@,$(pkglibdir),g" \
|
||||
-e 's,@localstatedir\@,$(localstatedir),g' \
|
||||
-e 's,@prefix\@,$(prefix),g'
|
||||
|
||||
#install-exec-hook:
|
||||
|
||||
backupninja: $(srcdir)/backupninja.in
|
||||
rm -f backupninja
|
||||
$(edit) $(srcdir)/backupninja.in > backupninja
|
||||
chmod ugo+x backupninja
|
||||
|
||||
ninjahelper: $(srcdir)/ninjahelper.in
|
||||
rm -f ninjahelper
|
||||
$(edit) $(srcdir)/ninjahelper.in > ninjahelper
|
||||
chmod ugo+x ninjahelper
|
||||
|
||||
ninjareport: $(srcdir)/ninjareport.in
|
||||
rm -f ninjareport
|
||||
$(edit) $(srcdir)/ninjareport.in > ninjareport
|
||||
chmod ugo+x ninjareport
|
@ -1,586 +0,0 @@
|
||||
#!@BASH@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
# |\_
|
||||
# B A C K U P N I N J A /()/
|
||||
# `\|
|
||||
#
|
||||
# Copyright (C) 2004-05 riseup.net -- property is theft.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
|
||||
#####################################################
|
||||
## FUNCTIONS
|
||||
|
||||
function setupcolors () {
|
||||
BLUE="\033[34;01m"
|
||||
GREEN="\033[32;01m"
|
||||
YELLOW="\033[33;01m"
|
||||
PURPLE="\033[35;01m"
|
||||
RED="\033[31;01m"
|
||||
OFF="\033[0m"
|
||||
CYAN="\033[36;01m"
|
||||
COLORS=($BLUE $GREEN $YELLOW $RED $PURPLE $CYAN)
|
||||
}
|
||||
|
||||
function colorize () {
|
||||
if [ "$usecolors" == "yes" ]; then
|
||||
local typestr=`echo "$@" | @SED@ 's/\(^[^:]*\).*$/\1/'`
|
||||
[ "$typestr" == "Debug" ] && type=0
|
||||
[ "$typestr" == "Info" ] && type=1
|
||||
[ "$typestr" == "Warning" ] && type=2
|
||||
[ "$typestr" == "Error" ] && type=3
|
||||
[ "$typestr" == "Fatal" ] && type=4
|
||||
[ "$typestr" == "Halt" ] && type=5
|
||||
color=${COLORS[$type]}
|
||||
endcolor=$OFF
|
||||
echo -e "$color$@$endcolor"
|
||||
else
|
||||
echo -e "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# We have the following message levels:
|
||||
# 0 - debug - blue
|
||||
# 1 - normal messages - green
|
||||
# 2 - warnings - yellow
|
||||
# 3 - errors - red
|
||||
# 4 - fatal - purple
|
||||
# 5 - halt - cyan
|
||||
# First variable passed is the error level, all others are printed
|
||||
|
||||
# if 1, echo out all warnings, errors, or fatal
|
||||
# used to capture output from handlers
|
||||
echo_debug_msg=0
|
||||
|
||||
usecolors=yes
|
||||
|
||||
function printmsg() {
|
||||
[ ${#@} -gt 1 ] || return
|
||||
|
||||
type=$1
|
||||
shift
|
||||
if [ $type == 100 ]; then
|
||||
typestr=`echo "$@" | @SED@ 's/\(^[^:]*\).*$/\1/'`
|
||||
[ "$typestr" == "Debug" ] && type=0
|
||||
[ "$typestr" == "Info" ] && type=1
|
||||
[ "$typestr" == "Warning" ] && type=2
|
||||
[ "$typestr" == "Error" ] && type=3
|
||||
[ "$typestr" == "Fatal" ] && type=4
|
||||
[ "$typestr" == "Halt" ] && type=5
|
||||
typestr=""
|
||||
else
|
||||
types=(Debug Info Warning Error Fatal Halt)
|
||||
typestr="${types[$type]}: "
|
||||
fi
|
||||
|
||||
print=$[4-type]
|
||||
|
||||
if [ $echo_debug_msg == 1 ]; then
|
||||
echo -e "$typestr$@" >&2
|
||||
elif [ $debug ]; then
|
||||
colorize "$typestr$@" >&2
|
||||
fi
|
||||
|
||||
if [ $print -lt $loglevel ]; then
|
||||
logmsg "$typestr$@"
|
||||
fi
|
||||
}
|
||||
|
||||
function logmsg() {
|
||||
if [ -w "$logfile" ]; then
|
||||
echo -e `LC_ALL=C date "+%h %d %H:%M:%S"` "$@" >> $logfile
|
||||
fi
|
||||
}
|
||||
|
||||
function passthru() {
|
||||
printmsg 100 "$@"
|
||||
}
|
||||
function debug() {
|
||||
printmsg 0 "$@"
|
||||
}
|
||||
function info() {
|
||||
printmsg 1 "$@"
|
||||
}
|
||||
function warning() {
|
||||
printmsg 2 "$@"
|
||||
}
|
||||
function error() {
|
||||
printmsg 3 "$@"
|
||||
}
|
||||
function fatal() {
|
||||
printmsg 4 "$@"
|
||||
exit 2
|
||||
}
|
||||
function halt() {
|
||||
printmsg 5 "$@"
|
||||
exit 2
|
||||
}
|
||||
|
||||
msgcount=0
|
||||
function msg {
|
||||
messages[$msgcount]=$1
|
||||
let "msgcount += 1"
|
||||
}
|
||||
|
||||
#
|
||||
# enforces very strict permissions on configuration file $file.
|
||||
#
|
||||
|
||||
function check_perms() {
|
||||
local file=$1
|
||||
debug "check_perms $file"
|
||||
local perms
|
||||
local owners
|
||||
|
||||
perms=($(stat -L --format='%A' $file))
|
||||
debug "perms: $perms"
|
||||
local gperm=${perms:4:3}
|
||||
debug "gperm: $gperm"
|
||||
local wperm=${perms:7:3}
|
||||
debug "wperm: $wperm"
|
||||
|
||||
owners=($(stat -L --format='%g %G %u %U' $file))
|
||||
local gid=${owners[0]}
|
||||
local group=${owners[1]}
|
||||
local owner=${owners[2]}
|
||||
|
||||
if [ "$owner" != 0 ]; then
|
||||
echo "Configuration files must be owned by root! Dying on file $file"
|
||||
fatal "Configuration files must be owned by root! Dying on file $file"
|
||||
fi
|
||||
|
||||
if [ "$wperm" != '---' ]; then
|
||||
echo "Configuration files must not be world writable/readable! Dying on file $file"
|
||||
fatal "Configuration files must not be world writable/readable! Dying on file $file"
|
||||
fi
|
||||
|
||||
if [ "$gperm" != '---' ]; then
|
||||
case "$admingroup" in
|
||||
$gid|$group) :;;
|
||||
|
||||
*)
|
||||
if [ "$gid" != 0 ]; then
|
||||
echo "Configuration files must not be writable/readable by group $group! Use the admingroup option in backupninja.conf. Dying on file $file"
|
||||
fatal "Configuration files must not be writable/readable by group $group! Use the admingroup option in backupninja.conf. Dying on file $file"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# simple lowercase function
|
||||
function tolower() {
|
||||
echo "$1" | tr '[:upper:]' '[:lower:]'
|
||||
}
|
||||
|
||||
# simple to integer function
|
||||
function toint() {
|
||||
echo "$1" | tr -d '[:alpha:]'
|
||||
}
|
||||
|
||||
#
|
||||
# function isnow(): returns 1 if the time/day passed as $1 matches
|
||||
# the current time/day.
|
||||
#
|
||||
# format is <day> at <time>:
|
||||
# sunday at 16
|
||||
# 8th at 01
|
||||
# everyday at 22
|
||||
#
|
||||
|
||||
# we grab the current time once, since processing
|
||||
# all the configs might take more than an hour.
|
||||
nowtime=`LC_ALL=C date +%H`
|
||||
nowday=`LC_ALL=C date +%d`
|
||||
nowdayofweek=`LC_ALL=C date +%A`
|
||||
nowdayofweek=`tolower "$nowdayofweek"`
|
||||
|
||||
function isnow() {
|
||||
local when="$1"
|
||||
set -- $when
|
||||
|
||||
[ "$when" == "manual" ] && return 0
|
||||
|
||||
whendayofweek=$1; at=$2; whentime=$3;
|
||||
whenday=`toint "$whendayofweek"`
|
||||
whendayofweek=`tolower "$whendayofweek"`
|
||||
whentime=`echo "$whentime" | @SED@ 's/:[0-9][0-9]$//' | @SED@ -r 's/^([0-9])$/0\1/'`
|
||||
|
||||
if [ "$whendayofweek" == "everyday" -o "$whendayofweek" == "daily" ]; then
|
||||
whendayofweek=$nowdayofweek
|
||||
fi
|
||||
|
||||
if [ "$whenday" == "" ]; then
|
||||
if [ "$whendayofweek" != "$nowdayofweek" ]; then
|
||||
whendayofweek=${whendayofweek%s}
|
||||
if [ "$whendayofweek" != "$nowdayofweek" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
elif [ "$whenday" != "$nowday" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
[ "$at" == "at" ] || return 0
|
||||
[ "$whentime" == "$nowtime" ] || return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function usage() {
|
||||
cat << EOF
|
||||
$0 usage:
|
||||
This script allows you to coordinate system backup by dropping a few
|
||||
simple configuration files into @CFGDIR@/backup.d/. Typically, this
|
||||
script is run hourly from cron.
|
||||
|
||||
The following options are available:
|
||||
-h, --help This usage message
|
||||
-d, --debug Run in debug mode, where all log messages are
|
||||
output to the current shell.
|
||||
-f, --conffile FILE Use FILE for the main configuration instead
|
||||
of @CFGDIR@/backupninja.conf
|
||||
-t, --test Test run mode. This will test if the backup
|
||||
could run, without actually preforming any
|
||||
backups. For example, it will attempt to authenticate
|
||||
or test that ssh keys are set correctly.
|
||||
-n, --now Perform actions now, instead of when they might
|
||||
be scheduled. No output will be created unless also
|
||||
run with -d.
|
||||
--run FILE Execute the specified action file and then exit.
|
||||
Also puts backupninja in debug mode.
|
||||
|
||||
When in debug mode, output to the console will be colored:
|
||||
EOF
|
||||
usecolors=yes
|
||||
colorize "Debug: Debugging info (when run with -d)"
|
||||
colorize "Info: Informational messages (verbosity level 4)"
|
||||
colorize "Warning: Warnings (verbosity level 3 and up)"
|
||||
colorize "Error: Errors (verbosity level 2 and up)"
|
||||
colorize "Fatal: Errors which halt a given backup action (always shown)"
|
||||
colorize "Halt: Errors which halt the whole backupninja run (always shown)"
|
||||
}
|
||||
|
||||
##
|
||||
## this function handles the running of a backup action
|
||||
##
|
||||
## these globals are modified:
|
||||
## halts, fatals, errors, warnings, actions_run, errormsg
|
||||
##
|
||||
|
||||
function process_action() {
|
||||
local file="$1"
|
||||
local suffix="$2"
|
||||
local run="no"
|
||||
setfile $file
|
||||
|
||||
# skip over this config if "when" option
|
||||
# is not set to the current time.
|
||||
getconf when "$defaultwhen"
|
||||
if [ "$processnow" == 1 ]; then
|
||||
info ">>>> starting action $file (because of --now)"
|
||||
run="yes"
|
||||
elif [ "$when" == "hourly" ]; then
|
||||
info ">>>> starting action $file (because 'when = hourly')"
|
||||
run="yes"
|
||||
else
|
||||
IFS=$'\t\n'
|
||||
for w in $when; do
|
||||
IFS=$' \t\n'
|
||||
isnow "$w"
|
||||
ret=$?
|
||||
IFS=$'\t\n'
|
||||
if [ $ret == 0 ]; then
|
||||
debug "skipping $file because current time does not match $w"
|
||||
else
|
||||
info ">>>> starting action $file (because current time matches $w)"
|
||||
run="yes"
|
||||
fi
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
fi
|
||||
debug $run
|
||||
[ "$run" == "no" ] && return
|
||||
|
||||
let "actions_run += 1"
|
||||
|
||||
# call the handler:
|
||||
local bufferfile=`maketemp backupninja.buffer`
|
||||
echo "" > $bufferfile
|
||||
echo_debug_msg=1
|
||||
(
|
||||
. $scriptdirectory/$suffix $file
|
||||
) 2>&1 | (
|
||||
while read a; do
|
||||
echo $a >> $bufferfile
|
||||
[ $debug ] && colorize "$a"
|
||||
done
|
||||
)
|
||||
retcode=$?
|
||||
# ^^^^^^^^ we have a problem! we can't grab the return code "$?". grrr.
|
||||
echo_debug_msg=0
|
||||
|
||||
_warnings=`cat $bufferfile | grep "^Warning: " | wc -l`
|
||||
_errors=`cat $bufferfile | grep "^Error: " | wc -l`
|
||||
_fatals=`cat $bufferfile | grep "^Fatal: " | wc -l`
|
||||
_halts=`cat $bufferfile | grep "^Halt: " | wc -l`
|
||||
|
||||
ret=`grep "\(^Warning: \|^Error: \|^Fatal: \|Halt: \)" $bufferfile`
|
||||
rm $bufferfile
|
||||
if [ $_halts != 0 ]; then
|
||||
msg "*halt* -- $file"
|
||||
errormsg="$errormsg\n== halt request from $file==\n\n$ret\n"
|
||||
passthru "Halt: <<<< finished action $file: FAILED"
|
||||
elif [ $_fatals != 0 ]; then
|
||||
msg "*failed* -- $file"
|
||||
errormsg="$errormsg\n== fatal errors from $file ==\n\n$ret\n"
|
||||
passthru "Fatal: <<<< finished action $file: FAILED"
|
||||
elif [ $_errors != 0 ]; then
|
||||
msg "*error* -- $file"
|
||||
errormsg="$errormsg\n== errors from $file ==\n\n$ret\n"
|
||||
error "<<<< finished action $file: ERROR"
|
||||
elif [ $_warnings != 0 ]; then
|
||||
msg "*warning* -- $file"
|
||||
errormsg="$errormsg\n== warnings from $file ==\n\n$ret\n"
|
||||
warning "<<<< finished action $file: WARNING"
|
||||
else
|
||||
msg "success -- $file"
|
||||
info "<<<< finished action $file: SUCCESS"
|
||||
fi
|
||||
|
||||
let "halts += _halts"
|
||||
let "fatals += _fatals"
|
||||
let "errors += _errors"
|
||||
let "warnings += _warnings"
|
||||
}
|
||||
|
||||
#####################################################
|
||||
## MAIN
|
||||
|
||||
setupcolors
|
||||
conffile="@CFGDIR@/backupninja.conf"
|
||||
loglevel=3
|
||||
|
||||
## process command line options
|
||||
|
||||
while [ $# -ge 1 ]; do
|
||||
case $1 in
|
||||
-h|--help) usage;;
|
||||
-d|--debug) debug=1;;
|
||||
-t|--test) test=1;debug=1;;
|
||||
-n|--now) processnow=1;;
|
||||
-f|--conffile)
|
||||
if [ -f $2 ]; then
|
||||
conffile=$2
|
||||
else
|
||||
echo "-f|--conffile option must be followed by an existing filename"
|
||||
fatal "-f|--conffile option must be followed by an existing filename"
|
||||
usage
|
||||
fi
|
||||
# we shift here to avoid processing the file path
|
||||
shift
|
||||
;;
|
||||
--run)
|
||||
debug=1
|
||||
if [ -f $2 ]; then
|
||||
singlerun=$2
|
||||
processnow=1
|
||||
else
|
||||
echo "--run option must be followed by a backupninja action file"
|
||||
fatal "--run option must be followed by a backupninja action file"
|
||||
usage
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
debug=1
|
||||
echo "Unknown option $1"
|
||||
fatal "Unknown option $1"
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
#if [ $debug ]; then
|
||||
# usercolors=yes
|
||||
#fi
|
||||
|
||||
## Load and confirm basic configuration values
|
||||
|
||||
# bootstrap
|
||||
if [ ! -r "$conffile" ]; then
|
||||
echo "Configuration file $conffile not found."
|
||||
fatal "Configuration file $conffile not found."
|
||||
fi
|
||||
|
||||
# find $libdirectory
|
||||
libdirectory=`grep '^libdirectory' $conffile | @AWK@ '{print $3}'`
|
||||
if [ -z "$libdirectory" ]; then
|
||||
if [ -d "@libdir@" ]; then
|
||||
libdirectory="@libdir@"
|
||||
else
|
||||
echo "Could not find entry 'libdirectory' in $conffile."
|
||||
fatal "Could not find entry 'libdirectory' in $conffile."
|
||||
fi
|
||||
else
|
||||
if [ ! -d "$libdirectory" ]; then
|
||||
echo "Lib directory $libdirectory not found."
|
||||
fatal "Lib directory $libdirectory not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
# include shared functions
|
||||
. $libdirectory/tools
|
||||
. $libdirectory/vserver
|
||||
|
||||
setfile $conffile
|
||||
|
||||
# get global config options (second param is the default)
|
||||
getconf configdirectory @CFGDIR@/backup.d
|
||||
getconf scriptdirectory @datadir@
|
||||
getconf reportdirectory
|
||||
getconf reportemail
|
||||
getconf reporthost
|
||||
getconf reportspace
|
||||
getconf reportsuccess yes
|
||||
getconf reportuser
|
||||
getconf reportwarning yes
|
||||
getconf loglevel 3
|
||||
getconf when "Everyday at 01:00"
|
||||
defaultwhen=$when
|
||||
getconf logfile @localstatedir@/log/backupninja.log
|
||||
getconf usecolors "yes"
|
||||
getconf SLAPCAT /usr/sbin/slapcat
|
||||
getconf LDAPSEARCH /usr/bin/ldapsearch
|
||||
getconf RDIFFBACKUP /usr/bin/rdiff-backup
|
||||
getconf CSTREAM /usr/bin/cstream
|
||||
getconf MYSQLADMIN /usr/bin/mysqladmin
|
||||
getconf MYSQL /usr/bin/mysql
|
||||
getconf MYSQLHOTCOPY /usr/bin/mysqlhotcopy
|
||||
getconf MYSQLDUMP /usr/bin/mysqldump
|
||||
getconf PGSQLDUMP /usr/bin/pg_dump
|
||||
getconf PGSQLDUMPALL /usr/bin/pg_dumpall
|
||||
getconf PGSQLUSER postgres
|
||||
getconf GZIP /bin/gzip
|
||||
getconf RSYNC /usr/bin/rsync
|
||||
getconf admingroup root
|
||||
|
||||
# initialize vservers support
|
||||
# (get config variables and check real vservers availability)
|
||||
init_vservers nodialog
|
||||
|
||||
if [ ! -d "$configdirectory" ]; then
|
||||
echo "Configuration directory '$configdirectory' not found."
|
||||
fatal "Configuration directory '$configdirectory' not found."
|
||||
fi
|
||||
|
||||
[ -f "$logfile" ] || touch $logfile
|
||||
|
||||
if [ "$UID" != "0" ]; then
|
||||
echo "`basename $0` can only be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Process each configuration file
|
||||
|
||||
# by default, don't make files which are world or group readable.
|
||||
umask 077
|
||||
|
||||
# these globals are set by process_action()
|
||||
halts=0
|
||||
fatals=0
|
||||
errors=0
|
||||
warnings=0
|
||||
actions_run=0
|
||||
errormsg=""
|
||||
|
||||
if [ "$singlerun" ]; then
|
||||
files=$singlerun
|
||||
else
|
||||
files=`find $configdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n`
|
||||
|
||||
if [ -z "$files" ]; then
|
||||
fatal "No backup actions configured in '$configdirectory', run ninjahelper!"
|
||||
fi
|
||||
fi
|
||||
|
||||
for file in $files; do
|
||||
[ -f "$file" ] || continue
|
||||
[ "$halts" = "0" ] || continue
|
||||
|
||||
check_perms ${file%/*} # check containing dir
|
||||
check_perms $file
|
||||
suffix="${file##*.}"
|
||||
base=`basename $file`
|
||||
if [ "${base:0:1}" == "0" -o "$suffix" == "disabled" ]; then
|
||||
info "Skipping $file"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -e "$scriptdirectory/$suffix" ]; then
|
||||
process_action $file $suffix
|
||||
else
|
||||
error "Can't process file '$file': no handler script for suffix '$suffix'"
|
||||
msg "*missing handler* -- $file"
|
||||
fi
|
||||
done
|
||||
|
||||
## mail the messages to the report address
|
||||
|
||||
if [ $actions_run == 0 ]; then doit=0
|
||||
elif [ "$reportemail" == "" ]; then doit=0
|
||||
elif [ $fatals != 0 ]; then doit=1
|
||||
elif [ $errors != 0 ]; then doit=1
|
||||
elif [ "$reportsuccess" == "yes" ]; then doit=1
|
||||
elif [ "$reportwarning" == "yes" -a $warnings != 0 ]; then doit=1
|
||||
else doit=0
|
||||
fi
|
||||
|
||||
if [ $doit == 1 ]; then
|
||||
debug "send report to $reportemail"
|
||||
hostname=`hostname`
|
||||
[ $warnings == 0 ] || subject="WARNING"
|
||||
[ $errors == 0 ] || subject="ERROR"
|
||||
[ $fatals == 0 ] || subject="FAILED"
|
||||
|
||||
{
|
||||
for ((i=0; i < ${#messages[@]} ; i++)); do
|
||||
echo ${messages[$i]}
|
||||
done
|
||||
echo -e "$errormsg"
|
||||
if [ "$reportspace" == "yes" ]; then
|
||||
previous=""
|
||||
for i in $(ls "$configdirectory"); do
|
||||
backuploc=$(grep ^directory "$configdirectory"/"$i" | @AWK@ '{print $3}')
|
||||
if [ "$backuploc" != "$previous" -a -n "$backuploc" ]; then
|
||||
df -h "$backuploc"
|
||||
previous="$backuploc"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
} | mail -s "backupninja: $hostname $subject" $reportemail
|
||||
fi
|
||||
|
||||
if [ $actions_run != 0 ]; then
|
||||
info "FINISHED: $actions_run actions run. $fatals fatal. $errors error. $warnings warning."
|
||||
if [ "$halts" != "0" ]; then
|
||||
info "Backup was halted prematurely. Some actions may not have run."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$reporthost" ]; then
|
||||
debug "send $logfile to $reportuser@$reporthost:$reportdirectory"
|
||||
rsync -qt $logfile $reportuser@$reporthost:$reportdirectory
|
||||
fi
|
@ -1,268 +0,0 @@
|
||||
#!@BASH@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
|
||||
####################################################
|
||||
## Functions
|
||||
|
||||
##
|
||||
## returns the next available file name given a file
|
||||
## in the form @CFGDIR@/backup.d/10.sys
|
||||
## sets variable $next_filename
|
||||
##
|
||||
get_next_filename() {
|
||||
next_filename=$1
|
||||
dir=`dirname $next_filename`
|
||||
file=`basename $next_filename`
|
||||
number=${file:0:2}
|
||||
suffix=${file:3}
|
||||
while [ -f $next_filename ]; do
|
||||
let "number += 1"
|
||||
next_filename="$dir/$number.$suffix"
|
||||
done
|
||||
}
|
||||
|
||||
##
|
||||
## installs packages (passed in as $@) if not present
|
||||
##
|
||||
require_packages() {
|
||||
for pkg in "$@"; do
|
||||
installed=`dpkg -s $pkg | grep 'ok installed'`
|
||||
if [ -z "$installed" ]; then
|
||||
booleanBox "install $pkg?" "This backup action requires package $pkg. Do you want to install it now?"
|
||||
if [ $? = 0 ]; then
|
||||
apt-get install $pkg
|
||||
echo "hit return to continue...."
|
||||
read
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
##
|
||||
## menu for the wizards
|
||||
##
|
||||
donew() {
|
||||
# (re-)initialize vservers support
|
||||
init_vservers
|
||||
# menu
|
||||
listBegin "new action menu" "select an action to create"
|
||||
listItem return "return to main menu"
|
||||
for data in $HELPERS; do
|
||||
data=${data//_/ }
|
||||
helper_function=${data%%:*}
|
||||
helper_info=${data##*:}
|
||||
listItem $helper_function "$helper_info"
|
||||
done
|
||||
listDisplay menu
|
||||
|
||||
[ $? = 1 ] && return
|
||||
result="$REPLY"
|
||||
[ "$result" = "return" -o "$result" = "" ] && return
|
||||
run_wizard=${result}_wizard
|
||||
$run_wizard
|
||||
result=$?
|
||||
# 0 is ok, 1 is cancel, anything else is bad.
|
||||
if [ $result != 1 -a $result != 0 ]; then
|
||||
echo "An error occurred ($result), bailing out. Hit return to continue."
|
||||
read
|
||||
fi
|
||||
}
|
||||
|
||||
do_rm_action() {
|
||||
booleanBox "remove action" "Are you sure you want to remove action file $1?"
|
||||
if [ $? = 0 ]; then
|
||||
rm $1;
|
||||
fi
|
||||
}
|
||||
|
||||
do_run() {
|
||||
backupninja --run $1
|
||||
echo "Hit return to continue..."
|
||||
read
|
||||
}
|
||||
|
||||
do_xedit() {
|
||||
if [ -z "$EDITOR" -o ! -x "`which $EDITOR`" ]; then
|
||||
if [ -h /etc/alternatives/editor -a -x "`readlink /etc/alternatives/editor`" ]; then
|
||||
EDITOR="`readlink /etc/alternatives/editor`"
|
||||
elif [ -x "`which nano`" ]; then
|
||||
EDITOR="`which nano`"
|
||||
elif [ -x "`which vim`" ]; then
|
||||
EDITOR="`which vim`"
|
||||
elif [ -x "`which vi`" ]; then
|
||||
EDITOR="`which vi`"
|
||||
else
|
||||
echo "No suitable editor found."
|
||||
echo "Please define $EDITOR or configure /etc/alternatives/editor."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
$EDITOR $1
|
||||
}
|
||||
|
||||
do_run_test() {
|
||||
backupninja --test --run $1
|
||||
echo "Hit return to continue..."
|
||||
read
|
||||
}
|
||||
|
||||
do_disable() {
|
||||
mv $1 $1.disabled
|
||||
}
|
||||
|
||||
do_enable() {
|
||||
mv $1 ${1%.*}
|
||||
}
|
||||
|
||||
do_rename() {
|
||||
dir=`dirname $1`
|
||||
filename=`basename $1`
|
||||
inputBox "rename action" "enter a new filename" $filename
|
||||
mv $dir/$filename $dir/$REPLY
|
||||
}
|
||||
|
||||
doaction() {
|
||||
action=$1
|
||||
base=`basename $action`
|
||||
if [ "${base##*.}" == "disabled" ]; then
|
||||
enable="enable";
|
||||
else
|
||||
enable="disable";
|
||||
fi
|
||||
while true; do
|
||||
menuBox "action menu" "$action $first" \
|
||||
main "return to main menu" \
|
||||
view "view configuration" \
|
||||
xedit "launch external editor" \
|
||||
$enable "$enable action" \
|
||||
name "change the filename" \
|
||||
run "run this action now" \
|
||||
test "do a test run" \
|
||||
kill "remove this action"
|
||||
[ $? = 1 ] && return;
|
||||
result="$REPLY"
|
||||
case "$result" in
|
||||
"view") dialog --textbox $action 0 0;;
|
||||
"xedit") do_xedit $action;;
|
||||
"disable") do_disable $action; return;;
|
||||
"enable") do_enable $action; return;;
|
||||
"name") do_rename $action; return;;
|
||||
"run") do_run $action;;
|
||||
"test") do_run_test $action;;
|
||||
"kill") do_rm_action $action; return;;
|
||||
"main") return;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
#####################################################
|
||||
## begin program
|
||||
|
||||
if [ ! -x "`which dialog`" ]; then
|
||||
echo "ninjahelper is a menu based wizard for backupninja."
|
||||
echo "It requires 'dialog' in order to run. Do you want to install dialog now?"
|
||||
while true; do
|
||||
echo -n "(yes/no): "
|
||||
read install
|
||||
if [ "$install" == "yes" ]; then
|
||||
apt-get install dialog
|
||||
break
|
||||
elif [ "$install" == "no" ]; then
|
||||
exit
|
||||
else
|
||||
echo "You must answer 'yes' or 'no'"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# bootstrap
|
||||
conffile="@CFGDIR@/backupninja.conf"
|
||||
if [ ! -r "$conffile" ]; then
|
||||
echo "Configuration file $conffile not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# find $libdirectory
|
||||
libdirectory=`grep '^libdirectory' $conffile | @AWK@ '{print $3}'`
|
||||
if [ -z "$libdirectory" ]; then
|
||||
if [ -d "@libdir@" ]; then
|
||||
libdirectory="@libdir@"
|
||||
else
|
||||
echo "Could not find entry 'libdirectory' in $conffile."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ ! -d "$libdirectory" ]; then
|
||||
echo "Lib directory $libdirectory not found."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# include shared functions
|
||||
. $libdirectory/easydialog
|
||||
. $libdirectory/tools
|
||||
. $libdirectory/vserver
|
||||
|
||||
# am I running as root?
|
||||
if [ "$UID" != "0" ]; then
|
||||
msgBox "warning" "`basename $0` must be run by root!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get global config options (second param is the default)
|
||||
setfile $conffile
|
||||
getconf configdirectory @CFGDIR@/backup.d
|
||||
if [ ! -d $configdirectory ]; then
|
||||
msgBox "warning" "The backupninja configuration directory $configdirectory does not exist. Ninjahelper cannot run without it!"
|
||||
exit 1
|
||||
fi
|
||||
getconf scriptdirectory @datadir@
|
||||
|
||||
# load all the helpers
|
||||
HELPERS=""
|
||||
for file in `find $scriptdirectory -follow -name '*.helper'`; do
|
||||
. $file
|
||||
if [ $? != 0 ]; then
|
||||
echo "An error occurred while loading $file. Hit return to continue."
|
||||
read
|
||||
fi
|
||||
done
|
||||
|
||||
setApplicationTitle "ninjahelper"
|
||||
setDimension 75 19
|
||||
|
||||
#####################################################
|
||||
## main event loop
|
||||
|
||||
while true; do
|
||||
|
||||
menulist=
|
||||
action=
|
||||
let "i = 1"
|
||||
for file in `find ${configdirectory} -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n`; do
|
||||
menulist="$menulist $i $file"
|
||||
actions[$i]=$file
|
||||
let "i += 1"
|
||||
done
|
||||
|
||||
menuBox "main menu" "Select a backup action for more options, or create a new action:" $menulist \
|
||||
new "create a new backup action" \
|
||||
quit "leave ninjahelper"
|
||||
|
||||
[ $? = 1 -o $? = 255 ] && exit 0;
|
||||
|
||||
choice="$REPLY"
|
||||
if [ "$choice" == "new" ]; then
|
||||
donew;
|
||||
elif [ "$choice" == "quit" ]; then
|
||||
exit 0;
|
||||
else
|
||||
action=${actions[$choice]};
|
||||
if [ -f "$action" ]; then
|
||||
doaction $action
|
||||
else
|
||||
msgBox "error" "error: cannot find the file '$action'"
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
@ -1,205 +0,0 @@
|
||||
#!@BASH@
|
||||
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
||||
#
|
||||
#
|
||||
# Ninjareport - generate a single simple report for a lot of hosts
|
||||
#
|
||||
# requires logtail
|
||||
#
|
||||
# Copyright (C) 2007 - riseup.net -- property is theft.
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# . check for logs that are never updating and warn
|
||||
# . change constantly updating logs (maildir) to be more friendly
|
||||
# . documentation
|
||||
# . maybe make config option that lists all hosts that should report-in, and if
|
||||
# one doesn't then warn
|
||||
# . restrict rsync somehow?
|
||||
# . abstract path for logtail
|
||||
# . on the report master, the reportdirectory should be set where the reports will be going, note this
|
||||
|
||||
mail=1
|
||||
display=0
|
||||
|
||||
process() {
|
||||
|
||||
# look in the logfile for any lines like the following:
|
||||
# Jan 20 01:02:46 Info: FINISHED: 2 actions run. 0 fatal. 0 error. 0 warning.
|
||||
#
|
||||
# note: some backups never finish, such as the maildir one, need to handle these
|
||||
# perhaps by looking for FAILED messages?
|
||||
# note2: what about logs that aren't being updated? this is a failure case and
|
||||
# should be looked for
|
||||
# note3: there are also these entries:
|
||||
# Jan 20 14:00:01 Fatal: No backup actions configured in '/etc/backup.d', run ninjahelper!
|
||||
|
||||
# The following has to be done without invoking a subshell (see BashFAQ #24)
|
||||
logupdates=`maketemp ninjadata`
|
||||
|
||||
/usr/sbin/logtail -f $host > $logupdates
|
||||
grep FINISHED $logupdates |
|
||||
(
|
||||
fatal=0
|
||||
warning=0
|
||||
error=0
|
||||
|
||||
while read line
|
||||
do
|
||||
line_array=($line)
|
||||
fatal=$(($fatal + ${line_array[8]}))
|
||||
error=$(($error + ${line_array[10]}))
|
||||
warning=$(($warning + ${line_array[12]}))
|
||||
done
|
||||
if (( $fatal || $warning || $error )); then
|
||||
echo "`basename $host .log`: $fatal fatals found, $error errors found, $warning warnings found" >> $statusfile
|
||||
echo "" >> $reportappend
|
||||
echo "`basename $host .log` log entries since last ninjareport" >> $reportappend
|
||||
echo "---------" >> $reportappend
|
||||
cat $logupdates >> $reportappend
|
||||
rm $logupdates
|
||||
fi
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
generatereport() {
|
||||
|
||||
reportfile=`maketemp ninjareport`
|
||||
|
||||
# Generate a report, only if there are failures
|
||||
if [ -s $statusfile ]; then
|
||||
echo " backupninja mission failures - `date`" >> $reportfile
|
||||
echo " --------------------------------------------------------------" >> $reportfile
|
||||
echo "" >> $reportfile
|
||||
cat $statusfile | column -t >> $reportfile
|
||||
echo "" >> $reportfile
|
||||
echo " log entries from failed reports" >> $reportfile
|
||||
echo " -----------------------------------" >> $reportfile
|
||||
cat $reportappend >> $reportfile
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
This script generates a backupninja status report for all configured
|
||||
systems. It requires that each status report is placed in a spot where
|
||||
ninjareport can read it, reports are mailed to the reportemail
|
||||
configured in @CFGDIR@/backupninja.conf.
|
||||
|
||||
The following options are available:
|
||||
-h, --help This usage message
|
||||
-f, --conffile FILE Use FILE for the configuration instead
|
||||
of @CFGDIR@/backupninja.conf
|
||||
-m, --mail <email> Mail the report to this address
|
||||
-o, --out Don't mail the report, just display it
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
#####################################################
|
||||
## MAIN
|
||||
|
||||
conffile="@CFGDIR@/backupninja.conf"
|
||||
|
||||
## process command line options
|
||||
|
||||
while [ $# -ge 1 ]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-f|--conffile)
|
||||
if [ -f $2 ]; then
|
||||
conffile=$2
|
||||
else
|
||||
echo "-f|--conffile option must be followed by an existing filename"
|
||||
fatal "-f|--conffile option must be followed by an existing filename"
|
||||
usage
|
||||
fi
|
||||
# we shift here to avoid processing the file path
|
||||
shift
|
||||
;;
|
||||
-m|--mail)
|
||||
reportemail=$2
|
||||
shift
|
||||
;;
|
||||
-o|--out)
|
||||
mail=0
|
||||
display=1
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option $1"
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
## Load and confirm basic configuration values
|
||||
|
||||
# bootstrap
|
||||
if [ ! -r "$conffile" ]; then
|
||||
echo "Configuration file $conffile not found."
|
||||
fatal "Configuration file $conffile not found."
|
||||
fi
|
||||
|
||||
# find $libdirectory
|
||||
libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'`
|
||||
if [ -z "$libdirectory" ]; then
|
||||
if [ -d "@libdir@" ]; then
|
||||
libdirectory="@libdir@"
|
||||
else
|
||||
echo "Could not find entry 'libdirectory' in $conffile."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ ! -d "$libdirectory" ]; then
|
||||
echo "Lib directory $libdirectory not found."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# include shared functions
|
||||
. $libdirectory/tools
|
||||
|
||||
setfile $conffile
|
||||
|
||||
getconf reportdirectory
|
||||
getconf reportemail
|
||||
|
||||
## Process each configuration file
|
||||
|
||||
hosts=`find $reportdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '*.offset' | sort -n`
|
||||
|
||||
if [ -z "$hosts" ]; then
|
||||
echo "Fatal: No backupninja reports found in '$reportdirectory'!"
|
||||
mail=0
|
||||
fi
|
||||
|
||||
statusfile=`maketemp ninjastatus`
|
||||
reportappend=`maketemp ninjaappend`
|
||||
|
||||
for host in $hosts; do
|
||||
[ -f "$host" ] || continue
|
||||
# Check somehow that the file is a valid report file
|
||||
process $host
|
||||
done
|
||||
|
||||
generatereport
|
||||
|
||||
## mail the report to the report address or display it
|
||||
|
||||
if [ -s $reportfile ]; then
|
||||
if [ $mail == 1 ]; then
|
||||
mail -s "backupninja mission failure report" $reportemail < $reportfile
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $display == 1 ]; then
|
||||
cat $reportfile
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user