/[smecontribs]/rpms/mailman/contribs8/mailman-migrate-fhs
ViewVC logotype

Annotation of /rpms/mailman/contribs8/mailman-migrate-fhs

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Tue Jul 2 20:11:40 2013 UTC (11 years, 5 months ago) by unnilennium
Branch: MAIN
CVS Tags: mailman-2_1_5_1-34_rhel4_6_el5_sme
Initial import

1 unnilennium 1.1 #!/usr/bin/env python
2    
3     import sys
4     import os
5     import re
6     import shutil
7     import getopt
8     from stat import *
9    
10     #------------------------------------------------------------------------------
11    
12     # Command Line Args
13     doit = True
14     verbose = False
15     quiet = False
16     warn = False
17     force = False
18     print_mapping = False
19     remove_files = False
20     remove_installation = False
21    
22     # Scan Results
23     existing_files = {}
24     non_existing_files = {}
25    
26     # Directory and File mappings
27    
28     # This is the complete directory map, it includes both data files
29     # and run-time files
30     dir_map = {
31     '/var/mailman' : '/var/lib/mailman',
32     '/var/mailman/Mailman' : '/usr/lib/mailman/Mailman',
33     '/var/mailman/archives' : '/var/lib/mailman/archives',
34     '/var/mailman/bin' : '/usr/lib/mailman/bin',
35     '/var/mailman/cgi-bin' : '/usr/lib/mailman/cgi-bin',
36     '/var/mailman/cron' : '/usr/lib/mailman/cron',
37     '/var/mailman/data' : '/var/lib/mailman/data',
38     '/var/mailman/lists' : '/var/lib/mailman/lists',
39     '/var/mailman/locks' : '/var/lock/mailman',
40     '/var/mailman/logs' : '/var/log/mailman',
41     '/var/mailman/mail' : '/usr/lib/mailman/mail',
42     '/var/mailman/messages' : '/usr/lib/mailman/messages',
43     '/var/mailman/pythonlib' : '/usr/lib/mailman/pythonlib',
44     '/var/mailman/qfiles' : '/var/spool/mailman',
45     '/var/spool/mailman/qfiles' : '/var/spool/mailman',
46     '/var/mailman/scripts' : '/usr/lib/mailman/scripts',
47     '/var/mailman/spam' : '/var/lib/mailman/spam',
48     '/var/mailman/templates' : '/usr/lib/mailman/templates',
49     '/var/mailman/tests' : '/usr/lib/mailman/tests'
50     }
51    
52     # These are directories that contain data files the user may
53     # want to preserve from an old installation and should be copied
54     # into the new directory location.
55     data_dir_map = {
56     '/var/mailman/archives' : '/var/lib/mailman/archives',
57     '/var/mailman/data' : '/var/lib/mailman/data',
58     '/var/mailman/lists' : '/var/lib/mailman/lists',
59     '/var/mailman/logs' : '/var/log/mailman',
60     '/var/mailman/qfiles' : '/var/spool/mailman',
61     '/var/spool/mailman/qfiles' : '/var/spool/mailman',
62     '/var/mailman/spam' : '/var/lib/mailman/spam',
63     }
64    
65     # These are mappings for individual files. They represent files that
66     # cannot be mapped via their parent dirctories, they must be treated
67     # individually.
68     file_map = {
69     '/var/mailman/data/adm.pw' : '/etc/mailman/adm.pw',
70     '/var/mailman/data/creator.pw' : '/etc/mailman/creator.pw',
71     '/var/mailman/data/aliases' : '/etc/mailman/aliases',
72     '/var/mailman/data/virtual-mailman' : '/etc/mailman/virtual-mailman',
73     '/var/mailman/data/sitelist.cfg' : '/etc/mailman/sitelist.cfg',
74     '/var/mailman/data/master-qrunner.pid' : '/var/run/mailman/master-qrunner.pid'
75     }
76    
77     #------------------------------------------------------------------------------
78    
79     def DumpMapping():
80     '''Print out the directory and file mappings'''
81     print "Directory Mapping:"
82     for key in dir_map.keys():
83     print "%s --> %s" %(key, dir_map[key])
84    
85     print "\nFile Mapping:"
86     for key in file_map.keys():
87     print "%s --> %s" %(key, file_map[key])
88    
89     def RecordFile(src, dst):
90     '''If the src files (old) exists record this as a potential
91     file operation. File operations are grouped into two sets,
92     those where the dst (new) files exists and those where it does not
93     exist. This is done to prevent overwriting files'''
94    
95     global existing_files, non_existing_files
96    
97     if not os.path.exists(src):
98     return
99    
100     if existing_files.has_key(src):
101     if warn:
102     print "WARNING: src file already seen (%s) and has dst match: (%s)" % (src, dst)
103     return
104    
105     if non_existing_files.has_key(src):
106     if warn:
107     print "WARNING: src file already seen (%s) does not have dst match" % (src)
108     return
109    
110     if os.path.exists(dst):
111     existing_files[src] = dst
112     else:
113     non_existing_files[src] = dst
114    
115     def GetCopyFiles(old_root, new_root):
116     '''Recursively generate a list of src files (old) in the old_root
117     and pair each of them with their new dst path name'''
118    
119     prefix_re = re.compile("^(%s)/*(.*)" % re.escape(old_root))
120     dst_files_existing = []
121     dst_files_non_existing = []
122     for root, dirs, files in os.walk(old_root):
123     match = prefix_re.match(root)
124     subdir = match.group(2)
125     for name in files:
126     oldpath = os.path.join(root, name)
127     newpath = os.path.join(new_root, subdir, name)
128     RecordFile(oldpath, newpath)
129    
130     def CopyFile(src_path, dst_path):
131     '''Copy file, preserve its mode and ownership. If the dst directory
132     does not exist, create it preserving the mode and ownership of the
133     src direcotry'''
134    
135     if not doit:
136     print "cp %s %s" % (src_path, dst_path)
137     return
138    
139     src_dir = os.path.dirname(src_path)
140     dst_dir = os.path.dirname(dst_path)
141    
142     if not os.path.isdir(dst_dir):
143     if os.path.exists(dst_dir):
144     print "ERROR: dst dir exists, but is not directory (%s)" % dst_dir
145     return
146     st = os.stat(src_dir)
147     os.makedirs(dst_dir, st[ST_MODE])
148     os.chown(dst_dir, st[ST_UID], st[ST_GID])
149    
150     shutil.copy2(src_path, dst_path)
151     st = os.stat(src_path)
152     os.chown(dst_path, st[ST_UID], st[ST_GID])
153    
154     def RemoveFile(path):
155     '''Remove the file'''
156    
157     if not os.path.exists(path):
158     if warn:
159     print "WARNING: attempt to remove non-existent file (%s)" % path
160     return
161    
162     if not os.path.isfile(path):
163     if warn:
164     print "WARNING: attempt to remove non-plain file (%s)" % path
165     return
166    
167     if not doit:
168     print "rm %s" % (path)
169     return
170    
171     os.unlink(path)
172    
173     def RemoveDirs(top):
174     '''Delete everything reachable from the directory named in 'top',
175     assuming there are no symbolic links.
176     CAUTION: This is dangerous! For example, if top == '/', it
177     could delete all your disk files.'''
178     for root, dirs, files in os.walk(top, topdown=False):
179     for name in files:
180     path = os.path.join(root, name)
181     if not doit:
182     print "rm %s" % (path)
183     else:
184     os.remove(path)
185     for name in dirs:
186     path = os.path.join(root, name)
187     if not doit:
188     print "rmdir %s" % (path)
189     else:
190     os.rmdir(path)
191    
192     def Usage():
193     print """
194     This script will help you copy mailman data files from the old
195     directory structure to the new FHS directory structure.
196    
197     Mailman should not be running when you perform this!
198     /sbin/service mailman stop
199    
200     This script is conservative, by default it will not overwrite
201     any file in the new directory on the assumption it is most recent
202     and most correct. If you want to force overwrites use -f.
203    
204     Files are copied to the new directories, if you want to remove the
205     old data files use -r. Hint: copy first and test, once everything is
206     working remove the old files with -r. If you want to remove the entire
207     old installation use -R
208    
209     migrate [-f] [-n] [-q] [-v] [-w] [-m] [-r] [-R]
210     -n don't execute, but show what would be done
211     -f force destination overwrites
212     -m print mapping
213     -r remove old data files
214     -R remove entire old installation
215     -q be quiet
216     -v be verbose
217     -w print warnings
218     -h help
219     """
220    
221     #------------------------------------------------------------------------------
222    
223     try:
224     opts, args = getopt.getopt(sys.argv[1:], "nfvmqwhrR")
225     for o, a in opts:
226     if o == "-n":
227     doit = False
228     elif o == "-f":
229     force = True
230     elif o == "-v":
231     verbose = True
232     elif o == "-m":
233     print_mapping = True
234     elif o == "-q":
235     quiet = True
236     elif o == "-w":
237     warn = True
238     elif o == "-r":
239     remove_files = True
240     elif o == "-R":
241     remove_installation = True
242     elif o == "-h":
243     Usage()
244     sys.exit(1)
245     except getopt.GetoptError, err:
246     print err
247     Usage()
248     sys.exit(1)
249    
250    
251     if print_mapping:
252     DumpMapping()
253     sys.exit(0)
254    
255     # Generate file list
256     for src_dir in data_dir_map.keys():
257     GetCopyFiles(src_dir, dir_map[src_dir])
258    
259     for src_file in file_map.keys():
260     RecordFile(src_file, file_map[src_file])
261    
262    
263     # Copy files
264     for src in non_existing_files:
265     dst = non_existing_files[src]
266     CopyFile(src, dst)
267    
268     if force:
269     for src in existing_files:
270     dst = existing_files[src]
271     CopyFile(src, dst)
272     else:
273     if len(existing_files) > 0 and not quiet:
274     print "\nThe following files already exist in the destination, they will NOT be copied"
275     print "To force overwriting invoke with -f\n"
276     for src in existing_files:
277     dst = existing_files[src]
278     print "# cp %s %s" %(src, dst)
279    
280     # Remove old files
281     if remove_files:
282     for src in existing_files:
283     RemoveFile(src)
284     for src in non_existing_files:
285     RemoveFile(src)
286    
287     if remove_installation:
288     for old_dir in dir_map.keys():
289     RemoveDirs(old_dir)
290    
291    
292     sys.exit(0)
293    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed