Skip to content

Instantly share code, notes, and snippets.

@akomakom
Last active December 19, 2016 22:58
Show Gist options
  • Save akomakom/71a1b61b6d1d02fd9a14cf18066273a4 to your computer and use it in GitHub Desktop.
Save akomakom/71a1b61b6d1d02fd9a14cf18066273a4 to your computer and use it in GitHub Desktop.
Nexus 2.x backup helper that finds local repositories and produces an rsync include file or runs a command for each one. See comments and -h for usage.
#!/usr/bin/env ruby
#
# helper for backing up nexus 2 repositories that matter
# Run with -h for help
#
# Finds Nexus repositories that are not group, shadow or proxy
# and either produces an rsync file or runs an arbitrary command for each directory
#
# Examples (you may need to specify -n for all of these examples to specify your nexus installation)
# tar up all the local repos in one file:
# tar cvfz file.tar.gz $(find-nexus-local-repos.rb -c 'echo %s')
#
# tar up all the local repos as separate tar.gz files:
# find-nexus-local-repos.rb -c 'tar cvfz /path/to/tarball/$(basename %s).tar.gz %s'
#
# rsync all the local repos somewhere:
# find-nexus-local-repos.rb -r includes.list --rsync_num_dir_components 2
# rsync -a --delete -v --include '/storage/' --include-from includes.list --exclude '*' /path/to/nexus/storage /path/to/backup/to
require 'nokogiri'
require 'optparse'
$options = {}
$options[:nexus_path] = '/opt/sonatype-work/nexus' # Default
$options[:extra_repos] = []
$options[:rsync_num_dir_components] = 1 # number of path components to include in the filter rules (starting at end of path)
$options[:included_policies] = [] # types of repo policy, ie 'RELEASE,SNAPSHOT'
OptionParser.new do |opts|
opts.banner = "Usage: [options]"
opts.on("-v", "--verbose", "Run verbosely") do |v|
$options[:verbose] = TRUE
end
opts.on("-n dir", "--nexus-path dir", "Nexus root path without /storage or /conf, default #{$options[:nexus_path]}") do |v|
$options[:nexus_path] = v
end
opts.on("-r filename", "--rsync-file filename", "Create an rsync list file") do |v|
$options[:rsync_file] = v
end
opts.on("--rsync_num_dir_components number", "Keep N directories including the final path element") do |v|
$options[:rsync_num_dir_components] = v.to_i
end
opts.on("-c template", "--run-command-each template", "Run a shell command for each repository path, eg: 'echo %s'") do |v|
$options[:command_template] = v
end
opts.on("-E extra,repos,list", "--extra-repos-list extra,repos,list", "Add extra repositories to the results explicitly even if they are not local") do |v|
$options[:extra_repos] = v.split(',')
end
opts.on("-t repository_policies", "--repository-policies list,of,policies", "Only include repos with these policies, ie 'RELEASE,SNAPSHOT', defaults to all.") do |v|
$options[:included_policies] = v.split(',')
end
end.parse!
def vlog(s)
if $options[:verbose]
puts s
end
end
to_back_up_full_path = []
doc = File.open("#{$options[:nexus_path]}/conf/nexus.xml") { |f| Nokogiri::XML(f) }
repos = doc.xpath('/nexusConfiguration/repositories/repository')
repos.each {| repo |
# puts repo
id = repo.at_xpath('id').content
# do not include group and shadow repos, or anything with a remoteStorage (proxy)
if repo.xpath('remoteStorage').empty? and repo.at_xpath('providerRole').content == 'org.sonatype.nexus.proxy.repository.Repository'
policy = repo.at_xpath('externalConfiguration/repositoryPolicy').content
if $options[:included_policies].size == 0 or $options[:included_policies].include? policy
vlog "Repo #{id}: LOCAL"
to_back_up_full_path << "#{$options[:nexus_path]}/storage/#{id}"
else
vlog "Repo #{id}: LOCAL but policy #{policy} is excluded by policy list"
end
elsif $options[:extra_repos].include? id
vlog "Repo #{id}: manually including"
to_back_up_full_path << "#{$options[:nexus_path]}/storage/#{id}"
else
vlog "Repo #{id}: skipped"
end
}
to_back_up_full_path.sort!
vlog "Found #{to_back_up_full_path.size} local repos"
if $options[:rsync_file]
File.open($options[:rsync_file], 'w') { |file|
vlog "Writing to #{$options[:rsync_file]}"
to_back_up_full_path.each { |r|
mangled_path = r.split('/')[-$options[:rsync_num_dir_components]..-1].join('/')
file.write("+ /#{mangled_path}/***\n")
}
}
end
if $options[:command_template]
vlog "Command template: #{$options[:command_template]}"
to_back_up_full_path.each { |r|
cmd = sprintf($options[:command_template], r, r, r, r, r)
vlog "Running #{cmd}"
if !system cmd
vlog "Failed"
end
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment