Skip to content

Commit

Permalink
Refactor RMT::Mirror
Browse files Browse the repository at this point in the history
  • Loading branch information
ikapelyukhin committed Jun 11, 2018
1 parent dc62391 commit 21d0ab4
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 112 deletions.
10 changes: 0 additions & 10 deletions lib/rmt/cli/base.rb
Expand Up @@ -94,14 +94,4 @@ def needs_path(path)
File.directory?(path) ? yield : warn("#{path} is not a directory.")
end

def mirror!(repo, repository_url: nil, to: RMT::DEFAULT_MIRROR_DIR, to_offline: false, logger:)
repository_url ||= repo.external_url

logger.info "Mirroring repository #{repo.name} to #{to}"
RMT::Mirror.from_url(repo.external_url, repo.auth_token, repository_url: repository_url, base_dir: to, to_offline: to_offline, logger: logger).mirror
repo.refresh_timestamp!
rescue RMT::Mirror::Exception => e
logger.warn e.to_s
end

end
11 changes: 9 additions & 2 deletions lib/rmt/cli/export.rb
Expand Up @@ -28,16 +28,23 @@ def settings(path)
def repos(path)
needs_path(path) do
logger = RMT::Logger.new(STDOUT)
mirror = RMT::Mirror.new(mirroring_base_dir: path, logger: logger, disable_hardlinks: true)

repos_file = File.join(path, 'repos.json')
unless File.exist?(repos_file)
warn "#{repos_file} does not exist."
warn "#{repos_file} does not exist." # FIXME: raise exception
return
end

repos = JSON.parse(File.read(repos_file))
repos.each do |repo|
puts "Mirroring repository at #{repo['url']}"
begin
RMT::Mirror.from_url(repo['url'], repo['auth_token'], base_dir: path, to_offline: true, logger: logger).mirror
mirror.mirror(
repository_url: repo['url'],
local_path: Repository.make_local_path(repo['url']),
auth_token: repo['auth_token']
)
rescue RMT::Mirror::Exception => e
warn e.to_s
end
Expand Down
20 changes: 18 additions & 2 deletions lib/rmt/cli/import.rb
Expand Up @@ -14,11 +14,12 @@ def repos(path)
RMT::Lockfile.lock do
needs_path(path) do
logger = RMT::Logger.new(STDOUT)
mirror = RMT::Mirror.new(logger: logger, disable_hardlinks: true)

repos_file = File.join(path, 'repos.json')
unless File.exist?(repos_file)
warn "#{repos_file} does not exist."
return
return # FIXME: needs to raise exception
end

repos = JSON.parse(File.read(repos_file))
Expand All @@ -30,7 +31,22 @@ def repos(path)
end

repo.external_url = 'file://' + path + Repository.make_local_path(repo_json['url'])
mirror!(repo, repository_url: repo_json['url'], to_offline: true, logger: logger)
# mirror!(repo, repository_url: repo_json['url'], to_offline: true, logger: logger)

begin
local_path = Repository.make_local_path(repo_json['url'])
logger.info "Mirroring repository #{repo.name} to #{local_path}"

mirror.mirror(
repository_url: repo.external_url,
local_path: local_path,
auth_token: repo.auth_token
)

repo.refresh_timestamp!
rescue RMT::Mirror::Exception => e
logger.warn e.to_s
end
end
end
end
Expand Down
23 changes: 21 additions & 2 deletions lib/rmt/cli/main.rb
Expand Up @@ -21,12 +21,31 @@ def sync
def mirror
RMT::Lockfile.lock do
logger = RMT::Logger.new(STDOUT)
mirror = RMT::Mirror.new(logger: logger)

repos = Repository.where(mirroring_enabled: true)
if repos.empty?
warn 'There are no repositories marked for mirroring.'
return
return # FIXME: needs to raise exception
end

repos.each do |repo|
# mirror!(repo, logger: logger)
begin
local_path = Repository.make_local_path(repo.external_url)
logger.info "Mirroring repository #{repo.name} to #{local_path}"

mirror.mirror(
repository_url: repo.external_url,
local_path: Repository.make_local_path(repo.external_url),
auth_token: repo.auth_token
)

repo.refresh_timestamp!
rescue RMT::Mirror::Exception => e
logger.warn e.to_s
end
end
repos.each { |repo| mirror!(repo, logger: logger) }
end
end

Expand Down
33 changes: 9 additions & 24 deletions lib/rmt/mirror.rb
@@ -1,36 +1,35 @@
require 'rmt/downloader'
require 'rmt/rpm'
require 'time'

# rubocop:disable Metrics/ClassLength
class RMT::Mirror

class RMT::Mirror::Exception < RuntimeError
end

def initialize(mirroring_base_dir:, repository_url:, local_path:, logger:, mirror_src: false, auth_token: nil, to_offline: false)
@repository_dir = File.join(mirroring_base_dir, local_path)
@repository_url = repository_url
def initialize(mirroring_base_dir: RMT::DEFAULT_MIRROR_DIR, logger:, mirror_src: false, disable_hardlinks: false)
@mirroring_base_dir = mirroring_base_dir
@mirror_src = mirror_src
@logger = logger
@primary_files = []
@deltainfo_files = []
@auth_token = auth_token
@force_dedup_by_copy = to_offline
@force_dedup_by_copy = disable_hardlinks

@downloader = RMT::Downloader.new(
repository_url: @repository_url,
destination_dir: @repository_dir,
logger: @logger,
save_for_dedup: !to_offline # don't save files for deduplication when in offline mode
save_for_dedup: !disable_hardlinks # don't save files for deduplication when in offline mode
)
end

def mirror
def mirror(repository_url:, local_path:, auth_token: nil)
@repository_dir = File.join(@mirroring_base_dir, local_path)
@repository_url = repository_url

create_directories
mirror_license
# downloading license doesn't require an auth token
@downloader.auth_token = @auth_token
@downloader.auth_token = auth_token
mirror_metadata
mirror_data

Expand All @@ -40,20 +39,6 @@ def mirror
remove_tmp_directories
end

def self.from_url(uri, auth_token, repository_url: nil, base_dir: nil, to_offline: false, logger:)
repository_url ||= uri

new(
mirroring_base_dir: base_dir || RMT::DEFAULT_MIRROR_DIR,
repository_url: uri,
auth_token: auth_token,
local_path: Repository.make_local_path(repository_url),
mirror_src: Settings.try(:mirroring).try(:mirror_src),
logger: logger,
to_offline: to_offline
)
end

protected

def create_directories
Expand Down
39 changes: 28 additions & 11 deletions spec/lib/rmt/cli/export_spec.rb
Expand Up @@ -58,22 +58,29 @@

context 'with valid repo ids' do
before do
expect(RMT::Mirror).to receive(:from_url).with(
'http://foo.bar/repo1', 'foobar', base_dir: path, to_offline: true,
logger: instance_of(RMT::Logger)
).once.and_return(mirror_double)

expect(RMT::Mirror).to receive(:from_url).with(
'http://foo.bar/repo2', '', base_dir: path, to_offline: true,
logger: instance_of(RMT::Logger)
expect(RMT::Mirror).to receive(:new).with(
mirroring_base_dir: path,
logger: instance_of(RMT::Logger),
disable_hardlinks: true
).once.and_return(mirror_double)
end

it 'reads repo ids from file at path and mirrors these repos' do
FileUtils.mkdir_p path
File.write("#{path}/repos.json", repo_settings.to_json)

expect(mirror_double).to receive(:mirror).twice
expect(mirror_double).to receive(:mirror).with(
repository_url: 'http://foo.bar/repo1',
auth_token: 'foobar',
local_path: '/repo1'
)

expect(mirror_double).to receive(:mirror).with(
repository_url: 'http://foo.bar/repo2',
auth_token: '',
local_path: '/repo2'
)

expect { command }.to output(/Mirroring repository/).to_stdout
end

Expand All @@ -82,8 +89,18 @@
FileUtils.mkdir_p path
File.write("#{path}/repos.json", repo_settings.to_json)

expect(mirror_double).to receive(:mirror)
expect(mirror_double).to receive(:mirror).and_raise(RMT::Mirror::Exception, 'black mirror')
expect(mirror_double).to receive(:mirror).with(
repository_url: 'http://foo.bar/repo1',
auth_token: 'foobar',
local_path: '/repo1'
).and_raise(RMT::Mirror::Exception, 'black mirror')

expect(mirror_double).to receive(:mirror).with(
repository_url: 'http://foo.bar/repo2',
auth_token: '',
local_path: '/repo2'
)

expect { command }.to output(/black mirror/).to_stderr.and output(/Mirroring repository/).to_stdout
end
end
Expand Down
50 changes: 30 additions & 20 deletions spec/lib/rmt/cli/import_spec.rb
Expand Up @@ -36,7 +36,7 @@
let(:repo2) { create :repository, mirroring_enabled: true }
let(:repo1_local_path) { repo_url_to_local_path(path, repo1.external_url) }
let(:repo2_local_path) { repo_url_to_local_path(path, repo2.external_url) }
let(:mirror_double) { instance_double 'RMT::Mirror' }
let(:mirror_double) { instance_double RMT::Mirror }
let(:repo_settings) do
[
{ url: repo1.external_url, auth_token: repo1.auth_token.to_s },
Expand Down Expand Up @@ -70,16 +70,22 @@

context 'without exception' do
before do
expect(mirror_double).to receive(:mirror).twice
expect(RMT::Mirror).to receive(:from_url).with(
repo1_local_path, repo1.auth_token, base_dir: RMT::DEFAULT_MIRROR_DIR,
repository_url: repo1.external_url, to_offline: true, logger: instance_of(RMT::Logger)
expect(RMT::Mirror).to receive(:new).with(
logger: instance_of(RMT::Logger),
disable_hardlinks: true
).and_return(mirror_double)

expect(RMT::Mirror).to receive(:from_url).with(
repo2_local_path, repo2.auth_token, base_dir: RMT::DEFAULT_MIRROR_DIR,
repository_url: repo2.external_url, to_offline: true, logger: instance_of(RMT::Logger)
).and_return(mirror_double)
expect(mirror_double).to receive(:mirror).with(
repository_url: repo1_local_path,
local_path: Repository.make_local_path(repo1.external_url),
auth_token: repo1.auth_token
)

expect(mirror_double).to receive(:mirror).with(
repository_url: repo2_local_path,
local_path: Repository.make_local_path(repo2.external_url),
auth_token: repo2.auth_token
)
end

it 'mirrors repo1 and repo2' do
Expand All @@ -93,7 +99,6 @@
end

context 'with exceptions during mirroring' do
let(:mirror_error_double) { instance_double 'RMT::Mirror' }
let(:repo_settings) do
[
{ url: repo1.external_url, auth_token: repo1.auth_token.to_s },
Expand All @@ -102,17 +107,22 @@
end

before do
expect(mirror_error_double).to receive(:mirror).once.and_raise(RMT::Mirror::Exception, 'black mirror')
expect(mirror_double).to receive(:mirror).once
expect(RMT::Mirror).to receive(:from_url).with(
repo1_local_path, repo1.auth_token, base_dir: RMT::DEFAULT_MIRROR_DIR,
repository_url: repo1.external_url, to_offline: true, logger: instance_of(RMT::Logger)
).and_return(mirror_error_double)

expect(RMT::Mirror).to receive(:from_url).with(
repo2_local_path, repo2.auth_token, base_dir: RMT::DEFAULT_MIRROR_DIR,
repository_url: repo2.external_url, to_offline: true, logger: instance_of(RMT::Logger)
expect(RMT::Mirror).to receive(:new).with(
logger: instance_of(RMT::Logger),
disable_hardlinks: true
).and_return(mirror_double)

expect(mirror_double).to receive(:mirror).with(
repository_url: repo1_local_path,
local_path: Repository.make_local_path(repo1.external_url),
auth_token: repo1.auth_token
).and_raise(RMT::Mirror::Exception, 'black mirror')

expect(mirror_double).to receive(:mirror).with(
repository_url: repo2_local_path,
local_path: Repository.make_local_path(repo2.external_url),
auth_token: repo2.auth_token
)
end

it 'mirrors repo2 when repo1 raised an exception' do
Expand Down

0 comments on commit 21d0ab4

Please sign in to comment.