Skip to content
Snippets Groups Projects
Commit 76e7a95f8f5b authored by DJ Mountney's avatar DJ Mountney
Browse files

Merge branch 'praefect-delete-repo' into 'master'

'gitlab-ctl praefect delete-repo' command.

Closes gitaly#3776

See merge request gitlab-org/omnibus-gitlab!5614
2 merge requests!55Intermediate build after shift of stable series,!54GitLab 14.4
require 'optparse'
module Praefect
EXEC_PATH = '/opt/gitlab/embedded/bin/praefect'.freeze
DIR_PATH = '/var/opt/gitlab/praefect'.freeze
USAGE ||= <<~EOS.freeze
Usage:
gitlab-ctl praefect command [options]
COMMANDS:
remove-repository Remove repository from Gitaly cluster
EOS
def self.parse_options!(args)
loop do
break if args.shift == 'praefect'
end
global = OptionParser.new do |opts|
opts.on('-h', '--help', 'Usage help') do
Kernel.puts USAGE
Kernel.exit 0
end
end
options = {}
commands = {
'remove-repository' => OptionParser.new do |opts|
opts.banner = "Usage: gitlab-ctl praefect remove-repository [options]"
opts.on("-h", "--help", "Prints this help") do
Kernel.puts opts
Kernel.exit 0
end
opts.on('--virtual-storage-name NAME', 'Name of the virtual storage where the repository resides (mandatory)') do |virtual_storage_name|
options[:virtual_storage_name] = virtual_storage_name
end
opts.on('--repository-relative-path PATH', 'Relative path to the repository on the disk (mandatory)') do |repository_relative_path|
options[:repository_relative_path] = repository_relative_path
end
opts.on('--dir DIR', 'Directory in which Praefect is installed') do |dir|
options[:dir] = dir
end
end
}
global.order!(args)
command = args.shift
raise OptionParser::ParseError, "Praefect command is not specified." \
if command.nil? || command.empty?
raise OptionParser::ParseError, "Unknown Praefect command: #{command}" \
unless commands.key?(command)
commands[command].parse!(args)
raise OptionParser::ParseError, "Option --virtual-storage-name must be specified" \
unless options.key?(:virtual_storage_name)
raise OptionParser::ParseError, "Option --repository-relative-path must be specified" \
unless options.key?(:repository_relative_path)
options[:command] = command
options
end
def self.execute(options)
config_file_path = File.join(options.fetch(:dir, DIR_PATH), 'config.toml')
[EXEC_PATH, config_file_path].each do |path|
next if File.exist?(path)
Kernel.abort "Could not find '#{path}' file. Is your package installed correctly?"
end
command = [EXEC_PATH, "-config", config_file_path, options[:command]]
command += ["-virtual-storage", options[:virtual_storage_name]]
command += ["-repository", options[:repository_relative_path]]
status = Kernel.system(*command)
Kernel.exit!(1) unless status
end
end
require 'optparse'
require "#{base_path}/embedded/service/omnibus-ctl/lib/gitlab_ctl"
require "#{base_path}/embedded/service/omnibus-ctl/lib/praefect"
add_command_under_category('praefect', 'gitaly', 'Interact with Gitaly cluster', 2) do
begin
options = Praefect.parse_options!(ARGV)
rescue OptionParser::ParseError => e
warn "#{e}\n\n#{Praefect::USAGE}"
exit 128
end
puts "Running #{options[:command]}"
Praefect.execute(options)
puts "Done."
exit 0
end
require 'spec_helper'
require 'optparse'
require_relative('../../../files/gitlab-ctl-commands/lib/praefect')
RSpec.describe Praefect do
describe '.parse_options!' do
before do
allow(Kernel).to receive(:exit) { |code| raise "Kernel.exit(#{code})" }
end
it 'throws an error when command is not specified' do
expect { Praefect.parse_options!(%w(praefect)) }.to raise_error(OptionParser::ParseError, /Praefect command is not specified/)
end
it 'throws an error when unknown command is specified' do
expect { Praefect.parse_options!(%w(praefect unknown-command)) }.to raise_error(OptionParser::ParseError, /Unknown Praefect command: unknown-command/)
end
it 'throws an error when unknown option is specified' do
expect { Praefect.parse_options!(%w(praefect remove-repository --unknown)) }.to raise_error(OptionParser::InvalidOption, /unknown/)
end
it 'throws an error when an argument for --virtual-storage-name is not specified' do
expect { Praefect.parse_options!(%w(praefect remove-repository --virtual-storage-name)) }.to raise_error(OptionParser::MissingArgument, /virtual-storage-name/)
end
it 'throws an error when --virtual-storage-name is not specified' do
expect { Praefect.parse_options!(%w(praefect remove-repository)) }.to raise_error(OptionParser::ParseError, /Option --virtual-storage-name must be specified/)
end
it 'throws an error when an argument for --repository-relative-path is not specified' do
expect { Praefect.parse_options!(%w(praefect remove-repository --repository-relative-path)) }.to raise_error(OptionParser::MissingArgument, /repository-relative-path/)
end
it 'throws an error when --repository-relative-path is not specified' do
expect { Praefect.parse_options!(%w(praefect remove-repository --virtual-storage-name name)) }.to raise_error(OptionParser::ParseError, /Option --repository-relative-path must be specified/)
end
it 'successfully parses correct params' do
expected_options = { command: 'remove-repository', virtual_storage_name: 'name', repository_relative_path: 'path' }
expect(Praefect.parse_options!(%w(praefect remove-repository --virtual-storage-name name --repository-relative-path path))).to eq(expected_options)
end
context 'when help option is passed' do
it 'shows help message and exit for global help option' do
expect(Kernel).to receive(:puts) do |msg|
expect(msg.to_s).to match(/gitlab-ctl praefect command/)
end
expect { Praefect.parse_options!(%w(praefect -h)) }.to raise_error('Kernel.exit(0)')
end
['remove-repository'].each do |cmd|
it "shows help message and exit for #{cmd} help option" do
expect(Kernel).to receive(:puts) do |msg|
expect(msg.to_s).to match(/gitlab-ctl praefect remove-repository/)
end
expect { Praefect.parse_options!(%W(praefect #{cmd} -h)) }.to raise_error('Kernel.exit(0)')
end
end
end
end
describe '#execute' do
context 'when package is not installed correctly' do
it 'aborts the execution if a path does not exit' do
allow(File).to receive(:exists?).twice.and_return(false)
expect(Kernel).to receive(:abort).and_raise('aborted')
expect { Praefect.execute({}) }.to raise_error('aborted')
end
end
it 'executes the command' do
allow(File).to receive(:exist?).and_return(true)
expect(Kernel).not_to receive(:abort)
expect(Kernel).to receive(:system).with(
Praefect::EXEC_PATH, '-config', 'dir/config.toml', 'cmd',
'-virtual-storage', 'storage-name', '-repository', 'repository-path'
).and_return('result!')
expect(Kernel).not_to receive(:exit!)
options = {
virtual_storage_name: 'storage-name',
repository_relative_path: 'repository-path',
command: 'cmd',
dir: 'dir'
}
Praefect.execute(options)
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment