Drupal database backup

Printer-friendly versionPrinter-friendly version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/env python
 
"""
 
    MySQL Database Backupper
    Copyright (C) 2008  Samuele ~redShadow~ Santi - http://hackzine.org
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
"""
 
    TODO LIST
      -  Check destination path, add options to auto-create it when exists.
         Try not to overwrite anything by default..
      -  Let the user customize the output filename (with a template file name)
      -  find a clean way to pass the password to pg_dump -> and add support
         also to postgresql backups
      -  add more parameters for mysqldump/pg_dump
      -  add more compression types (such as ZIP)
 
 
"""
 
#
# Needed modules
#
import sys, os, re
from time import strftime
 
 
#
# The Intro
#
def print_intro():
        print_c("""MyBackup.py 0.1  Copyright (C) 2008  Samuele ~redShadow~ Santi
This program comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see <http://www.gnu.org/licenses/>.
        """)
 
 
#
# The help
#
def print_help(myname):
        print_c("""
Usage: %s [options] <db_url> [ <db_url1> [ <db_ur2> [ .. ] ] ] <destination>
 
  Database urls are in the same form accepted by Drupal (www.drupal.org)
    [mysql|mysqli|pgsql]://<username>:<password>@<host>[:<port>]/<database>
 
  Destination is the path where backups will be stored
 
  OPTIONS
    OUTPUT CONTROL
      -d   Enables debugging mode
      -q   Quiet mode (no output)
 
    COMPRESSION
      -cb  Compress output using bzip2
      -cg  Compress output using gzip
      -cn  No compression (default)
 
        """ % myname)
 
 
#
# Run database backups
#
def backup_databases(urls, destpath):
        print_c("Starting backups for %d databases...\n" % len(urls))
        print_c("Destination: %s" % destpath, True)
        # Cannot use urlparse module here due to problems parsing urls with
        # non-standard schema (such as mysql:// or pgsql://)
        urlPattern = re.compile(r'^([A-Za-z0-9]*)://([^:]*):([^@]*)@([^:/]*):?([^/]*)/([^/]*).*$')
        for db_url in urls:
                db_schema, db_user, db_pass, db_host, db_port, db_name = urlPattern.search(db_url).groups()
                if db_schema == 'mysqli': db_schema = 'mysql' # it's the same thing..
                if db_schema=='mysql' or db_schema=='pgsql':
                        #print db_schema, db_user, db_pass, db_host, db_port, db_name
                        if not db_port:
                                db_port = 3306 # default port
                        else:
                                db_port = int(db_port) # clean port number
                        cur_date = strftime("%Y%m%d_%H%M%S")
                        dest_file = "%s/%s_%s.sql" % (destpath, db_name, cur_date)
                        log_file = "/tmp/%s_%s.log" % (db_name, cur_date)
                        print_c("--- Running Database Backup ----------------------------")
                        print_c("%20s: %s" % ("DB URL",        db_url), True)
                        print_c("%20s: %s" % ("Type",          db_schema))
                        print_c("%20s: %s" % ("DB Host",       db_host))
                        print_c("%20s: %s" % ("Port",          db_port))
                        print_c("%20s: %s" % ("Username",      db_user))
                        print_c("%20s: %s" % ("Password",      "****")) # HIDE PASSWORD!
                        print_c("%20s: %s" % ("Database Name", db_name))
                        print_c("%20s: %s" % ("Date",          cur_date))
                        print_c("%20s: %s" % ("Destination",   dest_file))
                        print_c("--------------------------------------------------------")
                        ### TODO Check destination
                        ### TODO Let the user customize the output filename
                        if db_schema == 'mysql':
                                dump_command = "mysqldump --host=\"%s\" --port=\"%s\" --user=\"%s\" --password=\"%s\" \"%s\" 1>\"%s\" 2>\"%s\" " % (db_host, db_port, db_user, db_pass, db_name, dest_file, log_file)
                        elif db_schema == 'pgsql':
                                # TODO find a clean way to pass the password to pg_dump
                                #dump_command = "echo \"%s\" | pg_dump --host=\"%s\" --port=\"%s\" --username=\"%s\" \"%s\" --file=\"%s\" 2>\"%s\"" % (db_pass, db_host, db_port, db_user, db_name, dest_file, log_file)
                                dump_command = "echo \"PG DUMP not supported yet!\""
                        else:
                                # ..a fuckin' unknown strange error
                                print_c(">>> Unknown, strange, fatal error!")
                                sys.exit(1)
                        res = os.system(dump_command)
                        print_c(dump_command, True)
                        if res == 0:
                                # Successful.. compress resulting database dump
                                print_c("Successful!")
                                if compression:
                                        print_c("Compressing dump using %s..." % compression)
                                        if compression == 'bzip2':
                                                compress_command = "bzip2 %s" % dest_file
                                        elif compression == 'gzip':
                                                compress_command = "gzip %s" % dest_file
                                        compress_result = os.system(compress_command)
                                        if compress_result == 0:
                                                print_c("Compression done.")
                                        else:
                                                print_c("Error occurred.")
                        else:
                                # Something wrong..
                                print_c("Something went wrong.. (return status %d)" % (res))
                                print_c("Logfile:", log_file)
                        print_c("")
                else:
                        print_c("Unsupported Schema: %s (skipping)\n\n" % db_schema)
 
 
#
# "Conditional print"
#
def print_c(text, debug = False):
        if quiet_mode == False:
                if debug == False or debug_mode == True:
                        print text
 
#
# Default variables
#
debug_mode = False
quiet_mode = False
compression = False
 
#
# Main
#
if __name__=="__main__":
        # read arguments
        args = sys.argv
        if len(args) < 3:
                print_c("No enough arguments passed!")
                print_help(args[0])
        else:
                # Display intro
                print_intro()
                # Load arguments...
                # ..destination path...
                destpath = args[-1]
                # ..and arguments
                args = args[1:-1]
                urls = []
                # TODO add more parameters to configure dump more options
                for a in args:
                        if a[0]=='-':
                                if a == '-d':
                                        debug_mode = True
                                elif a == '-q':
                                        quiet_mode = True
                                elif a == '-cb':
                                        compression = "bzip2"
                                elif a == '-cg':
                                        compression = "gzip"
                                elif a == '-cn':
                                        compression = False
                                else:
                                        print_c("Unknown option: %s" % (a))
                        else:
                                urls.append(a)
                # Some output..
                if debug_mode:
                        print_c(">>> Debug mode is ON", True)
                if compression or debug_mode:
                        print_c(">>> Compression type: %s" % compression)
                print_c("")
                backup_databases(urls, destpath)

1 comment

 
Anonymous wrote 2 weeks 4 days ago

respond this topic

To reach success, students have to decide if they want to create the custom essay paper online or buy essay online of really good quality.

Who Am I?

~redShadow~ A.K.A. Samuele Santi is an Italian Open Source developer, currently working as a freelance developer, mainly in the web applications sector. Favourite programming languages: PHP and, of course, Python!

database (3) aircrack (1) caos (1) code (3) cryptography (1) curl (1) address book (2) como lake rovers (1) camera mia (1) audio (1) cars (1) debug (1) cocktails (1) 2v (1) circuits (1) arduino (1) development (11) apt (1) debian (1) blogroll (7) 3d (3) blender (3) dmcrypt (1) documentation (2) backup (3) Drupal (21) doku (1) algorythms (1) aoe (1) bash (11) e-mail (2) awstats (3) Drupal Forms (1) C++ (2) alcool (1) contact manager (1) citroen (1) apache (1) cartoons (1) archive (1)