class Sandbox
Attributes
Public Class Methods
@param [String] name - the name of the sandbox @param [Array modules - the names of the modules that should be forked and branched @param [String] repos_dir
- the path to the repos directory @param [String] control_repo_path
- the url or path to the r10k control repo @option [String] fork_namespace - the namespace from which you fork modules to
the user passes in the r10k git url or path or we assume the path if the user does not pass in the git url we assume the repo already exist if the repo doesn't exist we clone the url
# File lib/release_manager/sandbox.rb, line 220 def self.create(name, options) box = Sandbox.new(name, options[:modules], options[:r10k_repo_path], options[:repos_path], options) box.check_requirements box.verify_api_token box.create(options[:r10k_repo_url]) end
# File lib/release_manager/sandbox.rb, line 18 def initialize(name, modules, control_repo_path, repos_dir = nil, options = {}) @name = name @repos_dir = repos_dir @module_names = modules @control_repo_path = control_repo_path @options = options end
Public Instance Methods
# File lib/release_manager/sandbox.rb, line 202 def check_requirements begin add_ssh_key rescue InvalidModuleNameException => e logger.error(e.message) exit 1 end end
checkout and/or create branch get modules fork module unless already exists clone fork of module create branch of fork set module fork set module branch set upstream to original namespace cleanup branches
# File lib/release_manager/sandbox.rb, line 140 def create(r10k_url) begin setup_repos_dir(repos_dir) @control_repo = setup_control_repo(r10k_url, options[:src_target]) # get modules we are interested in rescue InvalidBranchName => e logger.error(e.message) exit 1 end module_names.each do | mod_name | puts "## #{mod_name} ##".yellow begin mod = puppetfile.find_mod(mod_name) setup_module_repo(mod) rescue Rugged::CheckoutError => e logger.fatal(e.message) exit 1 rescue InvalidModuleNameException => e logger.error(e.message) value = nil loop do print "Do you want to create a new entry in the Puppetfile for the module named #{mod_name}?(y/n): ".yellow value = gets.downcase.chomp break if value =~ /y|n/ end next if value == 'n' mod = setup_new_module(mod_name) setup_module_repo(mod) end end @control_repo.checkout_branch(name) puppetfile.write_to_file logger.info("Committing Puppetfile changes to r10k-control branch: #{name}") committed = puppetfile.commit("Sandbox Creation for #{name} environment") # no need to push if we didn't commit anything if committed logger.info("Pushing new environment branch: #{name} to upstream") puppetfile.push('upstream', name, true, false) end logger.info("Sandbox created successfully") return self end
# File lib/release_manager/sandbox.rb, line 198 def puppetfile @puppetfile ||= control_repo.puppetfile end
@return [ControlRepo] - creates a new control repo object and clones the url unless already cloned @param url [String] - the url to clone and fork @param src_target [String] - the source to checkout from, defaults to 'upstream/dev'
# File lib/release_manager/sandbox.rb, line 52 def setup_control_repo(url, src_target = 'upstream/dev') src_target ||= 'upstream/dev' # clone r10k unless already cloned puts "## r10k-control ##".yellow fork = create_repo_fork(url) c = ControlRepo.create(control_repo_path, fork.ssh_url_to_repo) c.add_remote(fork.ssh_url_to_repo, 'myfork') c.fetch('myfork') c.fetch('origin') c.add_remote(url, 'upstream') raise InvalidBranchName.new("The source #{src_target} does not exist") unless c.branch_exist?(src_target) # if the user doesn't have the branch, we create from upstream # and then checkout from the fork, we defer pushing the branch to later after updating the puppetfile target = c.branch_exist?("upstream/#{name}") ? "upstream/#{name}" : src_target # if the user has previously created the branch but doesn't exist locally, no need to create c.create_branch(name, target) c.checkout_branch(name) c end
@return [PuppetModule] - creates a new puppet_module object and clones the url unless already cloned @param [ControlMod] mod - the module to clone and fork @param [Boolean] create_fork - defaults to true which creates a fork if the fork is already created, do nothing
# File lib/release_manager/sandbox.rb, line 76 def setup_module_repo(mod) raise InvalidModule.new(mod) unless mod.instance_of?(ControlMod) fork = create_repo_fork(mod.repo) m = PuppetModule.create(File.join(repos_dir, mod.name), fork.ssh_url_to_repo, name) m.fetch('origin') m.add_remote(fork.ssh_url_to_repo, 'myfork') # without the following, we risk accidently setting the upstream to the newly forked url # this occurs because r10k-control branch contains the forked url instead of the upstream url # we assume the metadata.source attribute contains the correct upstream url begin delay_source_change = false if m.source =~ /\Agit\@/ m.add_remote(m.source, 'upstream', true) else logger.warn("Module's source is not defined correctly for #{m.name} should be a git url, fixing...") # delay the changing of metadata source until we checkout the branch delay_source_change = true m.add_remote(mod.repo, 'upstream', true) end rescue ModNotFoundException => e logger.error("Is #{mod.name} a puppet module? Can't find the metadata source") end # if the user doesn't have the branch, we create from upstream # and then checkout from the fork # if the user has previously created the branch but doesn't exist locally, no need to create if m.remote_exists?('upstream') target = m.branch_exist?("myfork/#{name}") ? "myfork/#{name}" : 'upstream/master' else # don't create from upstream since the upstream remote does not exist # upstream does not exist because the url in the metadata source is not a git url target = 'master' end m.create_branch(name, target) m.push_branch('myfork', name) m.checkout_branch(name) if delay_source_change m.source = mod.repo m.commit_metadata_source end logger.info("Updating r10k-control Puppetfile to use fork: #{fork.ssh_url_to_repo} with branch: #{name}") puppetfile.write_source(mod.name, fork.ssh_url_to_repo, name ) m end
# File lib/release_manager/sandbox.rb, line 120 def setup_new_module(mod_name) repo_url = nil loop do print "Please enter the git url of the source repo : ".yellow repo_url = gets.chomp break if repo_url =~ /git\@/ puts "Repo Url must be a git url".red end puppetfile.add_module(mod_name, git: repo_url) end
@param [String] repos_path - the path to the repos directory where you want to clone modules @return [String] the repos_path Creates the repos path using mkdir_p unless the path already exists
# File lib/release_manager/sandbox.rb, line 29 def setup_repos_dir(repos_path) FileUtils.mkdir_p(repos_path) unless File.exists?(repos_path) repos_path end
TODO: extract this out to an adapter
# File lib/release_manager/sandbox.rb, line 185 def verify_api_token begin Gitlab.user rescue Exception => e raise InvalidToken.new(e.message) end end