2014-11-14 22:17:52 +01:00
|
|
|
module RepositoryFetch
|
|
|
|
|
|
|
|
def self.logger
|
|
|
|
::Rails.logger
|
|
|
|
end
|
|
|
|
|
|
|
|
PATTERNS = [
|
|
|
|
{ :pattern => "/redmine_git_fetch/github.com/",
|
|
|
|
:uri_prefix => "git@github.com:",
|
2014-11-18 20:02:29 +01:00
|
|
|
:host => "github.com",
|
2014-11-14 22:17:52 +01:00
|
|
|
:key => "/home/redmine/data/keys/id_rsa"
|
|
|
|
},
|
|
|
|
{ :pattern => "/redmine_git_fetch/gitlab.com/",
|
|
|
|
:uri_prefix => "git@gitlab.com:",
|
2014-11-18 20:02:29 +01:00
|
|
|
:host => "gitlab.com",
|
2014-11-14 22:17:52 +01:00
|
|
|
:key => "/home/redmine/data/keys/id_rsa"
|
|
|
|
},
|
|
|
|
{ :pattern => "/redmine_git_fetch/git.ewdev.ca/",
|
|
|
|
:uri_prefix => "git@git.ewdev.ca:",
|
2014-11-18 20:02:29 +01:00
|
|
|
:host => "git.ewdev.ca",
|
2014-11-14 22:17:52 +01:00
|
|
|
:key => "/home/redmine/data/keys/id_rsa"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
def self.clone_or_fetch(repository)
|
|
|
|
return unless repository.scm_name == "Git"
|
|
|
|
|
|
|
|
path = repository.url
|
|
|
|
|
|
|
|
p = PATTERNS.find { |p| path.starts_with? p[:pattern] }
|
|
|
|
unless p
|
|
|
|
# TODO: figure out how to handle non-matching repos.
|
|
|
|
# eg. skip them, try fetching them, throw warning or not?
|
|
|
|
proj = repository.project.identifier
|
|
|
|
logger.warn "repository_fetch: no match for '#{path}' in project '#{proj}'"
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-11-18 20:02:29 +01:00
|
|
|
add_known_host(p[:host])
|
|
|
|
|
2014-11-14 22:17:52 +01:00
|
|
|
# If dir exists and non-empty, should be safe to 'git fetch'
|
|
|
|
if Dir.exists?(path) && Dir.entries(path) != [".", ".."]
|
|
|
|
puts "Running git fetch on #{path}"
|
2014-11-18 20:02:29 +01:00
|
|
|
puts exec_with_key "git -C #{path} fetch --all", p[:key]
|
2014-11-14 22:17:52 +01:00
|
|
|
else
|
|
|
|
# try cloning the repo
|
|
|
|
url = path.sub( p[:pattern], p[:uri_prefix])
|
|
|
|
puts "Matched new URL, trying to clone: " + url
|
2014-11-18 20:02:29 +01:00
|
|
|
puts exec_with_key "git clone --mirror #{url} #{path}", p[:key]
|
2014-11-14 22:17:52 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.exec_with_key(cmd, keyfile)
|
|
|
|
return `ssh-agent bash -c 'ssh-add #{keyfile}; #{cmd}'`
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.fetch
|
|
|
|
Project.active.has_module(:repository).all.each do |project|
|
|
|
|
project.repositories.each do |repository|
|
2014-11-18 20:02:29 +01:00
|
|
|
clone_or_fetch(repository)
|
2014-11-14 22:17:52 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-11-18 20:02:29 +01:00
|
|
|
# Checks if host is in ~/.ssh/known_hosts, adds it if not present
|
|
|
|
def self.add_known_host(host)
|
|
|
|
# if not found...
|
|
|
|
if `ssh-keygen -F #{host} | grep 'found'` == ""
|
|
|
|
# hack to work with 'docker exec' where HOME isn't set (or set to /)
|
|
|
|
ssh_known_hosts = (ENV['HOME'] == "/" or ENV['HOME'] == nil ? "/root" : ENV['HOME']) + "/.ssh/known_hosts"
|
|
|
|
puts "Authorizing #{host}"
|
|
|
|
puts `ssh-keyscan #{host} >> #{ssh_known_hosts}`
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
class Fetch
|
2014-11-14 22:17:52 +01:00
|
|
|
end
|
|
|
|
end
|