Commit 710746ff authored by Yorick Peterse's avatar Yorick Peterse

Merge branch 'shards' into 'master'

Implement shard paths handling

See https://gitlab.com/gitlab-org/gitlab-ee/issues/583

See merge request !61
parents 5a6d71d1 18b4d39a
v3.1.0
- Refactor repository paths handling to allow multiple git mount points
v3.0.1
- Update PostReceive worker to provide enqueued_at time.
......
......@@ -23,18 +23,15 @@ end
puts "\nCheck directories and files: "
config = GitlabConfig.new
dirs = [config.repos_path, config.auth_file]
dirs.each do |dir|
abort("ERROR: missing option in config.yml") unless dir
print "\t#{dir}: "
if File.exists?(dir)
abort("ERROR: missing option in config.yml") unless config.auth_file
print "\t#{config.auth_file}: "
if File.exists?(config.auth_file)
print 'OK'
else
else
abort "FAILED"
end
puts "\n"
end
puts "\n"
print "Send ping to redis server: "
abort unless GitlabNet.new.redis_client.ping
......@@ -7,10 +7,14 @@
require_relative '../lib/gitlab_init'
require File.join(ROOT_PATH, 'lib', 'gitlab_projects')
Dir["#{GitlabConfig.new.repos_path}/*/*.git"].each do |repo|
repository_storage_paths = ARGV
repository_storage_paths.each do |repo_path|
Dir["#{repo_path.chomp('/')}/*/*.git"].each do |repo|
begin
GitlabProjects.create_hooks(repo)
rescue Errno::ENOENT
# The user must have deleted their repository. Ignore.
end
end
end
......@@ -8,16 +8,20 @@ require_relative '../lib/gitlab_init'
config = GitlabConfig.new
key_dir = File.dirname("#{config.auth_file}")
repository_storage_paths = ARGV
commands = [
%W(mkdir -p #{config.repos_path}),
%W(mkdir -p #{key_dir}),
%W(chmod 700 #{key_dir}),
%W(touch #{config.auth_file}),
%W(chmod 600 #{config.auth_file}),
%W(chmod ug+rwX,o-rwx #{config.repos_path}),
]
repository_storage_paths.each do |repository_storage_path|
commands << %W(mkdir -p #{repository_storage_path})
commands << %W(chmod ug+rwX,o-rwx #{repository_storage_path})
end
commands.each do |cmd|
print "#{cmd.join(' ')}: "
if system(*cmd)
......
......@@ -24,12 +24,6 @@ http_settings:
# ca_path: /etc/pki/tls/certs
self_signed_cert: false
# Repositories path
# Give the canonicalized absolute pathname,
# REPOS_PATH MUST NOT CONTAIN ANY SYMLINK!!!
# Check twice that none of the components is a symlink, including "/home".
repos_path: "/home/git/repositories"
# File used as authorized_keys for gitlab user
auth_file: "/home/git/.ssh/authorized_keys"
......
......@@ -15,7 +15,7 @@ class GitlabAccess
@config = GitlabConfig.new
@repo_path = repo_path.strip
@actor = actor
@repo_name = extract_repo_name(@repo_path.dup, config.repos_path.to_s)
@repo_name = extract_repo_name(@repo_path.dup)
@changes = changes.lines
end
......
require 'json'
class GitAccessStatus
attr_reader :message
attr_reader :message, :repository_path
def initialize(status, message)
def initialize(status, message, repository_path)
@status = status
@message = message
@repository_path = repository_path
end
def self.create_from_json(json)
values = JSON.parse(json)
self.new(values["status"], values["message"])
self.new(values["status"], values["message"], values["repository_path"])
end
def allowed?
......
......@@ -11,10 +11,6 @@ class GitlabConfig
ENV['HOME']
end
def repos_path
@config['repos_path'] ||= File.join(home, "repositories")
end
def auth_file
@config['auth_file'] ||= File.join(home, ".ssh/authorized_keys")
end
......
......@@ -38,7 +38,7 @@ class GitlabNet
if resp.code == '200'
GitAccessStatus.create_from_json(resp.body)
else
GitAccessStatus.new(false, 'API is not accessible')
GitAccessStatus.new(false, 'API is not accessible', nil)
end
end
......
......@@ -43,8 +43,8 @@ class GitlabProjects
def initialize
@command = ARGV.shift
@repos_path = ARGV.shift
@project_name = ARGV.shift
@repos_path = GitlabConfig.new.repos_path
@full_path = File.join(@repos_path, @project_name) unless @project_name.nil?
end
......
......@@ -9,12 +9,12 @@ class GitlabShell
GIT_COMMANDS = %w(git-upload-pack git-receive-pack git-upload-archive git-annex-shell git-lfs-authenticate).freeze
attr_accessor :key_id, :repo_name, :git_cmd, :repos_path, :repo_name
attr_accessor :key_id, :repo_name, :git_cmd
attr_reader :repo_path
def initialize(key_id)
@key_id = key_id
@config = GitlabConfig.new
@repos_path = @config.repos_path
end
# The origin_cmd variable contains UNTRUSTED input. If the user ran
......@@ -66,13 +66,10 @@ class GitlabShell
when 'git-annex-shell'
raise DisallowedCommandError unless @config.git_annex_enabled?
@repo_name = escape_path(args[2].sub(/\A\/~\//, ''))
# Make sure repository has git-annex enabled
init_git_annex(@repo_name) unless gcryptsetup?(args)
@repo_name = args[2].sub(/\A\/~\//, '')
when 'git-lfs-authenticate'
raise DisallowedCommandError unless args.count >= 2
@repo_name = escape_path(args[1])
@repo_name = args[1]
case args[2]
when 'download'
@git_access = 'git-upload-pack'
......@@ -83,7 +80,7 @@ class GitlabShell
end
else
raise DisallowedCommandError unless args.count == 2
@repo_name = escape_path(args.last)
@repo_name = args.last
end
end
......@@ -91,19 +88,22 @@ class GitlabShell
status = api.check_access(@git_access, @repo_name, @key_id, '_any')
raise AccessDeniedError, status.message unless status.allowed?
self.repo_path = status.repository_path
end
def process_cmd(args)
repo_full_path = File.join(repos_path, repo_name)
if @git_cmd == 'git-annex-shell'
raise DisallowedCommandError unless @config.git_annex_enabled?
# Make sure repository has git-annex enabled
init_git_annex unless gcryptsetup?(args)
parsed_args =
args.map do |arg|
# use full repo path
if arg =~ /\A\/.*\.git\Z/
repo_full_path
repo_path
else
arg
end
......@@ -112,8 +112,8 @@ class GitlabShell
$logger.info "gitlab-shell: executing git-annex command <#{parsed_args.join(' ')}> for #{log_username}."
exec_cmd(*parsed_args)
else
$logger.info "gitlab-shell: executing git command <#{@git_cmd} #{repo_full_path}> for #{log_username}."
exec_cmd(@git_cmd, repo_full_path)
$logger.info "gitlab-shell: executing git command <#{@git_cmd} #{repo_path}> for #{log_username}."
exec_cmd(@git_cmd, repo_path)
end
end
......@@ -164,23 +164,11 @@ class GitlabShell
@config.audit_usernames ? username : "user with key #{@key_id}"
end
def escape_path(path)
full_repo_path = File.join(repos_path, path)
if File.absolute_path(full_repo_path) == full_repo_path
path
else
raise InvalidRepositoryPathError
end
end
def init_git_annex(path)
full_repo_path = File.join(repos_path, path)
unless File.exists?(File.join(full_repo_path, 'annex'))
cmd = %W(git --git-dir=#{full_repo_path} annex init "GitLab")
def init_git_annex
unless File.exists?(File.join(repo_path, 'annex'))
cmd = %W(git --git-dir=#{repo_path} annex init "GitLab")
system(*cmd, err: '/dev/null', out: '/dev/null')
$logger.info "Enable git-annex for repository: #{path}."
$logger.info "Enable git-annex for repository: #{repo_name}."
end
end
......@@ -188,4 +176,12 @@ class GitlabShell
non_dashed = args.reject { |a| a.start_with?('-') }
non_dashed[0, 2] == %w{git-annex-shell gcryptsetup}
end
private
def repo_path=(repo_path)
raise InvalidRepositoryPathError if File.absolute_path(repo_path) != repo_path
@repo_path = repo_path
end
end
module NamesHelper
def extract_repo_name(path, base)
def extract_repo_name(path)
repo_name = path.strip
repo_name.gsub!(base, "")
repo_name.gsub!(/\.git$/, "")
repo_name.gsub!(/^\//, "")
repo_name
repo_name.split(File::SEPARATOR).last(2).join(File::SEPARATOR)
end
def extract_ref_name(ref)
......
......@@ -7,7 +7,7 @@ describe GitlabAccess do
let(:repo_path) { File.join(repository_path, repo_name) + ".git" }
let(:api) do
double(GitlabNet).tap do |api|
api.stub(check_access: GitAccessStatus.new(true, 'ok'))
api.stub(check_access: GitAccessStatus.new(true, 'ok', '/home/git/repositories'))
end
end
subject do
......@@ -38,7 +38,7 @@ describe GitlabAccess do
context "access is denied" do
before do
api.stub(check_access: GitAccessStatus.new(false, 'denied'))
api.stub(check_access: GitAccessStatus.new(false, 'denied', nil))
end
it "returns false" do
......
......@@ -59,21 +59,22 @@ describe GitlabProjects do
describe :initialize do
before do
argv('add-project', repo_name)
argv('add-project', tmp_repos_path, repo_name)
@gl_projects = GitlabProjects.new
end
it { @gl_projects.project_name.should == repo_name }
it { @gl_projects.repos_path.should == tmp_repos_path }
it { @gl_projects.full_path.should == "#{tmp_repos_path}/gitlab-ci.git" }
it { @gl_projects.instance_variable_get(:@command).should == 'add-project' }
it { @gl_projects.instance_variable_get(:@full_path).should == "#{GitlabConfig.new.repos_path}/gitlab-ci.git" }
end
describe :create_tag do
let(:gl_projects_create) {
build_gitlab_projects('import-project', repo_name, 'https://github.com/randx/six.git')
build_gitlab_projects('import-project', tmp_repos_path, repo_name, 'https://github.com/randx/six.git')
}
context "lightweight tag" do
let(:gl_projects) { build_gitlab_projects('create-tag', repo_name, 'test_tag', 'master') }
let(:gl_projects) { build_gitlab_projects('create-tag', tmp_repos_path, repo_name, 'test_tag', 'master') }
it "should create a tag" do
gl_projects_create.exec
......@@ -87,7 +88,7 @@ describe GitlabProjects do
msg = 'some message'
tag_name = 'test_annotated_tag'
let(:gl_projects) { build_gitlab_projects('create-tag', repo_name, tag_name, 'master', msg) }
let(:gl_projects) { build_gitlab_projects('create-tag', tmp_repos_path, repo_name, tag_name, 'master', msg) }
it "should create an annotated tag" do
gl_projects_create.exec
......@@ -106,7 +107,7 @@ describe GitlabProjects do
end
describe :add_project do
let(:gl_projects) { build_gitlab_projects('add-project', repo_name) }
let(:gl_projects) { build_gitlab_projects('add-project', tmp_repos_path, repo_name) }
it "should create a directory" do
gl_projects.stub(system: true)
......@@ -130,7 +131,7 @@ describe GitlabProjects do
describe :list_projects do
let(:gl_projects) do
build_gitlab_projects('add-project', "list_test/#{repo_name}")
build_gitlab_projects('add-project', tmp_repos_path, "list_test/#{repo_name}")
end
before do
......@@ -145,7 +146,7 @@ describe GitlabProjects do
end
describe :mv_project do
let(:gl_projects) { build_gitlab_projects('mv-project', repo_name, 'repo.git') }
let(:gl_projects) { build_gitlab_projects('mv-project', tmp_repos_path, repo_name, 'repo.git') }
let(:new_repo_path) { File.join(tmp_repos_path, 'repo.git') }
before do
......@@ -160,20 +161,20 @@ describe GitlabProjects do
end
it "should fail if no destination path is provided" do
incomplete = build_gitlab_projects('mv-project', repo_name)
incomplete = build_gitlab_projects('mv-project', tmp_repos_path, repo_name)
$logger.should_receive(:error).with("mv-project failed: no destination path provided.")
incomplete.exec.should be_false
end
it "should fail if the source path doesn't exist" do
bad_source = build_gitlab_projects('mv-project', 'bad-src.git', 'dest.git')
bad_source = build_gitlab_projects('mv-project', tmp_repos_path, 'bad-src.git', 'dest.git')
$logger.should_receive(:error).with("mv-project failed: source path <#{tmp_repos_path}/bad-src.git> does not exist.")
bad_source.exec.should be_false
end
it "should fail if the destination path already exists" do
FileUtils.mkdir_p(File.join(tmp_repos_path, 'already-exists.git'))
bad_dest = build_gitlab_projects('mv-project', repo_name, 'already-exists.git')
bad_dest = build_gitlab_projects('mv-project', tmp_repos_path, repo_name, 'already-exists.git')
message = "mv-project failed: destination path <#{tmp_repos_path}/already-exists.git> already exists."
$logger.should_receive(:error).with(message)
bad_dest.exec.should be_false
......@@ -187,7 +188,7 @@ describe GitlabProjects do
end
describe :rm_project do
let(:gl_projects) { build_gitlab_projects('rm-project', repo_name) }
let(:gl_projects) { build_gitlab_projects('rm-project', tmp_repos_path, repo_name) }
before do
FileUtils.mkdir_p(tmp_repo_path)
......@@ -207,7 +208,7 @@ describe GitlabProjects do
describe :import_project do
context 'success import' do
let(:gl_projects) { build_gitlab_projects('import-project', repo_name, 'https://github.com/randx/six.git') }
let(:gl_projects) { build_gitlab_projects('import-project', tmp_repos_path, repo_name, 'https://github.com/randx/six.git') }
it { gl_projects.exec.should be_true }
......@@ -224,7 +225,7 @@ describe GitlabProjects do
end
context 'already exists' do
let(:gl_projects) { build_gitlab_projects('import-project', repo_name, 'https://github.com/randx/six.git') }
let(:gl_projects) { build_gitlab_projects('import-project', tmp_repos_path, repo_name, 'https://github.com/randx/six.git') }
it 'should import only once' do
gl_projects.exec.should be_true
......@@ -233,7 +234,7 @@ describe GitlabProjects do
end
context 'timeout' do
let(:gl_projects) { build_gitlab_projects('import-project', repo_name, 'https://github.com/gitlabhq/gitlabhq.git', '1') }
let(:gl_projects) { build_gitlab_projects('import-project', tmp_repos_path, repo_name, 'https://github.com/gitlabhq/gitlabhq.git', '1') }
it { gl_projects.exec.should be_false }
......@@ -253,15 +254,15 @@ describe GitlabProjects do
describe :fork_project do
let(:source_repo_name) { File.join('source-namespace', repo_name) }
let(:dest_repo) { File.join(tmp_repos_path, 'forked-to-namespace', repo_name) }
let(:gl_projects_fork) { build_gitlab_projects('fork-project', source_repo_name, 'forked-to-namespace') }
let(:gl_projects_import) { build_gitlab_projects('import-project', source_repo_name, 'https://github.com/randx/six.git') }
let(:gl_projects_fork) { build_gitlab_projects('fork-project', tmp_repos_path, source_repo_name, 'forked-to-namespace') }
let(:gl_projects_import) { build_gitlab_projects('import-project', tmp_repos_path, source_repo_name, 'https://github.com/randx/six.git') }
before do
gl_projects_import.exec
end
it "should not fork without a destination namespace" do
missing_arg = build_gitlab_projects('fork-project', source_repo_name)
missing_arg = build_gitlab_projects('fork-project', tmp_repos_path, source_repo_name)
$logger.should_receive(:error).with("fork-project failed: no destination namespace provided.")
missing_arg.exec.should be_false
end
......@@ -304,13 +305,13 @@ describe GitlabProjects do
describe :exec do
it 'should puts message if unknown command arg' do
gitlab_projects = build_gitlab_projects('edit-project', repo_name)
gitlab_projects = build_gitlab_projects('edit-project', tmp_repos_path, repo_name)
gitlab_projects.should_receive(:puts).with('not allowed')
gitlab_projects.exec
end
it 'should log a warning for unknown commands' do
gitlab_projects = build_gitlab_projects('hurf-durf', repo_name)
gitlab_projects = build_gitlab_projects('hurf-durf', tmp_repos_path, repo_name)
$logger.should_receive(:warn).with('Attempt to execute invalid gitlab-projects command "hurf-durf".')
gitlab_projects.exec
end
......
......@@ -22,7 +22,7 @@ describe GitlabShell do
let(:api) do
double(GitlabNet).tap do |api|
api.stub(discover: { 'name' => 'John Doe' })
api.stub(check_access: GitAccessStatus.new(true, 'ok'))
api.stub(check_access: GitAccessStatus.new(true, 'ok', repo_path))
end
end
......@@ -30,15 +30,17 @@ describe GitlabShell do
let(:ssh_cmd) { nil }
let(:tmp_repos_path) { File.join(ROOT_PATH, 'tmp', 'repositories') }
let(:repo_name) { 'gitlab-ci.git' }
let(:repo_path) { File.join(tmp_repos_path, repo_name) }
before do
GitlabConfig.any_instance.stub(repos_path: tmp_repos_path, audit_usernames: false)
GitlabConfig.any_instance.stub(audit_usernames: false)
end
describe :initialize do
let(:ssh_cmd) { 'git-receive-pack' }
its(:key_id) { should == key_id }
its(:repos_path) { should == tmp_repos_path }
end
describe :parse_cmd do
......@@ -55,6 +57,7 @@ describe GitlabShell do
end
context 'namespace' do
let(:repo_name) { 'dmitriy.zaporozhets/gitlab-ci.git' }
let(:ssh_args) { %W(git-upload-pack dmitriy.zaporozhets/gitlab-ci.git) }
before do
......@@ -75,50 +78,24 @@ describe GitlabShell do
end
describe 'git-annex' do
let(:repo_path) { File.join(tmp_repos_path, 'dzaporozhets/gitlab.git') }
let(:repo_name) { 'dzaporozhets/gitlab.git' }
let(:ssh_args) { %W(git-annex-shell inannex /~/dzaporozhets/gitlab.git SHA256E) }
before do
GitlabConfig.any_instance.stub(git_annex_enabled?: true)
# Create existing project
FileUtils.mkdir_p(repo_path)
cmd = %W(git --git-dir=#{repo_path} init --bare)
system(*cmd)
subject.send :parse_cmd, ssh_args
end
its(:repo_name) { should == 'dzaporozhets/gitlab.git' }
its(:git_cmd) { should == 'git-annex-shell' }
it 'should init git-annex' do
File.exists?(File.join(tmp_repos_path, 'dzaporozhets/gitlab.git/annex')).should be_true
end
context 'with git-annex-shell gcryptsetup' do
let(:ssh_args) { %W(git-annex-shell gcryptsetup /~/dzaporozhets/gitlab.git) }
it 'should not init git-annex' do
File.exists?(File.join(tmp_repos_path, 'dzaporozhets/gitlab.git/annex')).should be_false
end
end
context 'with git-annex and relative path without ~/' do
# Using a SSH URL on a custom port will generate /dzaporozhets/gitlab.git
let(:ssh_args) { %W(git-annex-shell inannex /dzaporozhets/gitlab.git SHA256E) }
it 'should init git-annex' do
File.exists?(File.join(tmp_repos_path, 'dzaporozhets/gitlab.git/annex')).should be_true
end
end
end
end
describe :exec do
context 'git-upload-pack' do
let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' }
let(:ssh_cmd) { "git-upload-pack gitlab-ci.git" }
after { subject.exec(ssh_cmd) }
it "should process the command" do
......@@ -126,12 +103,12 @@ describe GitlabShell do
end
it "should execute the command" do
subject.should_receive(:exec_cmd).with("git-upload-pack", File.join(tmp_repos_path, 'gitlab-ci.git'))
subject.should_receive(:exec_cmd).with("git-upload-pack", repo_path)
end
it "should log the command execution" do
message = "gitlab-shell: executing git command "
message << "<git-upload-pack #{File.join(tmp_repos_path, 'gitlab-ci.git')}> "
message << "<git-upload-pack #{repo_path}> "
message << "for user with key #{key_id}."
$logger.should_receive(:info).with(message)
end
......@@ -143,7 +120,7 @@ describe GitlabShell do
end
context 'git-receive-pack' do
let(:ssh_cmd) { 'git-receive-pack gitlab-ci.git' }
let(:ssh_cmd) { "git-receive-pack gitlab-ci.git" }
after { subject.exec(ssh_cmd) }
it "should process the command" do
......@@ -151,12 +128,12 @@ describe GitlabShell do
end
it "should execute the command" do
subject.should_receive(:exec_cmd).with("git-receive-pack", File.join(tmp_repos_path, 'gitlab-ci.git'))
subject.should_receive(:exec_cmd).with("git-receive-pack", repo_path)
end
it "should log the command execution" do
message = "gitlab-shell: executing git command "
message << "<git-receive-pack #{File.join(tmp_repos_path, 'gitlab-ci.git')}> "
message << "<git-receive-pack #{repo_path}> "
message << "for user with key #{key_id}."
$logger.should_receive(:info).with(message)
end
......@@ -206,37 +183,96 @@ describe GitlabShell do
end
describe 'git-annex' do
let(:ssh_cmd) { 'git-annex-shell commit /~/gitlab-ci.git SHA256' }
let(:repo_name) { 'dzaporozhets/gitlab.git' }
before do
GitlabConfig.any_instance.stub(git_annex_enabled?: true)
end
context 'initialization' do
let(:ssh_cmd) { "git-annex-shell inannex /~/gitlab-ci.git SHA256E" }
before do
# Create existing project
FileUtils.mkdir_p(repo_path)
cmd = %W(git --git-dir=#{repo_path} init --bare)
system(*cmd)
subject.exec(ssh_cmd)
end
it 'should init git-annex' do
File.exists?(repo_path).should be_true
end
context 'with git-annex-shell gcryptsetup' do
let(:ssh_cmd) { "git-annex-shell gcryptsetup /~/dzaporozhets/gitlab.git" }
it 'should not init git-annex' do
File.exists?(File.join(tmp_repos_path, 'dzaporozhets/gitlab.git/annex')).should be_false
end
end
context 'with git-annex and relative path without ~/' do
# Using a SSH URL on a custom port will generate /dzaporozhets/gitlab.git
let(:ssh_cmd) { "git-annex-shell inannex dzaporozhets/gitlab.git SHA256E" }
it 'should init git-annex' do
File.exists?(File.join(tmp_repos_path, "dzaporozhets/gitlab.git/annex")).should be_true
end
end
end
context 'execution' do
let(:ssh_cmd) { "git-annex-shell commit /~/gitlab-ci.git SHA256" }
after { subject.exec(ssh_cmd) }
it "should execute the command" do
subject.should_receive(:exec_cmd).with("git-annex-shell", "commit", File.join(tmp_repos_path, 'gitlab-ci.git'), "SHA256")
subject.should_receive(:exec_cmd).with("git-annex-shell", "commit", repo_path, "SHA256")
end
end
end
end
describe :validate_access do
let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' }
let(:ssh_cmd) { "git-upload-pack gitlab-ci.git" }
describe 'check access with api' do
after { subject.exec(ssh_cmd) }
it "should call api.check_access" do
api.should_receive(:check_access).
with('git-upload-pack', 'gitlab-ci.git', key_id, '_any')
api.should_receive(:check_access).with('git-upload-pack', 'gitlab-ci.git', key_id, '_any')
end
it "should disallow access and log the attempt if check_access returns false status" do
api.stub(check_access: GitAccessStatus.new(false, 'denied'))
api.stub(check_access: GitAccessStatus.new(false, 'denied', nil))
message = "gitlab-shell: Access denied for git command <git-upload-pack gitlab-ci.git> "
message << "by user with key #{key_id}."
$logger.should_receive(:warn).with(message)
end
end
describe 'set the repository path' do
context 'with a correct path' do
before { subject.exec(ssh_cmd) }
its(:repo_path) { should == repo_path }
end
context "with a path that doesn't match an absolute path" do
before do
File.stub(:absolute_path) { 'y/gitlab-ci.git' }
end
it "refuses to assign the path" do
$stderr.should_receive(:puts).with("GitLab: Invalid repository path")
expect(subject.exec(ssh_cmd)).to be_false
end
end
end
end
describe :exec_cmd do
let(:shell) { GitlabShell.new(key_id) }
before { Kernel.stub!(:exec) }
......@@ -262,12 +298,4 @@ describe GitlabShell do
it { should be_a(GitlabNet) }
end
describe :escape_path do
let(:shell) { GitlabShell.new(key_id) }
before { File.stub(:absolute_path) { 'y' } }
subject { -> { shell.send(:escape_path, 'z') } }
it { should raise_error(GitlabShell::InvalidRepositoryPathError) }
end
end
......@@ -5,8 +5,8 @@ describe NamesHelper do
include NamesHelper
describe :extract_repo_name do
it { extract_repo_name(' /opt/repos/randx/gitlab.git', '/opt/repos').should == 'randx/gitlab' }
it { extract_repo_name("/opt/repos/randx/gitlab.git\r\n", '/opt/repos/').should == 'randx/gitlab' }
it { extract_repo_name(' /opt/repos/randx/gitlab.git').should == 'randx/gitlab' }
it { extract_repo_name("/opt/repos/randx/gitlab.git\r\n").should == 'randx/gitlab' }
end
describe :extract_ref_name do
......@@ -15,4 +15,3 @@ describe NamesHelper do
it { extract_ref_name('refs/tags/releases/v2.2.1').should == 'releases/v2.2.1' }
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment