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

Contents of /rpms/mailman/contribs10/mailman-migrate-fhs

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


Revision 1.1 - (show annotations) (download)
Mon Feb 22 15:34:01 2021 UTC (3 years, 9 months ago) by brianr
Branch: MAIN
CVS Tags: HEAD
Error occurred while calculating annotation data.
Initial import

1 #!/usr/bin/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