summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbackends/gitlab-ce188
-rwxr-xr-xbackends/gitlab-ee28
-rw-r--r--backends/gitmirrorbackend.rb30
-rw-r--r--docs.org2
-rwxr-xr-xgit-mirror2
5 files changed, 150 insertions, 100 deletions
diff --git a/backends/gitlab-ce b/backends/gitlab-ce
index 3b6cc90..c91effc 100755
--- a/backends/gitlab-ce
+++ b/backends/gitlab-ce
@@ -4,37 +4,39 @@
# http://docs.gitlab.com/ee/workflow/repository_mirroring.html
# https://gitlab.com/gitlab-org/gitlab-ee/issues/767
+load 'gitmirrorbackend.rb'
require 'net/http'
require 'uri'
require 'cgi'
require 'json'
-class GitLabCE
- def initialize(api_uri, api_key, project_id)
- @api_uri = URI(api_uri)
- unless @api_uri.path.end_with?("/")
- @api_uri.path += "/"
+class GitLabCE < GitMirrorBackend
+ class Error < RuntimeError
+ def initialize(obj)
+ @obj = obj
end
- @api_key = api_key.to_s
- @project_id = project_id.to_s
-
+ def obj
+ return @obj
+ end
+ end
+ def initialize()
@connections = {}
@cache = {}
- # API docs suck, just look at `lib/api/projects.rb`
+ # API docs suck, look at `lib/api/projects.rb` instead.
@vars = [
:builds_enabled, # create | create-user | edit
- :container_registry_enabled, # create | | edit
- :default_branch # | create-user | edit
+ :container_registry_enabled, # XXX # create | | edit
+ :default_branch, # | create-user | edit
:description, # create | create-user | edit
- :import_url, # create | create-user |
+ #:import_url, # XXX # create | create-user |
:issues_enabled, # create | create-user | edit
:lfs_enabled, # create | create-user | edit
:merge_requests_enabled, # create | create-user | edit
:name, # create | create-user | edit
- :namespace_id, # create | |
+ #:namespace_id, # create | |
:only_allow_merge_if_build_succeeds, # create | create-user | edit
- :path, # create | | edit
+ #:path, # create | | edit
:public, # create | create-user | edit
:public_builds, # create | create-user | edit
:request_access_enabled, # create | create-user | edit
@@ -44,27 +46,14 @@ class GitLabCE
:wiki_enabled, # create | create-user | edit
:only_allow_merge_if_all_discussions_are_resolved # create | create-user | edit
]
+ end
- @vars = [
- "builds_enabled",
- "container_registry_enabled",
- "default_branch",
- "description",
- "issues_enabled",
- "lfs_enabled",
- "merge_requests_enabled",
- "name",
- "only_allow_merge_if_all_discussions_are_resolved",
- "only_allow_merge_if_build_succeeds",
- "path",
- "public",
- "public_builds",
- "request_access_enabled",
- "shared_runners_enabled",
- "snippets_enabled",
- "visibility_level",
- "wiki_enabled",
- ]
+ def finish
+ @connections.each do |k,v|
+ v.finish()
+ end
+ @connections = {}
+ super
end
def _connection(uri)
@@ -76,77 +65,108 @@ class GitLabCE
return @connections[key]
end
- def _info
- unless @cache.has_key?(:info)
- req = Net::HTTP::Get.new(@api_uri + "projects/" + CGI::escape(@project_id))
+ def _info(project_id)
+ @cache[project_id] ||= {}
+ unless @cache[project_id].has_key?(:info)
+ req = Net::HTTP::Get.new(@api_uri + "projects/" + CGI::escape(project_id))
req.add_field("PRIVATE-TOKEN", @api_key)
con = _connection(req.uri)
res = con.request(req)
- if res.code != "200"
- throw res
+ case res.code
+ when "200"
+ @cache[project_id][:info] = JSON::parse(res.body)
+ when "404"
+ @cache[project_id][:info] = nil
+ else
+ raise Error.new(res)
+ end
+ end
+ return @cache[project_id][:info]
+ end
+
+ def cmd_config(*args)
+ args.each do |arg|
+ key, val = arg.split('=', 2)
+ case key
+ when "apiurl"
+ @api_uri = URI(val)
+ unless @api_uri.path.end_with?("/")
+ @api_uri.path += "/"
+ end
+ when "apikey"
+ @api_key = val
end
- @cache[:info] = JSON::parse(res.body)
end
- return @cache[:info]
end
- def get_meta
- return _info.select{|k,v| @vars.include?(k)}
+ def cmd_get_meta(project_id)
+ return _info(project_id).select{|k,v| @vars.include?(k.to_sym)}
end
- def set_meta(map)
- illegal = map.select{|k,v| not @vars.include?(k)}
+ def cmd_set_meta(project_id, *pairs)
+ map = {}
+ pairs.each do |pair|
+ key, val = arg.split('=', 2)
+ map[key] = val
+ end
+
+ mirror = map["mirror"]
+ map.delete("mirror")
+
+ illegal = map.select{|k,v| not @vars.include?(k.to_sym)}
if illegal.count > 0
- throw illegal
+ raise Error.new(illegal)
end
- req = Net::HTTP::Put.new(@api_uri + "projects/" + CGI::escape(_info["id"].to_s))
- req.add_field("PRIVATE-TOKEN", @api_key)
- req.add_field("Content-Type", "application/json")
- req.body = JSON::dump(map)
- con = _connection(req.uri)
- res = con.request(req)
- if res.code != "200"
- throw res
+ info = self._info(project_id)
+ if info == nil
+ # create
+ req = Net::HTTP::Put.new(@api_uri + "projects"))
+ req.add_field("PRIVATE-TOKEN", @api_key)
+ req.add_field("Content-Type", "application/json")
+ map["path"] = project_id
+ if not mirror.nil?
+ map["import_url"] = mirror
+ end
+ req.body = JSON::dump(map)
+ con = _connection(req.uri)
+ res = con.request(req)
+ if res.code != "201"
+ raise Error.new(res)
+ end
+ @cache[project_id][:info] = JSON::parse(res.body)
+ else
+ # update
+ req = Net::HTTP::Put.new(@api_uri + "projects/" + CGI::escape(info["id"].to_s))
+ req.add_field("PRIVATE-TOKEN", @api_key)
+ req.add_field("Content-Type", "application/json")
+ req.body = JSON::dump(map)
+ con = _connection(req.uri)
+ res = con.request(req)
+ if res.code != "200"
+ raise Error.new(res)
+ end
+ @cache[project_id][:info] = JSON::parse(res.body)
end
- @cache[:info] = JSON::parse(res.body)
return get_meta
end
- def pushURL
- return _info["ssh_url_to_repo"]
+ def cmd_push_url(project_id)
+ return _info(project_id)["ssh_url_to_repo"]
end
- def pullURL
- return _info["http_url_to_repo"]
+ def cmd_pull_url(project_id)
+ return _info(project_id)["http_url_to_repo"]
end
- def create(id, map)
- if map.has_key?("mirror")
- map["import_url"] = map["mirror"]
- map.delete("mirror")
- end
- req = Net::HTTP::Post.new(@api_uri + "projects")
- req.add_field("PRIVATE-TOKEN", @api_key)
- req.add_field("Content-Type", "application/json")
- req.body = JSON::dump(map)
- con = _connection(req.uri)
- res = con.request(req)
- end
-
- def capabilities
- return [
- [ "get-meta", @vars ].flatten,
- [ "set-meta", @vars ].flatten,
- [ "push-url" ],
- [ "pull-url" ],
- ]
+ def cmd_repo_mode
+ return "passive"
end
+end
- def finish
- @connections.each do |k,v|
- v.finish()
- end
- @connections = {}
+if __FILE__ == $0
+ if ARGV.length != 1
+ raise "Usage: $0 ACCOUNT_NAME"
end
+ GitLabCE.new().repl(ARGV[1])
end
diff --git a/backends/gitlab-ee b/backends/gitlab-ee
index d0db8b9..b69b1fc 100755
--- a/backends/gitlab-ee
+++ b/backends/gitlab-ee
@@ -69,31 +69,31 @@ class GitLabEE < GitLabCE
return URI(url)
end
- def get_meta
+ def cmd_get_meta
map = super
map["mirror"] = _mirrorURL.to_s
return map
end
- def set_meta(map)
+ def cmd_set_meta(map)
if map.has_key?("mirror")
- self._mirrorURL=map["mirror"]
+ mirror = map["mirror"]
map.delete("mirror")
+ super(map)
+ self._mirrorURL=url
+ else
+ super(map)
end
- return super(map)
end
- def create(id, map)
- super(id, map)
- self._mirrorURL=map["mirror"]
+ def cmd_repo_mode
+ return "active"
end
+end
- def capabilities
- return super.map{|c|
- if c[0] == "get-meta" or c[0] == "set-meta"
- c << "mirror"
- end
- c
- }
+if __FILE__ == $0
+ if ARGV.length != 1
+ throw "Usage: $0 ACCOUNT_NAME"
end
+ GitLabEE.new().repl(ARGV[1])
end
diff --git a/backends/gitmirrorbackend.rb b/backends/gitmirrorbackend.rb
new file mode 100644
index 0000000..25f7c3e
--- /dev/null
+++ b/backends/gitmirrorbackend.rb
@@ -0,0 +1,30 @@
+# coding: utf-8
+
+require 'shellwords'
+
+class GitMirrorBackend
+ def repl(accountName)
+ @accountName = account_name
+ $stdin.each do |line|
+ args = line.shellsplit
+ out = self.send('cmd_'+args[0].gsub('-', '_'), *args[1..0])
+ if out.is_a? String
+ puts out
+ elsif out.is_a? Array
+ out.each do |outline|
+ puts outline
+ end
+ elsif out.is_a? Hash
+ out.each do |k,v|
+ puts "#{k}=#{v}"
+ end
+ else
+ raise "I don't know what to do with output value: #{out}"
+ end
+ end
+ self.finish
+ end
+ def finish
+ # noop
+ end
+end
diff --git a/docs.org b/docs.org
index 3861bd9..dd7cc70 100644
--- a/docs.org
+++ b/docs.org
@@ -4,7 +4,7 @@
** push-url PATH => URL
** get-meta PATH => KEY=VAL\n...
** set-meta PATH KEY=VAL...
-** repo-mode => push|pull
+** repo-mode => active|passive
* ruby interface
** capabilities: .capabilities() => array
Returns an array of arrays. Each item in the array is an array of
diff --git a/git-mirror b/git-mirror
index 1a33774..521576e 100755
--- a/git-mirror
+++ b/git-mirror
@@ -97,7 +97,7 @@ upload() {
# push repository
local repo_mode
repo_mode=$(remote "$remote" repo-mode)
- if [[ $repo_mode == push ]]; then
+ if [[ $repo_mode == passive ]]; then
local push_url
push_url="$(remote "$remote" push-url)"
cd "$local" && git push --mirror "$push_url"