diff options
31 files changed, 350 insertions, 208 deletions
diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 0000000..4799e9d --- /dev/null +++ b/.hound.yml @@ -0,0 +1,3 @@ +StringLiterals: + EnforcedStyle: single_quotes + Enabled: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0b677af..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: ruby -env: - - TRAVIS=true -branches: - only: - - 'master' -rvm: - - 1.9.3-p327 - - 2.0.0 -before_script: - - "cp config.yml.example config.yml" -script: "bundle exec rspec spec" - @@ -1,3 +1,15 @@ +v2.0.1 + - Send post-receive changes to redis as a string instead of array + +v2.0.0 + - Works with GitLab v7.3+ + - Replace raise with abort when checking path to prevent path exposure + - Handle invalid number of arguments on remote commands + - Replace update hook with pre-receive and post-receive hooks. + - Symlink the whole hooks directory + - Ignore missing repositories in create-hooks + - Connect to Redis via sockets by default + v1.9.7 - Increased test coverage - By default use direct unicorn connection (localhost:8080) @@ -7,7 +7,7 @@ It is not a Unix shell nor a replacement for Bash or Zsh. ## Code status [](http://ci.gitlab.org/projects/4?ref=master) -[](https://travis-ci.org/gitlabhq/gitlab-shell) +[](https://semaphoreapp.com/gitlabhq/gitlab-shell) [](https://codeclimate.com/github/gitlabhq/gitlab-shell) [](https://coveralls.io/r/gitlabhq/gitlab-shell) @@ -1 +1 @@ -1.9.7 +2.0.1 diff --git a/bin/create-hooks b/bin/create-hooks index d6f07c7..4efa650 100755 --- a/bin/create-hooks +++ b/bin/create-hooks @@ -8,5 +8,9 @@ require_relative '../lib/gitlab_init' require File.join(ROOT_PATH, 'lib', 'gitlab_projects') Dir["#{GitlabConfig.new.repos_path}/*/*.git"].each do |repo| - GitlabProjects.create_hooks(repo) + begin + GitlabProjects.create_hooks(repo) + rescue Errno::ENOENT + # The user must have deleted their repository. Ignore. + end end diff --git a/config.yml.example b/config.yml.example index 413aa81..97b5006 100644 --- a/config.yml.example +++ b/config.yml.example @@ -28,9 +28,11 @@ auth_file: "/home/git/.ssh/authorized_keys" # Redis settings used for pushing commit notices to gitlab redis: bin: /usr/bin/redis-cli - host: 127.0.0.1 - port: 6379 - # socket: /tmp/redis.socket # Only define this if you want to use sockets + # host: 127.0.0.1 + # port: 6379 + # pass: redispass # Allows you to specify the password for Redis + database: 0 + socket: /var/run/redis/redis.sock # Comment out this line if you want to use TCP namespace: resque:gitlab # Log file. diff --git a/hooks/post-receive b/hooks/post-receive new file mode 100755 index 0000000..d85ad42 --- /dev/null +++ b/hooks/post-receive @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file was placed here by GitLab. It makes sure that your pushed commits +# will be processed properly. +# You can add your own hooks to this file, but be careful when updating gitlab-shell! + +changes = ARGF.read +key_id = ENV['GL_ID'] +repo_path = Dir.pwd + +require_relative '../lib/gitlab_post_receive' + +if GitlabPostReceive.new(repo_path, key_id, changes).exec + exit 0 +else + exit 1 +end diff --git a/hooks/update b/hooks/pre-receive index 6f762e8..2b979fa 100755 --- a/hooks/update +++ b/hooks/pre-receive @@ -4,10 +4,14 @@ # will be processed properly. # You can add your own hooks to this file, but be careful when updating gitlab-shell! -refname = ARGV[0] +refs = ARGF.read key_id = ENV['GL_ID'] repo_path = Dir.pwd -require_relative '../lib/gitlab_update' +require_relative '../lib/gitlab_access' -GitlabUpdate.new(repo_path, key_id, refname).exec +if GitlabAccess.new(repo_path, key_id, refs).exec + exit 0 +else + exit 1 +end diff --git a/lib/gitlab_access.rb b/lib/gitlab_access.rb new file mode 100644 index 0000000..63c074b --- /dev/null +++ b/lib/gitlab_access.rb @@ -0,0 +1,34 @@ +require_relative 'gitlab_init' +require_relative 'gitlab_net' +require_relative 'names_helper' +require 'json' + +class GitlabAccess + include NamesHelper + + attr_reader :config, :repo_path, :repo_name, :changes + + def initialize(repo_path, actor, changes) + @config = GitlabConfig.new + @repo_path, @actor = repo_path.strip, actor + @repo_name = extract_repo_name(@repo_path.dup, config.repos_path.to_s) + @changes = changes.lines + end + + def exec + if api.allowed?('git-receive-pack', @repo_name, @actor, @changes) + exit 0 + else + # reset GL_ID env since we stop git push here + ENV['GL_ID'] = nil + puts "GitLab: You are not allowed to access some of the refs!" + exit 1 + end + end + + protected + + def api + GitlabNet.new + end +end diff --git a/lib/gitlab_config.rb b/lib/gitlab_config.rb index ad15247..c97743b 100644 --- a/lib/gitlab_config.rb +++ b/lib/gitlab_config.rb @@ -7,12 +7,16 @@ class GitlabConfig @config = YAML.load_file(File.join(ROOT_PATH, 'config.yml')) end + def home + ENV['HOME'] + end + def repos_path - @config['repos_path'] ||= "/home/git/repositories" + @config['repos_path'] ||= File.join(home, "repositories") end def auth_file - @config['auth_file'] ||= "/home/git/.ssh/authorized_keys" + @config['auth_file'] ||= File.join(home, ".ssh/authorized_keys") end def gitlab_url @@ -50,10 +54,17 @@ class GitlabConfig # for users that haven't updated their configuration %W(env -i redis-cli) else + redis['database'] ||= 0 + redis['host'] ||= '127.0.0.1' + redis['port'] ||= '6379' if redis.has_key?("socket") - %W(#{redis['bin']} -s #{redis['socket']}) + %W(#{redis['bin']} -s #{redis['socket']} -n #{redis['database']}) else - %W(#{redis['bin']} -h #{redis['host']} -p #{redis['port']}) + if redis.has_key?("pass") + %W(#{redis['bin']} -h #{redis['host']} -p #{redis['port']} -n #{redis['database']} -a #{redis['pass']}) + else + %W(#{redis['bin']} -h #{redis['host']} -p #{redis['port']} -n #{redis['database']}) + end end end end diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb index 6397106..1eb043f 100644 --- a/lib/gitlab_net.rb +++ b/lib/gitlab_net.rb @@ -6,29 +6,25 @@ require_relative 'gitlab_config' require_relative 'gitlab_logger' class GitlabNet - def allowed?(cmd, repo, actor, ref, oldrev = nil, newrev = nil, forced_push = false) + def allowed?(cmd, repo, actor, changes) project_name = repo.gsub("'", "") project_name = project_name.gsub(/\.git\Z/, "") project_name = project_name.gsub(/\A\//, "") params = { action: cmd, - ref: ref, + changes: changes, project: project_name, - forced_push: forced_push, } - params.merge!(oldrev: oldrev) if oldrev - params.merge!(newrev: newrev) if newrev - if actor =~ /\Akey\-\d+\Z/ params.merge!(key_id: actor.gsub("key-", "")) elsif actor =~ /\Auser\-\d+\Z/ params.merge!(user_id: actor.gsub("user-", "")) end - url = "#{host}/allowed?" + URI.encode_www_form(params) - resp = get(url) + url = "#{host}/allowed" + resp = post(url, params) !!(resp.code == '200' && resp.body == 'true') end @@ -63,10 +59,15 @@ class GitlabNet end end - def http_request_for(url) + def http_request_for(url, method = :get) user = config.http_settings['user'] password = config.http_settings['password'] - Net::HTTP::Get.new(url.request_uri).tap { |r| r.basic_auth(user, password) if user && password } + + if method == :get + Net::HTTP::Get.new(url.request_uri).tap { |r| r.basic_auth(user, password) if user && password } + else + Net::HTTP::Post.new(url.request_uri).tap { |r| r.basic_auth(user, password) if user && password } + end end def get(url) @@ -85,8 +86,25 @@ class GitlabNet end end + def post(url, params) + $logger.debug "Performing POST #{url}" + + url = URI.parse(url) + http = http_client_for(url) + request = http_request_for(url, :post) + request.set_form_data(params) + + http.start { |http| http.request(request) }.tap do |resp| + if resp.code == "200" + $logger.debug { "Received response #{resp.code} => <#{resp.body}>." } + else + $logger.error { "API call <POST #{url}> failed: #{resp.code} => <#{resp.body}>." } + end + end + end + def cert_store - @cert_store ||= OpenSSL::X509::Store.new.tap { |store| + @cert_store ||= OpenSSL::X509::Store.new.tap do |store| store.set_default_paths if ca_file = config.http_settings['ca_file'] @@ -96,6 +114,6 @@ class GitlabNet if ca_path = config.http_settings['ca_path'] store.add_path(ca_path) end - } + end end end diff --git a/lib/gitlab_post_receive.rb b/lib/gitlab_post_receive.rb new file mode 100644 index 0000000..bd80408 --- /dev/null +++ b/lib/gitlab_post_receive.rb @@ -0,0 +1,31 @@ +require_relative 'gitlab_init' +require 'json' + +class GitlabPostReceive + attr_reader :config, :repo_path, :changes + + def initialize(repo_path, actor, changes) + @config = GitlabConfig.new + @repo_path, @actor = repo_path.strip, actor + @changes = changes + end + + def exec + # reset GL_ID env since we already + # get value from it + ENV['GL_ID'] = nil + + update_redis + end + + protected + + def update_redis + queue = "#{config.redis_namespace}:queue:post_receive" + msg = JSON.dump({'class' => 'PostReceive', 'args' => [@repo_path, @actor, @changes]}) + unless system(*config.redis_command, 'rpush', queue, msg, err: '/dev/null', out: '/dev/null') + puts "GitLab: An unexpected error occurred (redis-cli returned #{$?.exitstatus})." + exit 1 + end + end +end diff --git a/lib/gitlab_projects.rb b/lib/gitlab_projects.rb index a6fa1b5..58bbd28 100644 --- a/lib/gitlab_projects.rb +++ b/lib/gitlab_projects.rb @@ -5,6 +5,8 @@ require_relative 'gitlab_config' require_relative 'gitlab_logger' class GitlabProjects + GLOBAL_HOOKS_DIRECTORY = File.join(ROOT_PATH, 'hooks') + # Project name is a directory name for repository with .git at the end # It may be namespaced or not. Like repo.git or gitlab/repo.git attr_reader :project_name @@ -18,9 +20,11 @@ class GitlabProjects attr_reader :full_path def self.create_hooks(path) - hook = File.join(path, 'hooks', 'update') - File.delete(hook) if File.exists?(hook) - File.symlink(File.join(ROOT_PATH, 'hooks', 'update'), hook) + local_hooks_directory = File.join(path, 'hooks') + unless File.realpath(local_hooks_directory) == File.realpath(GLOBAL_HOOKS_DIRECTORY) + FileUtils.mv(local_hooks_directory, "#{local_hooks_directory}.old.#{Time.now.to_i}") + FileUtils.ln_s(GLOBAL_HOOKS_DIRECTORY, local_hooks_directory) + end end def initialize @@ -94,6 +98,20 @@ class GitlabProjects FileUtils.rm_rf(full_path) end + def mask_password_in_url(url) + result = URI(url) + result.password = "*****" unless result.password.nil? + result + rescue + url + end + + def remove_origin_in_repo + cmd = %W(git --git-dir=#{full_path} remote rm origin) + pid = Process.spawn(*cmd) + Process.wait(pid) + end + # Import project via git clone --bare # URL must be publicly cloneable def import_project @@ -101,10 +119,11 @@ class GitlabProjects return false if File.exists?(full_path) @source = ARGV.shift + masked_source = mask_password_in_url(@source) # timeout for clone timeout = (ARGV.shift || 120).to_i - $logger.info "Importing project #{@project_name} from <#{@source}> to <#{full_path}>." + $logger.info "Importing project #{@project_name} from <#{masked_source}> to <#{full_path}>." cmd = %W(git clone --bare -- #{@source} #{full_path}) pid = Process.spawn(*cmd) @@ -114,7 +133,7 @@ class GitlabProjects Process.wait(pid) end rescue Timeout::Error - $logger.error "Importing project #{@project_name} from <#{@source}> failed due to timeout." + $logger.error "Importing project #{@project_name} from <#{masked_source}> failed due to timeout." Process.kill('KILL', pid) Process.wait @@ -122,6 +141,9 @@ class GitlabProjects false else self.class.create_hooks(full_path) + # The project was imported successfully. + # Remove the origin URL since it may contain password. + remove_origin_in_repo end end diff --git a/lib/gitlab_shell.rb b/lib/gitlab_shell.rb index 086e36b..d0f23d7 100644 --- a/lib/gitlab_shell.rb +++ b/lib/gitlab_shell.rb @@ -3,6 +3,8 @@ require 'shellwords' require_relative 'gitlab_net' class GitlabShell + class DisallowedCommandError < StandardError; end + attr_accessor :key_id, :repo_name, :git_cmd, :repos_path, :repo_name def initialize @@ -28,19 +30,22 @@ class GitlabShell $stderr.puts "Access denied." end else - message = "gitlab-shell: Attempt to execute disallowed command <#{@origin_cmd}> by #{log_username}." - $logger.warn message - puts 'Not allowed command' + raise DisallowedCommandError end else puts "Welcome to GitLab, #{username}!" end + rescue DisallowedCommandError => ex + message = "gitlab-shell: Attempt to execute disallowed command <#{@origin_cmd}> by #{log_username}." + $logger.warn message + puts 'Not allowed command' end protected def parse_cmd args = Shellwords.shellwords(@origin_cmd) + raise DisallowedCommandError unless args.count == 2 @git_cmd = args[0] @repo_name = escape_path(args[1]) end @@ -93,7 +98,7 @@ class GitlabShell if File.absolute_path(full_repo_path) == full_repo_path path else - raise "Wrong repository path" + abort "Wrong repository path" end end end diff --git a/lib/gitlab_update.rb b/lib/gitlab_update.rb deleted file mode 100644 index cd7a1e5..0000000 --- a/lib/gitlab_update.rb +++ /dev/null @@ -1,58 +0,0 @@ -require_relative 'gitlab_init' -require_relative 'gitlab_net' -require_relative 'names_helper' -require 'json' - -class GitlabUpdate - include NamesHelper - - attr_reader :config, :repo_path, :repo_name, - :ref, :ref_name, :oldrev, :newrev - - def initialize(repo_path, actor, ref) - @config = GitlabConfig.new - @repo_path, @actor, @ref = repo_path.strip, actor, ref - @repo_name = extract_repo_name(@repo_path.dup, config.repos_path.to_s) - @ref_name = extract_ref_name(ref) - @oldrev = ARGV[1] - @newrev = ARGV[2] - end - - def forced_push? - if @oldrev !~ /00000000/ && @newrev !~ /00000000/ - missed_refs = IO.popen(%W(git rev-list #{@oldrev} ^#{@newrev})).read - missed_refs.split("\n").size > 0 - else - false - end - end - - def exec - # reset GL_ID env since we already - # get value from it - ENV['GL_ID'] = nil - - if api.allowed?('git-receive-pack', @repo_name, @actor, @ref_name, @oldrev, @newrev, forced_push?) - update_redis - exit 0 - else - puts "GitLab: You are not allowed to access #{@ref_name}!" - exit 1 - end - end - - protected - - def api - GitlabNet.new - end - - def update_redis - queue = "#{config.redis_namespace}:queue:post_receive" - msg = JSON.dump({'class' => 'PostReceive', 'args' => [@repo_path, @oldrev, @newrev, @ref, @actor]}) - unless system(*config.redis_command, 'rpush', queue, msg, err: '/dev/null', out: '/dev/null') - puts "GitLab: An unexpected error occurred (redis-cli returned #{$?.exitstatus})." - exit 1 - end - end -end diff --git a/spec/gitlab_access_spec.rb b/spec/gitlab_access_spec.rb new file mode 100644 index 0000000..13db4bd --- /dev/null +++ b/spec/gitlab_access_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' +require 'gitlab_access' + +describe GitlabAccess do + let(:repository_path) { "/home/git/repositories" } + let(:repo_name) { 'dzaporozhets/gitlab-ci' } + let(:repo_path) { File.join(repository_path, repo_name) + ".git" } + let(:gitlab_access) { GitlabAccess.new(repo_path, 'key-123', 'wow') } + + before do + GitlabConfig.any_instance.stub(repos_path: repository_path) + end + + describe :initialize do + it { gitlab_access.repo_name.should == repo_name } + it { gitlab_access.repo_path.should == repo_path } + it { gitlab_access.changes.should == ['wow'] } + end +end diff --git a/spec/gitlab_config_spec.rb b/spec/gitlab_config_spec.rb index 2b5525c..52fb182 100644 --- a/spec/gitlab_config_spec.rb +++ b/spec/gitlab_config_spec.rb @@ -5,26 +5,36 @@ describe GitlabConfig do let(:config) { GitlabConfig.new } describe :redis do - subject { config.redis } - - it { should be_a(Hash) } - it { should have_key('bin') } - it { should have_key('host') } - it { should have_key('port') } - it { should have_key('namespace') } - end - - describe :redis_namespace do - subject { config.redis_namespace } + before do + config.instance_variable_set(:@config, YAML.load(<<eos +redis: + bin: /usr/bin/redis-cli + host: 127.0.1.1 + port: 6378 + pass: secure + database: 1 + socket: /var/run/redis/redis.sock + namespace: my:gitlab +eos + )) + end - it { should eq('resque:gitlab') } + it { config.redis['bin'].should eq('/usr/bin/redis-cli') } + it { config.redis['host'].should eq('127.0.1.1') } + it { config.redis['port'].should eq(6378) } + it { config.redis['database'].should eq(1) } + it { config.redis['namespace'].should eq('my:gitlab') } + it { config.redis['socket'].should eq('/var/run/redis/redis.sock') } + it { config.redis['pass'].should eq('secure') } end describe :gitlab_url do + let(:url) { 'http://test.com' } subject { config.gitlab_url } + before { config.send(:config)['gitlab_url'] = url } it { should_not be_empty } - it { should eq('http://localhost:8080/') } + it { should eq(url) } end describe :audit_usernames do @@ -36,11 +46,6 @@ describe GitlabConfig do describe :redis_command do subject { config.redis_command } - it { should be_an(Array) } - it { should include(config.redis['host']) } - it { should include(config.redis['bin']) } - it { should include(config.redis['port'].to_s) } - context "with empty redis config" do before do config.stub(:redis) { {} } @@ -50,6 +55,17 @@ describe GitlabConfig do it { should include('redis-cli') } end + context "with host and port" do + before do + config.stub(:redis) { {'host' => 'localhost', 'port' => 1123, 'bin' => '/usr/bin/redis-cli'} } + end + + it { should be_an(Array) } + it { should include(config.redis['host']) } + it { should include(config.redis['bin']) } + it { should include(config.redis['port'].to_s) } + end + context "with redis socket" do let(:socket) { '/tmp/redis.socket' } before do @@ -62,4 +78,4 @@ describe GitlabConfig do it { should_not include('-h') } end end -end
\ No newline at end of file +end diff --git a/spec/gitlab_net_spec.rb b/spec/gitlab_net_spec.rb index 1b7ef4d..6b0b65a 100644 --- a/spec/gitlab_net_spec.rb +++ b/spec/gitlab_net_spec.rb @@ -4,6 +4,7 @@ require_relative '../lib/gitlab_net' describe GitlabNet, vcr: true do let(:gitlab_net) { GitlabNet.new } + let(:changes) { ['0000000000000000000000000000000000000000 92d0970eefd7acb6d548878925ce2208cfe2d2ec refs/heads/branch4'] } before do gitlab_net.stub!(:host).and_return('https://dev.gitlab.org/api/v3/internal') @@ -31,14 +32,14 @@ describe GitlabNet, vcr: true do context 'ssh key with access to project' do it 'should allow pull access for dev.gitlab.org' do VCR.use_cassette("allowed-pull") do - access = gitlab_net.allowed?('git-receive-pack', 'gitlab/gitlabhq.git', 'key-126', 'master') + access = gitlab_net.allowed?('git-receive-pack', 'gitlab/gitlabhq.git', 'key-126', changes) access.should be_true end end it 'should allow push access for dev.gitlab.org' do VCR.use_cassette("allowed-push") do - access = gitlab_net.allowed?('git-upload-pack', 'gitlab/gitlabhq.git', 'key-126', 'master') + access = gitlab_net.allowed?('git-upload-pack', 'gitlab/gitlabhq.git', 'key-126', changes) access.should be_true end end @@ -47,21 +48,21 @@ describe GitlabNet, vcr: true do context 'ssh key without access to project' do it 'should deny pull access for dev.gitlab.org' do VCR.use_cassette("denied-pull") do - access = gitlab_net.allowed?('git-receive-pack', 'gitlab/gitlabhq.git', 'key-2', 'master') + access = gitlab_net.allowed?('git-receive-pack', 'gitlab/gitlabhq.git', 'key-2', changes) access.should be_false end end it 'should deny push access for dev.gitlab.org' do VCR.use_cassette("denied-push") do - access = gitlab_net.allowed?('git-upload-pack', 'gitlab/gitlabhq.git', 'key-2', 'master') + access = gitlab_net.allowed?('git-upload-pack', 'gitlab/gitlabhq.git', 'key-2', changes) access.should be_false end end it 'should deny push access for dev.gitlab.org (with user)' do VCR.use_cassette("denied-push-with-user") do - access = gitlab_net.allowed?('git-upload-pack', 'gitlab/gitlabhq.git', 'user-1', 'master') + access = gitlab_net.allowed?('git-upload-pack', 'gitlab/gitlabhq.git', 'user-1', changes) access.should be_false end end diff --git a/spec/gitlab_post_receive_spec.rb b/spec/gitlab_post_receive_spec.rb new file mode 100644 index 0000000..50c6f0a --- /dev/null +++ b/spec/gitlab_post_receive_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' +require 'gitlab_post_receive' + +describe GitlabPostReceive do + let(:repository_path) { "/home/git/repositories" } + let(:repo_name) { 'dzaporozhets/gitlab-ci' } + let(:repo_path) { File.join(repository_path, repo_name) + ".git" } + let(:gitlab_post_receive) { GitlabPostReceive.new(repo_path, 'key-123', 'wow') } + + before do + GitlabConfig.any_instance.stub(repos_path: repository_path) + end + + describe :initialize do + it { gitlab_post_receive.repo_path.should == repo_path } + it { gitlab_post_receive.changes.should == 'wow' } + end +end diff --git a/spec/gitlab_projects_spec.rb b/spec/gitlab_projects_spec.rb index 3101b0b..0060fa9 100644 --- a/spec/gitlab_projects_spec.rb +++ b/spec/gitlab_projects_spec.rb @@ -295,7 +295,8 @@ describe GitlabProjects do FileUtils.mkdir_p(File.join(tmp_repos_path, 'forked-to-namespace')) gl_projects_fork.exec.should be_true File.exists?(dest_repo).should be_true - File.exists?(File.join(dest_repo, '/hooks/update')).should be_true + File.exists?(File.join(dest_repo, '/hooks/pre-receive')).should be_true + File.exists?(File.join(dest_repo, '/hooks/post-receive')).should be_true end it "should not fork if a project of the same name already exists" do diff --git a/spec/gitlab_shell_spec.rb b/spec/gitlab_shell_spec.rb index 6a00638..4741303 100644 --- a/spec/gitlab_shell_spec.rb +++ b/spec/gitlab_shell_spec.rb @@ -48,6 +48,14 @@ describe GitlabShell do its(:repo_name) { should == 'dmitriy.zaporozhets/gitlab-ci.git' } its(:git_cmd) { should == 'git-upload-pack' } end + + context 'with an invalid number of arguments' do + before { ssh_cmd 'foobar' } + + it "should raise an DisallowedCommandError" do + expect { subject.send :parse_cmd }.to raise_error(GitlabShell::DisallowedCommandError) + end + end end describe :exec do @@ -167,7 +175,7 @@ describe GitlabShell do before { File.stub(:absolute_path) { 'y' } } subject { -> { shell.send(:escape_path, 'z') } } - it { should raise_error(RuntimeError, "Wrong repository path") } + it { should raise_error(SystemExit, "Wrong repository path") } end def ssh_cmd(cmd) diff --git a/spec/gitlab_update_spec.rb b/spec/gitlab_update_spec.rb deleted file mode 100644 index 580d8c9..0000000 --- a/spec/gitlab_update_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'spec_helper' -require 'gitlab_update' - -describe GitlabUpdate do - let(:repository_path) { "/home/git/repositories" } - let(:repo_name) { 'dzaporozhets/gitlab-ci' } - let(:repo_path) { File.join(repository_path, repo_name) + ".git" } - let(:ref) { 'refs/heads/awesome-feature' } - let(:gitlab_update) { GitlabUpdate.new(repo_path, 'key-123', ref) } - - before do - ARGV[1] = 'd1e3ca3b25' - ARGV[2] = 'c2b3653b25' - GitlabConfig.any_instance.stub(repos_path: repository_path) - end - - describe :initialize do - it { gitlab_update.repo_name.should == repo_name } - it { gitlab_update.repo_path.should == repo_path } - it { gitlab_update.ref.should == ref } - it { gitlab_update.ref_name.should == 'awesome-feature' } - it { gitlab_update.oldrev.should == 'd1e3ca3b25' } - it { gitlab_update.newrev.should == 'c2b3653b25' } - end -end diff --git a/spec/names_helper_spec.rb b/spec/names_helper_spec.rb index db2a692..081dac9 100644 --- a/spec/names_helper_spec.rb +++ b/spec/names_helper_spec.rb @@ -1,5 +1,5 @@ require 'spec_helper' -require 'gitlab_update' +require 'names_helper' describe NamesHelper do include NamesHelper diff --git a/spec/vcr_cassettes/allowed-pull.yml b/spec/vcr_cassettes/allowed-pull.yml index af17288..29a0ac6 100644 --- a/spec/vcr_cassettes/allowed-pull.yml +++ b/spec/vcr_cassettes/allowed-pull.yml @@ -1,11 +1,11 @@ --- http_interactions: - request: - method: get - uri: https://dev.gitlab.org/api/v3/internal/allowed?action=git-receive-pack&forced_push=false&key_id=126&project=gitlab/gitlabhq&ref=master + method: post + uri: https://dev.gitlab.org/api/v3/internal/allowed body: encoding: US-ASCII - string: '' + string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&project=gitlab%2Fgitlabhq&key_id=126 headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -13,6 +13,8 @@ http_interactions: - "*/*" User-Agent: - Ruby + Content-Type: + - application/x-www-form-urlencoded response: status: code: 200 @@ -21,7 +23,7 @@ http_interactions: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:53 GMT + - Wed, 03 Sep 2014 11:27:36 GMT Content-Type: - application/json Content-Length: @@ -35,12 +37,12 @@ http_interactions: Cache-Control: - max-age=0, private, must-revalidate X-Request-Id: - - b049c014-05c4-4ec7-a591-1b0661257e33 + - 85bfa9b3-fddc-4810-a033-f1eabc04c66c X-Runtime: - - '0.055486' + - '0.089741' body: encoding: UTF-8 string: 'true' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:53 GMT + recorded_at: Wed, 03 Sep 2014 11:27:36 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/allowed-push.yml b/spec/vcr_cassettes/allowed-push.yml index fe50302..5d19db8 100644 --- a/spec/vcr_cassettes/allowed-push.yml +++ b/spec/vcr_cassettes/allowed-push.yml @@ -1,11 +1,11 @@ --- http_interactions: - request: - method: get - uri: https://dev.gitlab.org/api/v3/internal/allowed?action=git-upload-pack&forced_push=false&key_id=126&project=gitlab/gitlabhq&ref=master + method: post + uri: https://dev.gitlab.org/api/v3/internal/allowed body: encoding: US-ASCII - string: '' + string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&project=gitlab%2Fgitlabhq&key_id=126 headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -13,6 +13,8 @@ http_interactions: - "*/*" User-Agent: - Ruby + Content-Type: + - application/x-www-form-urlencoded response: status: code: 200 @@ -21,7 +23,7 @@ http_interactions: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:54 GMT + - Wed, 03 Sep 2014 11:27:37 GMT Content-Type: - application/json Content-Length: @@ -35,12 +37,12 @@ http_interactions: Cache-Control: - max-age=0, private, must-revalidate X-Request-Id: - - 7f92ebb7-4f92-4236-a35a-5f15c59b81f8 + - 115e7a72-b3a6-49e1-b531-980c71088c9d X-Runtime: - - '0.060724' + - '0.833195' body: encoding: UTF-8 string: 'true' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:54 GMT + recorded_at: Wed, 03 Sep 2014 11:27:37 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/check-ok.yml b/spec/vcr_cassettes/check-ok.yml index 5486697..641c6ce 100644 --- a/spec/vcr_cassettes/check-ok.yml +++ b/spec/vcr_cassettes/check-ok.yml @@ -21,7 +21,7 @@ http_interactions: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:52 GMT + - Wed, 03 Sep 2014 11:27:35 GMT Content-Type: - application/json Content-Length: @@ -31,16 +31,16 @@ http_interactions: Status: - 200 OK Etag: - - '"263db4ad138ffbada1f94332a1a2e1e8"' + - '"23ee74bf6981b57b9d0e0d8a91f3ec1b"' Cache-Control: - max-age=0, private, must-revalidate X-Request-Id: - - 17b6ff1c-e1a5-4443-b053-74cfced03184 + - c389e282-4d7b-4041-9aed-336e5b007424 X-Runtime: - - '0.004863' + - '0.958718' body: encoding: UTF-8 - string: '{"api_version":"v3","gitlab_version":"6.8.0.pre","gitlab_rev":"352bb97"}' + string: '{"api_version":"v3","gitlab_version":"7.3.0.pre","gitlab_rev":"e8f1331"}' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:52 GMT + recorded_at: Wed, 03 Sep 2014 11:27:35 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/denied-pull.yml b/spec/vcr_cassettes/denied-pull.yml index 7f81ded..505ce97 100644 --- a/spec/vcr_cassettes/denied-pull.yml +++ b/spec/vcr_cassettes/denied-pull.yml @@ -1,11 +1,11 @@ --- http_interactions: - request: - method: get - uri: https://dev.gitlab.org/api/v3/internal/allowed?action=git-receive-pack&forced_push=false&key_id=2&project=gitlab/gitlabhq&ref=master + method: post + uri: https://dev.gitlab.org/api/v3/internal/allowed body: encoding: US-ASCII - string: '' + string: action=git-receive-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&project=gitlab%2Fgitlabhq&key_id=2 headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -13,6 +13,8 @@ http_interactions: - "*/*" User-Agent: - Ruby + Content-Type: + - application/x-www-form-urlencoded response: status: code: 404 @@ -21,7 +23,7 @@ http_interactions: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:54 GMT + - Wed, 03 Sep 2014 11:27:38 GMT Content-Type: - application/json Content-Length: @@ -33,12 +35,12 @@ http_interactions: Cache-Control: - no-cache X-Request-Id: - - 7eb4f49d-66a6-4cca-84dd-9dfcd431210a + - f9c23a82-be65-41c8-958a-5f3e1b9aa58b X-Runtime: - - '0.010216' + - '0.028027' body: encoding: UTF-8 string: '{"message":"404 Not found"}' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:54 GMT + recorded_at: Wed, 03 Sep 2014 11:27:38 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/denied-push-with-user.yml b/spec/vcr_cassettes/denied-push-with-user.yml index c3e5b60..adca071 100644 --- a/spec/vcr_cassettes/denied-push-with-user.yml +++ b/spec/vcr_cassettes/denied-push-with-user.yml @@ -1,11 +1,11 @@ --- http_interactions: - request: - method: get - uri: https://dev.gitlab.org/api/v3/internal/allowed?action=git-upload-pack&forced_push=false&project=gitlab/gitlabhq&ref=master&user_id=1 + method: post + uri: https://dev.gitlab.org/api/v3/internal/allowed body: encoding: US-ASCII - string: '' + string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&project=gitlab%2Fgitlabhq&user_id=1 headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -13,32 +13,36 @@ http_interactions: - "*/*" User-Agent: - Ruby + Content-Type: + - application/x-www-form-urlencoded response: status: - code: 404 - message: Not Found + code: 200 + message: OK headers: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:54 GMT + - Wed, 03 Sep 2014 11:27:39 GMT Content-Type: - application/json Content-Length: - - '27' + - '4' Connection: - keep-alive Status: - - 404 Not Found + - 200 OK + Etag: + - '"b326b5062b2f0e69046810717534cb09"' Cache-Control: - - no-cache + - max-age=0, private, must-revalidate X-Request-Id: - - 2a2a3ef9-aaf1-4ffb-8b18-475d52ec5e09 + - 8bd01f76-6029-4921-ba97-12323a7d5750 X-Runtime: - - '0.013223' + - '0.019640' body: encoding: UTF-8 - string: '{"message":"404 Not found"}' + string: 'false' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:54 GMT + recorded_at: Wed, 03 Sep 2014 11:27:39 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/denied-push.yml b/spec/vcr_cassettes/denied-push.yml index ca1569d..2b0bfea 100644 --- a/spec/vcr_cassettes/denied-push.yml +++ b/spec/vcr_cassettes/denied-push.yml @@ -1,11 +1,11 @@ --- http_interactions: - request: - method: get - uri: https://dev.gitlab.org/api/v3/internal/allowed?action=git-upload-pack&forced_push=false&key_id=2&project=gitlab/gitlabhq&ref=master + method: post + uri: https://dev.gitlab.org/api/v3/internal/allowed body: encoding: US-ASCII - string: '' + string: action=git-upload-pack&changes=0000000000000000000000000000000000000000+92d0970eefd7acb6d548878925ce2208cfe2d2ec+refs%2Fheads%2Fbranch4&project=gitlab%2Fgitlabhq&key_id=2 headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -13,6 +13,8 @@ http_interactions: - "*/*" User-Agent: - Ruby + Content-Type: + - application/x-www-form-urlencoded response: status: code: 404 @@ -21,7 +23,7 @@ http_interactions: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:54 GMT + - Wed, 03 Sep 2014 11:27:38 GMT Content-Type: - application/json Content-Length: @@ -33,12 +35,12 @@ http_interactions: Cache-Control: - no-cache X-Request-Id: - - 2a2a3ef9-aaf1-4ffb-8b18-475d52ec5e09 + - 8b0210d2-4db5-4325-8120-740e22eaf7d5 X-Runtime: - - '0.013223' + - '0.015198' body: encoding: UTF-8 string: '{"message":"404 Not found"}' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:54 GMT + recorded_at: Wed, 03 Sep 2014 11:27:38 GMT recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/discover-ok.yml b/spec/vcr_cassettes/discover-ok.yml index 9609dec..982065a 100644 --- a/spec/vcr_cassettes/discover-ok.yml +++ b/spec/vcr_cassettes/discover-ok.yml @@ -21,7 +21,7 @@ http_interactions: Server: - nginx/1.1.19 Date: - - Mon, 14 Apr 2014 18:25:53 GMT + - Wed, 03 Sep 2014 11:27:35 GMT Content-Type: - application/json Content-Length: @@ -35,12 +35,12 @@ http_interactions: Cache-Control: - max-age=0, private, must-revalidate X-Request-Id: - - c3d44ccc-7599-4cc1-879e-281894f9cb39 + - ef4513ae-0424-4941-8be0-b5a3a7b4bf12 X-Runtime: - - '0.010799' + - '0.016934' body: encoding: UTF-8 string: '{"name":"Dmitriy Zaporozhets","username":"dzaporozhets"}' http_version: - recorded_at: Mon, 14 Apr 2014 18:25:53 GMT + recorded_at: Wed, 03 Sep 2014 11:27:35 GMT recorded_with: VCR 2.4.0 |