##// END OF EJS Templates
change owner rights to work with mod_perl authentication. add a test option that just connect to WS and say what should be done...
Nicolas Chuche -
r898:d6e8121ef1bd
parent child
Show More
@@ -1,213 +1,233
1 1 #!/usr/bin/ruby
2 2
3 3 # == Synopsis
4 4 #
5 5 # reposman: manages your svn repositories with Redmine
6 6 #
7 7 # == Usage
8 8 #
9 9 # reposman [ -h | --help ] [ -v | --verbose ] [ -V | --version ] [ -q | --quiet ] -s /var/svn -r redmine.host.org
10 10 # example: reposman --svn-dir=/var/svn --redmine-host=redmine.mydomain.foo
11 11 # reposman -s /var/svn -r redmine.mydomain.foo
12 12 #
13 13 # == Arguments (mandatory)
14 14 #
15 15 # -s, --svn-dir=DIR
16 16 # use DIR as base directory for svn repositories
17 17 #
18 18 # -r, --redmine-host=HOST
19 19 # assume Redmine is hosted on HOST.
20 20 # you can use :
21 21 # * -r redmine.mydomain.foo (will add http://)
22 22 # * -r http://redmine.mydomain.foo
23 23 # * -r https://mydomain.foo/redmine
24 24 #
25 25 # == Options
26 26 #
27 27 # -o, --owner=OWNER
28 28 # owner of the repository. using the rails login allow user to browse
29 29 # the repository in Redmine even for private project
30 30 #
31 31 # -u, --url=URL
32 32 # the base url Redmine will use to access your repositories. This
33 33 # will be used to register the repository in Redmine so that user
34 34 # doesn't need to do anything. reposman will add the identifier to this url :
35 35 #
36 36 # -u https://my.svn.server/my/reposity/root # if the repository can be access by http
37 37 # -u file:///var/svn/ # if the repository is local
38 38 # if this option isn't set, reposman won't register the repository
39 39 #
40 # -t, --test
41 # only show what should be done
40 42 #
41 43 # -h, --help:
42 44 # show help and exit
43 45 #
44 46 # -v, --verbose
45 47 # verbose
46 48 #
47 49 # -V, --version
48 50 # print version and exit
49 51 #
50 52 # -q, --quiet
51 53 # no log
52 54 #
53 55
54 56 require 'getoptlong'
55 57 require 'rdoc/usage'
56 58 require 'soap/wsdlDriver'
57 59 require 'find'
58 60 require 'etc'
59 61
60 62 Version = "1.0"
61 63
62 64 opts = GetoptLong.new(
63 65 ['--svn-dir', '-s', GetoptLong::REQUIRED_ARGUMENT],
64 66 ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
65 67 ['--owner', '-o', GetoptLong::REQUIRED_ARGUMENT],
66 68 ['--url', '-u', GetoptLong::REQUIRED_ARGUMENT],
69 ['--test', '-t', GetoptLong::NO_ARGUMENT],
67 70 ['--verbose', '-v', GetoptLong::NO_ARGUMENT],
68 71 ['--version', '-V', GetoptLong::NO_ARGUMENT],
69 72 ['--help' , '-h', GetoptLong::NO_ARGUMENT],
70 73 ['--quiet' , '-q', GetoptLong::NO_ARGUMENT]
71 74 )
72 75
73 76 $verbose = 0
74 77 $quiet = false
75 78 $redmine_host = ''
76 79 $repos_base = ''
77 80 $svn_owner = 'root'
78 81 $svn_url = false
82 $test = false
79 83
80 84 def log(text,level=0, exit=false)
81 85 return if $quiet or level > $verbose
82 86 puts text
83 87 exit 1 if exit
84 88 end
85 89
86 90 begin
87 91 opts.each do |opt, arg|
88 92 case opt
89 93 when '--svn-dir'; $repos_base = arg.dup
90 94 when '--redmine-host'; $redmine_host = arg.dup
91 95 when '--owner'; $svn_owner = arg.dup
92 96 when '--url'; $svn_url = arg.dup
93 97 when '--verbose'; $verbose += 1
98 when '--test'; $test = true
94 99 when '--version'; puts Version; exit
95 100 when '--help'; RDoc::usage
96 101 when '--quiet'; $quiet = true
97 102 end
98 103 end
99 104 rescue
100 105 exit 1
101 106 end
102 107
108 if $test
109 log("running in test mode")
110 end
111
103 112 $svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
104 113
105 114 if ($redmine_host.empty? or $repos_base.empty?)
106 115 RDoc::usage
107 116 end
108 117
109 118 unless File.directory?($repos_base)
110 119 log("directory '#{$repos_base}' doesn't exists", 0, true)
111 120 end
112 121
113 122 log("querying Redmine for projects...", 1);
114 123
115 124 $redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
116 125 $redmine_host.gsub!(/\/$/, '')
117 126
118 127 wsdl_url = "#{$redmine_host}/sys/service.wsdl";
119 128
120 129 begin
121 130 soap = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver
122 131 rescue => e
123 132 log("Unable to connect to #{wsdl_url} : #{e}", 0, true)
124 133 end
125 134
126 135 projects = soap.Projects
127 136
128 137 if projects.nil?
129 138 log('no project found, perhaps you forgot to "Enable WS for repository management"', 0, true)
130 139 end
131 140
132 141 log("retrieved #{projects.size} projects", 1)
133 142
134 143 def set_owner_and_rights(project, repos_path, &block)
135 144 if RUBY_PLATFORM =~ /mswin/
136 145 yield if block_given?
137 146 else
138 147 uid, gid = Etc.getpwnam($svn_owner).uid, Etc.getgrnam(project.identifier).gid
139 right = project.is_public ? 0575 : 0570
148 right = project.is_public ? 0775 : 0770
140 149 yield if block_given?
141 150 Find.find(repos_path) do |f|
142 151 File.chmod right, f
143 152 File.chown uid, gid, f
144 153 end
145 154 end
146 155 end
147 156
148 157 def other_read_right?(file)
149 158 (File.stat(file).mode & 0007).zero? ? false : true
150 159 end
151 160
152 161 def owner_name(file)
153 162 RUBY_PLATFORM =~ /mswin/ ?
154 163 $svn_owner :
155 164 Etc.getpwuid( File.stat(file).uid ).name
156 165 end
157 166
158 167 projects.each do |project|
159 168 log("treating project #{project.name}", 1)
160 169
161 170 if project.identifier.empty?
162 171 log("\tno identifier for project #{project.name}")
163 172 next
164 173 elsif not project.identifier.match(/^[a-z0-9\-]+$/)
165 174 log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
166 175 next;
167 176 end
168 177
169 178 repos_path = $repos_base + "/" + project.identifier
170 179
171 180 if File.directory?(repos_path)
172 181
173 182 # we must verify that repository has the good owner and the good
174 183 # rights before leaving
175 184 other_read = other_read_right?(repos_path)
176 185 owner = owner_name(repos_path)
177 186 next if project.is_public == other_read and owner == $svn_owner
178 187
188 if $test
189 log("\tchange mode on #{repos_path}")
190 next
191 end
192
179 193 begin
180 194 set_owner_and_rights(project, repos_path)
181 195 rescue Errno::EPERM => e
182 196 log("\tunable to change mode on #{repos_path} : #{e}\n")
183 197 next
184 198 end
185 199
186 200 log("\tmode change on #{repos_path}");
187 201
188 202 else
189 project.is_public ? File.umask(0202) : File.umask(0207)
203 project.is_public ? File.umask(0002) : File.umask(0007)
204
205 if $test
206 log("\tcreate repository #{repos_path}")
207 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}") if $svn_url;
208 next
209 end
190 210
191 211 begin
192 212 set_owner_and_rights(project, repos_path) do
193 213 raise "svnadmin create #{repos_path} failed" unless system("svnadmin", "create", repos_path)
194 214 end
195 215 rescue => e
196 216 log("\tunable to create #{repos_path} : #{e}\n")
197 217 next
198 218 end
199 219
200 220 if $svn_url
201 221 ret = soap.RepositoryCreated project.identifier, "#{$svn_url}#{project.identifier}"
202 222 if ret > 0
203 223 log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
204 224 else
205 225 log("\trepository #{repos_path} not registered in Redmine. Look in your log to find why.");
206 226 end
207 227 end
208 228
209 229 log("\trepository #{repos_path} created");
210 230 end
211 231
212 232 end
213 233
General Comments 0
You need to be logged in to leave comments. Login now