This commit updates the behavior of printing the checkpoint version check for Vagrant. To allow users to filter out the message, it updates the version check to go to stderr. It updates the UI class for printing the version check to be a "basic" class, so that the message continues to be the same color instead of a red error message.
184 lines
5.3 KiB
Ruby
184 lines
5.3 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(Vagrant::UI::Basic.new, "vagrant")
|
|
if latest_version > installed_version
|
|
@logger.info("new version of Vagrant available - #{latest_version}")
|
|
ui.error(I18n.t("vagrant.version_upgrade_available", latest_version: latest_version, installed_version: installed_version))
|
|
env.ui.error("")
|
|
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
|