1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
require "log4r"
require "vagrant"
module VagrantPlugins
module CFEngine
class Provisioner < Vagrant.plugin("2", :provisioner)
def provision
if @machine.config.vm.communicator == :winrm
raise Vagrant::Errors::ProvisionerWinRMUnsupported,
name: "cfengine"
end
@logger = Log4r::Logger.new("vagrant::plugins::cfengine")
@logger.info("Checking for CFEngine installation...")
handle_cfengine_installation
if @config.files_path
@machine.ui.info(I18n.t("vagrant.cfengine_installing_files_path"))
install_files(Pathname.new(@config.files_path).expand_path(@machine.env.root_path))
end
handle_cfengine_bootstrap if @config.mode == :bootstrap
if @config.mode == :single_run
# Just let people know
@machine.ui.info(I18n.t("vagrant.cfengine_single_run"))
end
if @config.run_file
@machine.ui.info(I18n.t("vagrant.cfengine_single_run_execute"))
path = Pathname.new(@config.run_file).expand_path(@machine.env.root_path)
machine.communicate.upload(path.to_s, @config.upload_path)
cfagent("-KI -f #{@config.upload_path}#{cfagent_classes_args}#{cfagent_extra_args}")
end
end
protected
# This runs cf-agent with the given arguments.
def cfagent(args, options=nil)
options ||= {}
command = "/var/cfengine/bin/cf-agent #{args}"
@machine.communicate.sudo(command, error_check: options[:error_check]) do |type, data|
if [:stderr, :stdout].include?(type)
# Output the data with the proper color based on the stream.
color = type == :stdout ? :green : :red
@machine.ui.info(
data,
color: color, new_line: false, prefix: false)
end
end
end
# Returns the arguments for the classes configuration if they are
# set.
#
# @return [String]
def cfagent_classes_args
return "" if !@config.classes
args = @config.classes.map { |c| "-D#{c}" }.join(" ")
return " #{args}"
end
# Extra arguments for calles to cf-agent.
#
# @return [String]
def cfagent_extra_args
return "" if !@config.extra_agent_args
return " #{@config.extra_agent_args}"
end
# This handles checking if the CFEngine installation needs to
# be bootstrapped, and bootstraps if it does.
def handle_cfengine_bootstrap
@logger.info("Bootstrapping CFEngine...")
if !@machine.guest.capability(:cfengine_needs_bootstrap, @config)
@machine.ui.info(I18n.t("vagrant.cfengine_no_bootstrap"))
return
end
# Needs bootstrap, let's determine the parameters
policy_server_address = @config.policy_server_address
if !policy_server_address
policy_server_address = @machine.guest.capability(:read_ip_address)
raise Vagrant::Errors::CFEngineCantAutodetectIP if !policy_server_address
@machine.ui.info(I18n.t("vagrant.cfengine_detected_ip", address: policy_server_address))
end
@machine.ui.info(I18n.t("vagrant.cfengine_bootstrapping",
policy_server: policy_server_address))
result = cfagent("--bootstrap #{policy_server_address}", error_check: false)
raise Vagrant::Errors::CFEngineBootstrapFailed if result != 0
# Policy hubs need to do additional things before they're ready
# to accept agents. Force that run now...
if @config.am_policy_hub
@machine.ui.info(I18n.t("vagrant.cfengine_bootstrapping_policy_hub"))
cfagent("-KI -f /var/cfengine/masterfiles/failsafe.cf#{cfagent_classes_args}")
cfagent("-KI #{cfagent_classes_args}#{cfagent_extra_args}")
end
end
# This handles verifying the CFEngine installation, installing it
# if it was requested, and so on. This method will raise exceptions
# if things are wrong.
def handle_cfengine_installation
if !@machine.guest.capability?(:cfengine_installed)
@machine.ui.warn(I18n.t("vagrant.cfengine_cant_detect"))
return
end
installed = @machine.guest.capability(:cfengine_installed)
if !installed || @config.install == :force
raise Vagrant::Errors::CFEngineNotInstalled if !@config.install
@machine.ui.info(I18n.t("vagrant.cfengine_installing"))
@machine.guest.capability(:cfengine_install, @config)
if !@machine.guest.capability(:cfengine_installed)
raise Vagrant::Errors::CFEngineInstallFailed
end
end
end
# This installs a set of files into the CFEngine folder within
# the machine.
#
# @param [Pathname] local_path
def install_files(local_path)
@logger.debug("Copying local files to CFEngine: #{local_path}")
@machine.communicate.sudo("rm -rf /tmp/cfengine-files")
@machine.communicate.upload(local_path.to_s, "/tmp/cfengine-files")
@machine.communicate.sudo("cp -R /tmp/cfengine-files/* /var/cfengine")
end
end
end
end
|