Add full checkpoint integration

This commit is contained in:
Chris Roberts 2018-01-16 14:15:43 -08:00
parent 6b1646eb51
commit 58f66ac8ce
6 changed files with 190 additions and 2 deletions

View File

@ -4,12 +4,14 @@ require 'optparse'
module Vagrant module Vagrant
# Manages the command line interface to Vagrant. # Manages the command line interface to Vagrant.
class CLI < Vagrant.plugin("2", :command) class CLI < Vagrant.plugin("2", :command)
def initialize(argv, env) def initialize(argv, env)
super super
@logger = Log4r::Logger.new("vagrant::cli") @logger = Log4r::Logger.new("vagrant::cli")
@main_args, @sub_command, @sub_args = split_main_and_subcommand(argv) @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
Util::CheckpointClient.instance.setup(env).check
@logger.info("CLI: #{@main_args.inspect} #{@sub_command.inspect} #{@sub_args.inspect}") @logger.info("CLI: #{@main_args.inspect} #{@sub_command.inspect} #{@sub_args.inspect}")
end end
@ -36,6 +38,8 @@ module Vagrant
command_class = command_plugin[0].call command_class = command_plugin[0].call
@logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}") @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
Util::CheckpointClient.instance.display
# Initialize and execute the command class, returning the exit status. # Initialize and execute the command class, returning the exit status.
result = 0 result = 0
begin begin

View File

@ -1,6 +1,7 @@
module Vagrant module Vagrant
module Util module Util
autoload :Busy, 'vagrant/util/busy' autoload :Busy, 'vagrant/util/busy'
autoload :CheckpointClient, 'vagrant/util/checkpoint_client'
autoload :CommandDeprecation, 'vagrant/util/command_deprecation' autoload :CommandDeprecation, 'vagrant/util/command_deprecation'
autoload :Counter, 'vagrant/util/counter' autoload :Counter, 'vagrant/util/counter'
autoload :CredentialScrubber, 'vagrant/util/credential_scrubber' autoload :CredentialScrubber, 'vagrant/util/credential_scrubber'

View File

@ -0,0 +1,174 @@
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
@files = {
signature: env.data_dir.join("checkpoint_signature"),
cache: env.data_dir.join("checkpoint_cache")
}
@checkpoint_thread = nil
@env = env
self
end
# Start checkpoint check
#
# @return [self]
def check
start_check
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 start_check
if enabled && @checkpoint_thread.nil?
logger.debug("starting plugin check")
@checkpoint_thread = Thread.new do
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
end
end
end

View File

@ -22,7 +22,7 @@ module VagrantPlugins
@env.ui.machine("version-installed", Vagrant::VERSION) @env.ui.machine("version-installed", Vagrant::VERSION)
# Load the latest information # Load the latest information
cp = @env.checkpoint cp = Vagrant::Util::CheckpointClient.instance.result
if !cp if !cp
@env.ui.output("\n"+I18n.t( @env.ui.output("\n"+I18n.t(
"vagrant.version_no_checkpoint")) "vagrant.version_no_checkpoint"))

View File

@ -1,5 +1,10 @@
en: en:
vagrant: vagrant:
alert: |-
[%{date}]:
%{message}
- %{url}
boot_completed: |- boot_completed: |-
Machine booted and ready! Machine booted and ready!
boot_waiting: |- boot_waiting: |-
@ -283,6 +288,10 @@ en:
version_no_checkpoint: |- version_no_checkpoint: |-
Vagrant was unable to check for the latest version of Vagrant. Vagrant was unable to check for the latest version of Vagrant.
Please check manually at https://www.vagrantup.com Please check manually at https://www.vagrantup.com
version_upgrade_available: |-
A new version of Vagrant is available: %{latest_version}!
To upgrade visit: https://www.vagrantup.com/downloads.html
version_upgrade_howto: |- version_upgrade_howto: |-
To upgrade to the latest version, visit the downloads page and To upgrade to the latest version, visit the downloads page and
download and install the latest version of Vagrant from the URL download and install the latest version of Vagrant from the URL

View File

@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.add_dependency "erubis", "~> 2.7.0" s.add_dependency "erubis", "~> 2.7.0"
s.add_dependency "i18n", ">= 0.6.0", "<= 0.8.0" s.add_dependency "i18n", ">= 0.6.0", "<= 0.8.0"
s.add_dependency "listen", "~> 3.1.5" s.add_dependency "listen", "~> 3.1.5"
s.add_dependency "hashicorp-checkpoint", "~> 0.1.1" s.add_dependency "hashicorp-checkpoint", "~> 0.1.5"
s.add_dependency "log4r", "~> 1.1.9", "< 1.1.11" s.add_dependency "log4r", "~> 1.1.9", "< 1.1.11"
s.add_dependency "net-ssh", "~> 4.2.0" s.add_dependency "net-ssh", "~> 4.2.0"
s.add_dependency "net-sftp", "~> 2.1" s.add_dependency "net-sftp", "~> 2.1"