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