require 'vagrant' require 'pe_build/archive' require 'pe_build/util/config' require 'log4r' require 'fileutils' module PEBuild module Provisioner class PEBootstrap < Vagrant.plugin('2', :provisioner) require 'pe_build/provisioner/pe_bootstrap/answers_file' require 'pe_build/provisioner/pe_bootstrap/post_install' # @!attribute [r] work_dir # @return [String] The path to the machine pe_build working directory attr_reader :work_dir # @!attribute [r] answer_dir # @return [String] The path to the default answer file template dir attr_reader :answer_dir # @!attribute [r] answer_file # @return [String] The path to the answer file for this machine. attr_reader :answer_file def initialize(machine, config) super @logger = Log4r::Logger.new('vagrant::provisioners::pe_bootstrap') @work_dir = File.join(@machine.env.root_path.join, PEBuild::WORK_DIR) @answer_dir = File.join(work_dir, 'answers') end # Instantiate all working directory content and stage the PE installer. # # @param root_config [Object] ??? # @return [void] def configure(root_config) late_config_merge(root_config) unless File.directory? work_dir FileUtils.mkdir_p work_dir end end def provision prepare_answers_file load_archive fetch_installer [:base, @config.role].each { |rolename| process_step rolename, :pre } @machine.guest.capability('run_install', @config, @archive) run_postinstall_tasks [:base, @config.role].each { |rolename| process_step rolename, :post } end private def late_config_merge(root_config) provision = @config global = root_config.pe_build # We don't necessarily know if the configs have been merged. If a config # is being used for default values and was never directly touched then it # may have bad values, so we re-finalize everything. This may not be # generally safe but inside of this plugin it should be ok. provision.finalize! global.finalize! merged = PEBuild::Util::Config.local_merge(provision, global) @config = merged end def prepare_answers_file af = AnswersFile.new(@machine, @config, @work_dir) af.generate end def load_archive if @config.suffix == :detect filename = @machine.guest.capability('detect_installer', @config.version) else filename = @config.filename end @archive = PEBuild::Archive.new(filename, @machine.env) @archive.version = @config.version end # @todo panic if @config.download_root is undefined def fetch_installer uri = @config.download_root @archive.fetch(@config.download_root) @archive.unpack_to(@work_dir) end require 'pe_build/on_machine' include PEBuild::OnMachine def process_step(role, stepname) if role != :base && config.step[stepname] if File.file? config.step[stepname] script_list = [*config.step[stepname]] else script_list = [] @machine.ui.warn "Cannot find defined step for #{role}/#{stepname.to_s} at \'#{config.step[stepname]}\'" end else # We do not have a user defined step for this role or we're processing the :base step script_dir = File.join(PEBuild.source_root, 'bootstrap', role.to_s, stepname.to_s) script_list = Dir.glob("#{script_dir}/*") end if script_list.empty? @logger.info "No steps for #{role}/#{stepname}" end script_list.each do |template_path| # A message to show which step's action is running @machine.ui.info "Running action for #{role}/#{stepname}" template = File.read(template_path) contents = ERB.new(template).result(binding) on_machine(@machine, contents) end end def run_postinstall_tasks postinstall = PostInstall.new(@machine, @config, @work_dir) postinstall.run end end end end