bosh_cli 0.19.6 → 1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/bosh +3 -0
- data/lib/cli.rb +15 -5
- data/lib/cli/{commands/base.rb → base_command.rb} +38 -44
- data/lib/cli/command_discovery.rb +40 -0
- data/lib/cli/command_handler.rb +135 -0
- data/lib/cli/commands/biff.rb +16 -12
- data/lib/cli/commands/blob_management.rb +10 -3
- data/lib/cli/commands/cloudcheck.rb +13 -11
- data/lib/cli/commands/complete.rb +29 -0
- data/lib/cli/commands/deployment.rb +137 -28
- data/lib/cli/commands/help.rb +96 -0
- data/lib/cli/commands/job.rb +4 -1
- data/lib/cli/commands/job_management.rb +36 -23
- data/lib/cli/commands/job_rename.rb +11 -12
- data/lib/cli/commands/log_management.rb +28 -32
- data/lib/cli/commands/maintenance.rb +6 -1
- data/lib/cli/commands/misc.rb +129 -87
- data/lib/cli/commands/package.rb +6 -65
- data/lib/cli/commands/property_management.rb +20 -8
- data/lib/cli/commands/release.rb +211 -206
- data/lib/cli/commands/ssh.rb +178 -188
- data/lib/cli/commands/stemcell.rb +114 -51
- data/lib/cli/commands/task.rb +74 -56
- data/lib/cli/commands/user.rb +6 -3
- data/lib/cli/commands/vms.rb +17 -15
- data/lib/cli/config.rb +27 -1
- data/lib/cli/core_ext.rb +27 -1
- data/lib/cli/deployment_helper.rb +47 -0
- data/lib/cli/director.rb +18 -9
- data/lib/cli/errors.rb +6 -0
- data/lib/cli/job_builder.rb +75 -23
- data/lib/cli/job_property_collection.rb +87 -0
- data/lib/cli/job_property_validator.rb +130 -0
- data/lib/cli/package_builder.rb +32 -5
- data/lib/cli/release.rb +2 -0
- data/lib/cli/release_builder.rb +9 -13
- data/lib/cli/release_compiler.rb +5 -34
- data/lib/cli/release_tarball.rb +4 -19
- data/lib/cli/runner.rb +118 -694
- data/lib/cli/version.rb +1 -1
- data/spec/assets/config/swift-hp/config/final.yml +6 -0
- data/spec/assets/config/swift-hp/config/private.yml +7 -0
- data/spec/assets/config/swift-rackspace/config/final.yml +6 -0
- data/spec/assets/config/swift-rackspace/config/private.yml +6 -0
- data/spec/spec_helper.rb +0 -5
- data/spec/unit/base_command_spec.rb +32 -37
- data/spec/unit/biff_spec.rb +11 -10
- data/spec/unit/cli_commands_spec.rb +96 -88
- data/spec/unit/core_ext_spec.rb +1 -1
- data/spec/unit/deployment_manifest_spec.rb +36 -0
- data/spec/unit/director_spec.rb +17 -3
- data/spec/unit/job_builder_spec.rb +2 -2
- data/spec/unit/job_property_collection_spec.rb +111 -0
- data/spec/unit/job_property_validator_spec.rb +7 -0
- data/spec/unit/job_rename_spec.rb +7 -6
- data/spec/unit/package_builder_spec.rb +2 -2
- data/spec/unit/release_builder_spec.rb +33 -0
- data/spec/unit/release_spec.rb +54 -0
- data/spec/unit/release_tarball_spec.rb +2 -7
- data/spec/unit/runner_spec.rb +1 -151
- data/spec/unit/ssh_spec.rb +15 -9
- metadata +41 -12
- data/lib/cli/command_definition.rb +0 -52
- data/lib/cli/templates/help_message.erb +0 -80
    
        data/bin/bosh
    CHANGED
    
    
    
        data/lib/cli.rb
    CHANGED
    
    | @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            module Bosh
         | 
| 4 4 | 
             
              module Cli
         | 
| 5 5 | 
             
                DEFAULT_CONFIG_PATH = File.expand_path("~/.bosh_config")
         | 
| 6 | 
            -
                DEFAULT_CACHE_DIR | 
| 6 | 
            +
                DEFAULT_CACHE_DIR = File.expand_path("~/.bosh_cache")
         | 
| 7 7 | 
             
              end
         | 
| 8 8 | 
             
            end
         | 
| 9 9 |  | 
| @@ -70,13 +70,23 @@ require "cli/release_tarball" | |
| 70 70 |  | 
| 71 71 | 
             
            require "cli/blob_manager"
         | 
| 72 72 |  | 
| 73 | 
            -
            require " | 
| 73 | 
            +
            require "common/properties"
         | 
| 74 | 
            +
            require "cli/job_property_collection"
         | 
| 75 | 
            +
            require "cli/job_property_validator"
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            require "cli/command_discovery"
         | 
| 78 | 
            +
            require "cli/command_handler"
         | 
| 74 79 | 
             
            require "cli/runner"
         | 
| 80 | 
            +
            require "cli/base_command"
         | 
| 75 81 |  | 
| 76 | 
            -
             | 
| 82 | 
            +
            if defined?(YAML::ENGINE.yamler)
         | 
| 83 | 
            +
              YAML::ENGINE.yamler = "syck"
         | 
| 84 | 
            +
            end
         | 
| 77 85 |  | 
| 78 | 
            -
             | 
| 86 | 
            +
            tmpdir = Dir.mktmpdir
         | 
| 87 | 
            +
            at_exit { FileUtils.rm_rf(tmpdir) }
         | 
| 88 | 
            +
            ENV["TMPDIR"] = tmpdir
         | 
| 79 89 |  | 
| 80 90 | 
             
            Dir[File.dirname(__FILE__) + "/cli/commands/*.rb"].each do |file|
         | 
| 81 | 
            -
              require  | 
| 91 | 
            +
              require file
         | 
| 82 92 | 
             
            end
         | 
| @@ -3,31 +3,50 @@ | |
| 3 3 | 
             
            module Bosh::Cli
         | 
| 4 4 | 
             
              module Command
         | 
| 5 5 | 
             
                class Base
         | 
| 6 | 
            -
                   | 
| 7 | 
            -
             | 
| 6 | 
            +
                  extend Bosh::Cli::CommandDiscovery
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  attr_reader :options
         | 
| 9 | 
            +
                  attr_reader :work_dir
         | 
| 10 | 
            +
                  attr_reader :runner
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  attr_accessor :out
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # @return [Array] Arguments passed to command handler
         | 
| 15 | 
            +
                  attr_accessor :args
         | 
| 8 16 |  | 
| 9 17 | 
             
                  DEFAULT_DIRECTOR_PORT = 25555
         | 
| 10 18 |  | 
| 11 | 
            -
                   | 
| 12 | 
            -
             | 
| 19 | 
            +
                  # @param [Bosh::Cli::Runner] runner
         | 
| 20 | 
            +
                  def initialize(runner = nil)
         | 
| 21 | 
            +
                    @runner = runner
         | 
| 22 | 
            +
                    @options = {}
         | 
| 13 23 | 
             
                    @work_dir = Dir.pwd
         | 
| 14 | 
            -
                    config_file = @options[:config] || Bosh::Cli::DEFAULT_CONFIG_PATH
         | 
| 15 | 
            -
                    @config = Config.new(config_file)
         | 
| 16 | 
            -
                    @cache = Config.cache
         | 
| 17 24 | 
             
                    @exit_code = 0
         | 
| 18 25 | 
             
                    @out = nil
         | 
| 19 | 
            -
                    @ | 
| 26 | 
            +
                    @args = []
         | 
| 20 27 | 
             
                  end
         | 
| 21 28 |  | 
| 22 | 
            -
                   | 
| 23 | 
            -
             | 
| 29 | 
            +
                  # @return [Bosh::Cli::Cache] Current CLI cache
         | 
| 30 | 
            +
                  def cache
         | 
| 31 | 
            +
                    Config.cache
         | 
| 32 | 
            +
                  end
         | 
| 24 33 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 34 | 
            +
                  # @return [Bosh::Cli::Config] Current configuration
         | 
| 35 | 
            +
                  def config
         | 
| 36 | 
            +
                    @config ||= begin
         | 
| 37 | 
            +
                      config_file = options[:config] || Bosh::Cli::DEFAULT_CONFIG_PATH
         | 
| 38 | 
            +
                      Bosh::Cli::Config.new(config_file)
         | 
| 28 39 | 
             
                    end
         | 
| 29 40 | 
             
                  end
         | 
| 30 41 |  | 
| 42 | 
            +
                  def add_option(name, value)
         | 
| 43 | 
            +
                    @options[name] = value
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def remove_option(name)
         | 
| 47 | 
            +
                    @options.delete(name)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 31 50 | 
             
                  def director
         | 
| 32 51 | 
             
                    @director ||= Bosh::Cli::Director.new(target, username, password)
         | 
| 33 52 | 
             
                  end
         | 
| @@ -51,38 +70,24 @@ module Bosh::Cli | |
| 51 70 | 
             
                  end
         | 
| 52 71 |  | 
| 53 72 | 
             
                  def non_interactive?
         | 
| 54 | 
            -
                     | 
| 73 | 
            +
                    options[:non_interactive]
         | 
| 55 74 | 
             
                  end
         | 
| 56 75 |  | 
| 57 76 | 
             
                  def interactive?
         | 
| 58 | 
            -
                    ! | 
| 77 | 
            +
                    !non_interactive?
         | 
| 59 78 | 
             
                  end
         | 
| 60 79 |  | 
| 61 80 | 
             
                  def verbose?
         | 
| 62 | 
            -
                    options[:verbose]
         | 
| 63 | 
            -
                  end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                  # TODO: implement it
         | 
| 66 | 
            -
                  def dry_run?
         | 
| 67 | 
            -
                    options[:dry_run]
         | 
| 68 | 
            -
                  end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                  def show_usage
         | 
| 71 | 
            -
                    say("Usage: #{@usage}") if @usage
         | 
| 72 | 
            -
                  end
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                  def run(namespace, action, *args)
         | 
| 75 | 
            -
                    eval(namespace.to_s.capitalize).new(options).send(action.to_sym, *args)
         | 
| 81 | 
            +
                    @options[:verbose]
         | 
| 76 82 | 
             
                  end
         | 
| 77 83 |  | 
| 78 84 | 
             
                  def redirect(*args)
         | 
| 79 | 
            -
                     | 
| 80 | 
            -
                    raise Bosh::Cli::GracefulExit, "redirected to %s" % [args.join(" ")]
         | 
| 85 | 
            +
                    Bosh::Cli::Runner.new(args, @options).run
         | 
| 81 86 | 
             
                  end
         | 
| 82 87 |  | 
| 83 88 | 
             
                  def confirmed?(question = "Are you sure?")
         | 
| 84 | 
            -
                    non_interactive? | 
| 85 | 
            -
             | 
| 89 | 
            +
                    return true if non_interactive?
         | 
| 90 | 
            +
                    ask("#{question} (type 'yes' to continue): ") == "yes"
         | 
| 86 91 | 
             
                  end
         | 
| 87 92 |  | 
| 88 93 | 
             
                  # @return [String] Target director URL
         | 
| @@ -112,17 +117,6 @@ module Bosh::Cli | |
| 112 117 | 
             
                    config.target_name || target_url
         | 
| 113 118 | 
             
                  end
         | 
| 114 119 |  | 
| 115 | 
            -
                  def target_version
         | 
| 116 | 
            -
                    config.target_version ? "Ver: " + config.target_version : ""
         | 
| 117 | 
            -
                  end
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                  def full_target_name
         | 
| 120 | 
            -
                    # TODO refactor this method
         | 
| 121 | 
            -
                    ret = (target_name.blank? || target_name == target_url ?
         | 
| 122 | 
            -
                        target_name : "%s (%s)" % [target_name, target_url])
         | 
| 123 | 
            -
                    ret + " %s" % target_version if ret
         | 
| 124 | 
            -
                  end
         | 
| 125 | 
            -
             | 
| 126 120 | 
             
                  # Sets or returns command exit code
         | 
| 127 121 | 
             
                  # @param [optional,Integer] code If param is given, sets exit code. If
         | 
| 128 122 | 
             
                  #   it's nil, returns previously set exit_code
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # Copyright (c) 2009-2012 VMware, Inc.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Bosh::Cli
         | 
| 4 | 
            +
              module CommandDiscovery
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def usage(string = nil)
         | 
| 7 | 
            +
                  @usage = string
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def desc(string)
         | 
| 11 | 
            +
                  @desc = string
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def option(name, *args)
         | 
| 15 | 
            +
                  (@options ||= []) << [name, args]
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # @param [Symbol] method_name Method name
         | 
| 19 | 
            +
                def method_added(method_name)
         | 
| 20 | 
            +
                  if @usage && @desc
         | 
| 21 | 
            +
                    @options ||= []
         | 
| 22 | 
            +
                    method = instance_method(method_name)
         | 
| 23 | 
            +
                    register_command(method, @usage, @desc, @options)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  @usage = nil
         | 
| 26 | 
            +
                  @desc = nil
         | 
| 27 | 
            +
                  @options = []
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                # @param [UnboundMethod] method Method implementing the command
         | 
| 31 | 
            +
                # @param [String] usage Command usage (used to parse command)
         | 
| 32 | 
            +
                # @param [String] desc Command description
         | 
| 33 | 
            +
                # @param [Array] options Command options
         | 
| 34 | 
            +
                def register_command(method, usage, desc, options = [])
         | 
| 35 | 
            +
                  command = CommandHandler.new(self, method, usage, desc, options)
         | 
| 36 | 
            +
                  Bosh::Cli::Config.register_command(command)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,135 @@ | |
| 1 | 
            +
            # Copyright (c) 2009-2012 VMware, Inc.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Bosh::Cli
         | 
| 4 | 
            +
              class CommandHandler
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                # @return [Array]
         | 
| 7 | 
            +
                attr_reader :keywords
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                # @return [String]
         | 
| 10 | 
            +
                attr_reader :usage
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                # @return [String]
         | 
| 13 | 
            +
                attr_reader :desc
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # @return [Bosh::Cli::Runner]
         | 
| 16 | 
            +
                attr_accessor :runner
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # @param [Class] klass
         | 
| 19 | 
            +
                # @param [UnboundMethod] method
         | 
| 20 | 
            +
                # @param [String] usage
         | 
| 21 | 
            +
                # @param [String] desc
         | 
| 22 | 
            +
                def initialize(klass, method, usage, desc, options = [])
         | 
| 23 | 
            +
                  @klass = klass
         | 
| 24 | 
            +
                  @method = method
         | 
| 25 | 
            +
                  @usage = usage
         | 
| 26 | 
            +
                  @desc = desc
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  @options = options
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  @hints = []
         | 
| 31 | 
            +
                  @keywords = []
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  @parser = OptionParser.new
         | 
| 34 | 
            +
                  @runner = nil
         | 
| 35 | 
            +
                  extract_keywords
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                # Run handler with provided args
         | 
| 39 | 
            +
                # @param [Array] args
         | 
| 40 | 
            +
                # @return [Integer] Command exit code
         | 
| 41 | 
            +
                def run(args, extra_options = {})
         | 
| 42 | 
            +
                  handler = @klass.new(@runner)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  @options.each do |(name, arguments)|
         | 
| 45 | 
            +
                    @parser.on(name, *arguments) do |value|
         | 
| 46 | 
            +
                      handler.add_option(format_option_name(name), value)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  extra_options.each_pair do |name, value|
         | 
| 51 | 
            +
                    handler.add_option(format_option_name(name), value)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  args = parse_options(args)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  begin
         | 
| 57 | 
            +
                    handler.send(@method.name, *args)
         | 
| 58 | 
            +
                    handler.exit_code
         | 
| 59 | 
            +
                  rescue ArgumentError => e
         | 
| 60 | 
            +
                    say(e.message)
         | 
| 61 | 
            +
                    err("Usage: #{usage_with_params}")
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def usage_with_params
         | 
| 66 | 
            +
                  result = [@usage]
         | 
| 67 | 
            +
                  @method.parameters.each do |parameter|
         | 
| 68 | 
            +
                    next if parameter.size < 2
         | 
| 69 | 
            +
                    kind, name = parameter
         | 
| 70 | 
            +
                    if kind == :opt
         | 
| 71 | 
            +
                      result << "[<#{name}>]"
         | 
| 72 | 
            +
                    elsif kind == :req
         | 
| 73 | 
            +
                      result << "<#{name}>"
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  @options.each do |(name, _)|
         | 
| 78 | 
            +
                    result << "[#{name}]"
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  result.join(" ")
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                def has_options?
         | 
| 85 | 
            +
                  @options.size > 0
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                def options_summary
         | 
| 89 | 
            +
                  result = []
         | 
| 90 | 
            +
                  padding = 5
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  margin = @options.inject(0) do |max, (name, _)|
         | 
| 93 | 
            +
                    [max, name.size].max
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  @options.each do |(name, desc)|
         | 
| 97 | 
            +
                    desc = desc.select { |word| word.is_a?(String) }
         | 
| 98 | 
            +
                    column_width = terminal_width - padding - margin
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                    result << name.ljust(margin).yellow + " " +
         | 
| 101 | 
            +
                      desc.join(" ").columnize(
         | 
| 102 | 
            +
                        column_width, [margin + 1, name.size + 1].max)
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  result.join("\n")
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                # @param [Array] args Arguments to parse
         | 
| 109 | 
            +
                def parse_options(args)
         | 
| 110 | 
            +
                  @parser.parse!(args)
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                private
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                def format_option_name(name)
         | 
| 116 | 
            +
                  case name
         | 
| 117 | 
            +
                  when Symbol
         | 
| 118 | 
            +
                    name
         | 
| 119 | 
            +
                  when String
         | 
| 120 | 
            +
                    name.split(/\s+/)[0].gsub(/^-*/, "").gsub("-", "_").to_sym
         | 
| 121 | 
            +
                  else
         | 
| 122 | 
            +
                    name
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                def extract_keywords
         | 
| 127 | 
            +
                  words = @usage.split(/\s+/)
         | 
| 128 | 
            +
                  words.each do |word|
         | 
| 129 | 
            +
                    break unless word.match(/^[a-z]/i)
         | 
| 130 | 
            +
                    @keywords << word
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
            end
         | 
    
        data/lib/cli/commands/biff.rb
    CHANGED
    
    | @@ -8,22 +8,26 @@ module Bosh::Cli::Command | |
| 8 8 | 
             
                # are diff'd and the user can choose to keep the new config.
         | 
| 9 9 | 
             
                # @param [String] template The string path to the template that should be
         | 
| 10 10 | 
             
                #     used.
         | 
| 11 | 
            +
                #
         | 
| 12 | 
            +
                usage "diff"
         | 
| 13 | 
            +
                desc "Diffs your current BOSH deployment configuration against " +
         | 
| 14 | 
            +
                     "the specified BOSH deployment configuration template so that " +
         | 
| 15 | 
            +
                     "you can keep your deployment configuration file up to date. " +
         | 
| 16 | 
            +
                     "A dev template can be found in deployments repos."
         | 
| 11 17 | 
             
                def biff(template)
         | 
| 12 | 
            -
                   | 
| 13 | 
            -
                    setup(template)
         | 
| 18 | 
            +
                  setup(template)
         | 
| 14 19 |  | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 20 | 
            +
                  template_to_fill = ERB.new(File.read(@template_file), 0, "%<>-")
         | 
| 21 | 
            +
                  @template_output = template_to_fill.result(binding)
         | 
| 17 22 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
                    end
         | 
| 24 | 
            -
                  ensure
         | 
| 25 | 
            -
                    delete_temp_diff_files
         | 
| 23 | 
            +
                  if @errors == 0
         | 
| 24 | 
            +
                    print_string_diff(File.read(@deployment_file), @template_output)
         | 
| 25 | 
            +
                    keep_new_file unless @no_differences
         | 
| 26 | 
            +
                  else
         | 
| 27 | 
            +
                    err("There were #{@errors} errors.")
         | 
| 26 28 | 
             
                  end
         | 
| 29 | 
            +
                ensure
         | 
| 30 | 
            +
                  delete_temp_diff_files
         | 
| 27 31 | 
             
                end
         | 
| 28 32 |  | 
| 29 33 | 
             
                private
         | 
| @@ -4,6 +4,8 @@ module Bosh::Cli::Command | |
| 4 4 | 
             
              class BlobManagement < Base
         | 
| 5 5 |  | 
| 6 6 | 
             
                # Prints out blobs status
         | 
| 7 | 
            +
                usage "blobs"
         | 
| 8 | 
            +
                desc "Print current blobs status"
         | 
| 7 9 | 
             
                def status
         | 
| 8 10 | 
             
                  blob_manager.print_status
         | 
| 9 11 | 
             
                end
         | 
| @@ -11,11 +13,13 @@ module Bosh::Cli::Command | |
| 11 13 | 
             
                # Adds blob to managed blobs
         | 
| 12 14 | 
             
                # @param [String] local_path Local file path
         | 
| 13 15 | 
             
                # @param [optional, String] blob_dir Directory to store blob in, relative
         | 
| 14 | 
            -
                # | 
| 16 | 
            +
                #   to blobs dir
         | 
| 17 | 
            +
                usage "add blob"
         | 
| 18 | 
            +
                desc "Add a local file as BOSH blob"
         | 
| 15 19 | 
             
                def add(local_path, blob_dir = nil)
         | 
| 16 20 | 
             
                  blob_path = File.basename(local_path)
         | 
| 17 21 | 
             
                  if blob_dir
         | 
| 18 | 
            -
                    # We don't need  | 
| 22 | 
            +
                    # We don't need 'blobs/' prefix,
         | 
| 19 23 | 
             
                    # but it might be handy for people who rely on auto-completion
         | 
| 20 24 | 
             
                    if blob_dir[0..5] == "blobs/"
         | 
| 21 25 | 
             
                      blob_dir = blob_dir[6..-1]
         | 
| @@ -26,6 +30,8 @@ module Bosh::Cli::Command | |
| 26 30 | 
             
                end
         | 
| 27 31 |  | 
| 28 32 | 
             
                # Uploads all blobs that need to be uploaded
         | 
| 33 | 
            +
                usage "upload blobs"
         | 
| 34 | 
            +
                desc "Upload new and updated blobs to the blobstore"
         | 
| 29 35 | 
             
                def upload
         | 
| 30 36 | 
             
                  blob_manager.print_status
         | 
| 31 37 |  | 
| @@ -38,10 +44,11 @@ module Bosh::Cli::Command | |
| 38 44 | 
             
                end
         | 
| 39 45 |  | 
| 40 46 | 
             
                # Syncs blobs with blobstore
         | 
| 47 | 
            +
                usage "sync blobs"
         | 
| 48 | 
            +
                desc "Sync blob with the blobstore"
         | 
| 41 49 | 
             
                def sync
         | 
| 42 50 | 
             
                  blob_manager.sync
         | 
| 43 51 | 
             
                  blob_manager.print_status
         | 
| 44 52 | 
             
                end
         | 
| 45 | 
            -
             | 
| 46 53 | 
             
              end
         | 
| 47 54 | 
             
            end
         | 
| @@ -4,23 +4,25 @@ module Bosh::Cli::Command | |
| 4 4 | 
             
              class CloudCheck < Base
         | 
| 5 5 | 
             
                include Bosh::Cli::DeploymentHelper
         | 
| 6 6 |  | 
| 7 | 
            -
                 | 
| 7 | 
            +
                # bosh cloudcheck
         | 
| 8 | 
            +
                usage "cloudcheck"
         | 
| 9 | 
            +
                desc "Cloud consistency check and interactive repair"
         | 
| 10 | 
            +
                option "--auto",
         | 
| 11 | 
            +
                       "resolve problems automatically ",
         | 
| 12 | 
            +
                       "(not recommended for production)"
         | 
| 13 | 
            +
                option "--report",
         | 
| 14 | 
            +
                       "generate report only, ",
         | 
| 15 | 
            +
                       "don't attempt to resolve problems"
         | 
| 16 | 
            +
                def perform(deployment_name = nil)
         | 
| 8 17 | 
             
                  auth_required
         | 
| 9 | 
            -
                   | 
| 10 | 
            -
                   | 
| 11 | 
            -
             | 
| 12 | 
            -
                  @auto_mode = options.delete("--auto")
         | 
| 13 | 
            -
                  @report_mode = options.delete("--report")
         | 
| 18 | 
            +
                  @auto_mode = options[:auto]
         | 
| 19 | 
            +
                  @report_mode = options[:report]
         | 
| 14 20 |  | 
| 15 21 | 
             
                  if non_interactive? && !@report_mode
         | 
| 16 22 | 
             
                    err ("Cloudcheck cannot be run in non-interactive mode\n" +
         | 
| 17 23 | 
             
                         "Please use `--auto' flag if you want automated resolutions")
         | 
| 18 24 | 
             
                  end
         | 
| 19 25 |  | 
| 20 | 
            -
                  if options.size > 0
         | 
| 21 | 
            -
                    err("Unknown options: #{options.join(", ")}")
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 26 | 
             
                  if @auto_mode && @report_mode
         | 
| 25 27 | 
             
                    err("Can't use --auto and --report mode together")
         | 
| 26 28 | 
             
                  end
         | 
| @@ -90,7 +92,7 @@ module Bosh::Cli::Command | |
| 90 92 |  | 
| 91 93 | 
             
                  if @problems.empty?
         | 
| 92 94 | 
             
                    say("No problems found".green)
         | 
| 93 | 
            -
                     | 
| 95 | 
            +
                    exit(0)
         | 
| 94 96 | 
             
                  end
         | 
| 95 97 |  | 
| 96 98 | 
             
                  @problems.each do |problem|
         |