184 lines
5.2 KiB
Ruby
184 lines
5.2 KiB
Ruby
require "log4r"
|
|
require "singleton"
|
|
|
|
module Vagrant
|
|
module Util
|
|
class CheckpointClient
|
|
|
|
include Singleton
|
|
|
|
# Maximum number of seconds to wait for check to complete
|
|
CHECKPOINT_TIMEOUT = 10
|
|
|
|
# @return [Log4r::Logger]
|
|
attr_reader :logger
|
|
|
|
# @return [Boolean]
|
|
attr_reader :enabled
|
|
|
|
# @return [Hash]
|
|
attr_reader :files
|
|
|
|
# @return [Vagrant::Environment]
|
|
attr_reader :env
|
|
|
|
def initialize
|
|
@logger = Log4r::Logger.new("vagrant::checkpoint_client")
|
|
@enabled = false
|
|
end
|
|
|
|
# Setup will attempt to load the checkpoint library and define
|
|
# required paths
|
|
#
|
|
# @param [Vagrant::Environment] env
|
|
# @return [self]
|
|
def setup(env)
|
|
begin
|
|
require "checkpoint"
|
|
@enabled = true
|
|
rescue LoadError
|
|
@logger.warn("checkpoint library not found. disabling.")
|
|
end
|
|
if ENV["VAGRANT_CHECKPOINT_DISABLE"]
|
|
@logger.debug("checkpoint disabled via explicit user request")
|
|
@enabled = false
|
|
end
|
|
@files = {
|
|
signature: env.data_dir.join("checkpoint_signature"),
|
|
cache: env.data_dir.join("checkpoint_cache")
|
|
}
|
|
@checkpoint_thread = nil
|
|
@env = env
|
|
self
|
|
end
|
|
|
|
# Check has completed
|
|
def complete?
|
|
!@checkpoint_thread.nil? && !@checkpoint_thread.alive?
|
|
end
|
|
|
|
# Result of check
|
|
#
|
|
# @return [Hash, nil]
|
|
def result
|
|
if !enabled || @checkpoint_thread.nil?
|
|
nil
|
|
elsif !defined?(@result)
|
|
@checkpoint_thread.join(CHECKPOINT_TIMEOUT)
|
|
@result = @checkpoint_thread[:result]
|
|
else
|
|
@result
|
|
end
|
|
end
|
|
|
|
# Run check
|
|
#
|
|
# @return [self]
|
|
def check
|
|
if enabled && @checkpoint_thread.nil?
|
|
logger.debug("starting plugin check")
|
|
@checkpoint_thread = Thread.new do
|
|
Thread.current.abort_on_exception = false
|
|
if Thread.current.respond_to?(:report_on_exception=)
|
|
Thread.current.report_on_exception = false
|
|
end
|
|
begin
|
|
Thread.current[:result] = Checkpoint.check(
|
|
product: "vagrant",
|
|
version: VERSION,
|
|
signature_file: files[:signature],
|
|
cache_file: files[:cache]
|
|
)
|
|
if !Thread.current[:result].is_a?(Hash)
|
|
Thread.current[:result] = nil
|
|
end
|
|
logger.debug("plugin check complete")
|
|
rescue => e
|
|
logger.debug("plugin check failure - #{e}")
|
|
end
|
|
end
|
|
end
|
|
self
|
|
end
|
|
|
|
# Display any alerts or version update information
|
|
#
|
|
# @return [boolean] true if displayed, false if not
|
|
def display
|
|
if !defined?(@displayed)
|
|
if !complete?
|
|
@logger.debug("waiting for checkpoint to complete...")
|
|
end
|
|
# Don't display if information is cached
|
|
if result && !result["cached"]
|
|
version_check
|
|
alerts_check
|
|
else
|
|
@logger.debug("no information received from checkpoint")
|
|
end
|
|
@displayed = true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def alerts_check
|
|
if result["alerts"] && !result["alerts"].empty?
|
|
result["alerts"].group_by{|a| a["level"]}.each_pair do |_, alerts|
|
|
alerts.each do |alert|
|
|
date = nil
|
|
begin
|
|
date = Time.at(alert["date"])
|
|
rescue
|
|
date = Time.now
|
|
end
|
|
output = I18n.t("vagrant.alert",
|
|
message: alert["message"],
|
|
date: date,
|
|
url: alert["url"]
|
|
)
|
|
case alert["level"]
|
|
when "info"
|
|
alert_ui = Vagrant::UI::Prefixed.new(env.ui, "vagrant")
|
|
alert_ui.info(output)
|
|
when "warn"
|
|
alert_ui = Vagrant::UI::Prefixed.new(env.ui, "vagrant-warning")
|
|
alert_ui.warn(output)
|
|
when "critical"
|
|
alert_ui = Vagrant::UI::Prefixed.new(env.ui, "vagrant-alert")
|
|
alert_ui.error(output)
|
|
end
|
|
end
|
|
env.ui.info("")
|
|
end
|
|
else
|
|
@logger.debug("no alert notifications to display")
|
|
end
|
|
end
|
|
|
|
def version_check
|
|
latest_version = Gem::Version.new(result["current_version"])
|
|
installed_version = Gem::Version.new(VERSION)
|
|
ui = Vagrant::UI::Prefixed.new(env.ui, "vagrant")
|
|
if latest_version > installed_version
|
|
@logger.info("new version of Vagrant available - #{latest_version}")
|
|
ui.info(I18n.t("vagrant.version_upgrade_available", latest_version: latest_version))
|
|
env.ui.info("")
|
|
else
|
|
@logger.debug("vagrant is currently up to date")
|
|
end
|
|
end
|
|
|
|
# @private
|
|
# Reset the cached values for platform. This is not considered a public
|
|
# API and should only be used for testing.
|
|
def reset!
|
|
logger = @logger
|
|
instance_variables.each(&method(:remove_instance_variable))
|
|
@logger = logger
|
|
@enabled = false
|
|
end
|
|
end
|
|
end
|
|
end
|