20b61668e9331d7348ef34b36f3413375820b22e
3 ### GNU Affero General Public License compliance
5 ### (c) 2013 Mark Wooding
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of Chopwood: a password-changing service.
12 ### Chopwood is free software; you can redistribute it and/or modify
13 ### it under the terms of the GNU Affero General Public License as
14 ### published by the Free Software Foundation; either version 3 of the
15 ### License, or (at your option) any later version.
17 ### Chopwood is distributed in the hope that it will be useful,
18 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ### GNU Affero General Public License for more details.
22 ### You should have received a copy of the GNU Affero General Public
23 ### License along with Chopwood; if not, see
24 ### <http://www.gnu.org/licenses/>.
26 import contextlib
as CTX
32 import subprocess
as SUB
38 from cStringIO
import StringIO
40 from auto
import PACKAGE
, VERSION
47 finally: SH
.rmtree(d
, ignore_errors
= True)
51 for m
in SYS
.modules
.itervalues():
53 except AttributeError: continue
54 d
= OS
.path
.realpath(OS
.path
.dirname(f
))
55 if d
.startswith('/usr/') and not d
.startswith('/usr/local/'): continue
61 if d
.startswith(last
): continue
66 def exists_subdir(subdir
):
67 return lambda dir: OS
.path
.isdir(OS
.path
.join(dir, subdir
))
71 kid
= SUB
.Popen(SL
.split(cmd
), stdout
= SUB
.PIPE
, cwd
= dir)
74 buf
= kid
.stdout
.read(16384)
82 if f
.startswith('./'): f
= f
[2:]
87 raise U
.ExpectedError
, \
88 (500, "trailing junk from `%s' in `%s'" %
(cmd
, dir))
92 (exists_subdir('.git'), [filez('git ls-files -coz --exclude-standard'),
93 filez('find .git -print0')]),
94 (lambda d
: True, [filez('find . ( ! -perm +004 -prune ) -o -print0')])]
96 def dump_dir(dir, tf
, root
):
97 for test
, listers
in DUMPERS
:
100 raise U
.ExpectedError
, (500, "no dumper for `%s'" % dir
)
101 for lister
in listers
:
102 base
= OS
.path
.basename(dir)
103 for file in lister(dir):
104 tf
.add(OS
.path
.join(dir, file), OS
.path
.join(root
, base
, file),
108 if SYS
.version_info
>= (2, 6):
109 tf
= TAR
.open(fileobj
= out
, mode
= 'w|gz', format
= TAR
.USTAR_FORMAT
)
111 tf
= TAR
.open(fileobj
= out
, mode
= 'w|gz')
113 root
= '%s-%s' %
(PACKAGE
, VERSION
)
117 for dir in dirs_to_dump():
118 dir = dir.rstrip('/')
119 base
= OS
.path
.basename(dir)
124 name
= '%s.%d' %
(base
, i
)
125 if name
not in seen
: break
126 dirmap
.append((dir + '/', name
))
127 festout
.write('%s = %s\n' %
(name
, dir))
128 fest
= festout
.getvalue()
129 ti
= TAR
.TarInfo(OS
.path
.join(root
, 'MANIFEST'))
133 ti
.type = TAR
.REGTYPE
134 uid
= OS
.getuid(); ti
.uid
, ti
.uname
= uid
, PW
.getpwuid(uid
).pw_name
135 gid
= OS
.getgid(); ti
.gid
, ti
.gname
= gid
, GR
.getgrgid(gid
).gr_name
136 tf
.addfile(ti
, fileobj
= StringIO(fest
))
137 for dir, name
in dirmap
:
138 dump_dir(dir, tf
, root
)
141 ###----- That's all, folks --------------------------------------------------