From 4fd8e44ba12d126b0553b90c099d1b63fa163d00 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 16 Jul 2015 10:10:46 +0200 Subject: Remove keys from authorized_keys in-place This will speed up the rm-key operation. The downside is that authorized_keys will not shrink when you remove a key. If this ever becomes a problem it can be fixed by running 'rake gitlab:shell:setup'. --- CHANGELOG | 2 ++ lib/gitlab_keys.rb | 15 +++++++-------- spec/gitlab_keys_spec.rb | 8 +++++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3205e8b..90bd21d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +v2.6.4 + - Remove keys from authorized_keys in-place v2.6.3 - Prevent keys with a very specific comment from accidentally being deleted. diff --git a/lib/gitlab_keys.rb b/lib/gitlab_keys.rb index 10f84bd..a8baf45 100644 --- a/lib/gitlab_keys.rb +++ b/lib/gitlab_keys.rb @@ -1,4 +1,3 @@ -require 'tempfile' require 'timeout' require_relative 'gitlab_config' @@ -82,14 +81,14 @@ class GitlabKeys def rm_key lock do $logger.info "Removing key #{@key_id}" - Tempfile.open('authorized_keys') do |temp| - open(auth_file, 'r+') do |current| - current.each do |line| - temp.puts(line) unless line.start_with?("command=\"#{key_command(@key_id)}\"") - end + open(auth_file, 'r+') do |f| + while line = f.gets do + next unless line.start_with?("command=\"#{key_command(@key_id)}\"") + f.seek(-line.length, IO::SEEK_CUR) + # Overwrite the line with #'s. Because the 'line' variable contains + # a terminating '\n', we write line.length - 1 '#' characters. + f.write('#' * (line.length - 1)) end - temp.close - FileUtils.cp(temp.path, auth_file) end end true diff --git a/spec/gitlab_keys_spec.rb b/spec/gitlab_keys_spec.rb index bcce628..ed2fd58 100644 --- a/spec/gitlab_keys_spec.rb +++ b/spec/gitlab_keys_spec.rb @@ -109,17 +109,19 @@ describe GitlabKeys do it "removes the right line" do create_authorized_keys_fixture other_line = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-742\",options ssh-rsa AAAAB3NzaDAxx2E" + delete_line = "command=\"#{ROOT_PATH}/bin/gitlab-shell key-741\",options ssh-rsa AAAAB3NzaDAxx2E" open(tmp_authorized_keys_path, 'a') do |auth_file| - auth_file.puts "command=\"#{ROOT_PATH}/bin/gitlab-shell key-741\",options ssh-rsa AAAAB3NzaDAxx2E" + auth_file.puts delete_line auth_file.puts other_line end gitlab_keys.send :rm_key - File.read(tmp_authorized_keys_path).should == "existing content\n#{other_line}\n" + erased_line = delete_line.gsub(/./, '#') + File.read(tmp_authorized_keys_path).should == "existing content\n#{erased_line}\n#{other_line}\n" end context "without file writing" do before do - Tempfile.stub(:open) + gitlab_keys.stub(:open) gitlab_keys.stub(:lock).and_yield end -- cgit v1.2.1