Class: Vagrant::Action::Builtin::BoxRemove

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant/action/builtin/box_remove.rb

Overview

This middleware will remove a box for a given provider.

Instance Method Summary collapse

Constructor Details

#initialize(app, env) ⇒ BoxRemove

Returns a new instance of BoxRemove.


8
9
10
11
# File 'lib/vagrant/action/builtin/box_remove.rb', line 8

def initialize(app, env)
  @app    = app
  @logger = Log4r::Logger.new("vagrant::action::builtin::box_remove")
end

Instance Method Details

#call(env) ⇒ Object


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
# File 'lib/vagrant/action/builtin/box_remove.rb', line 13

def call(env)
  box_name     = env[:box_name]
  box_provider = env[:box_provider]
  box_provider = box_provider.to_sym if box_provider
  box_version  = env[:box_version]
  box_remove_all_versions = env[:box_remove_all_versions]

  boxes = {}
  env[:box_collection].all.each do |n, v, p|
    boxes[n] ||= {}
    boxes[n][p] ||= []
    boxes[n][p] << v
  end

  all_box = boxes[box_name]
  if !all_box
    raise Errors::BoxRemoveNotFound, name: box_name
  end

  all_versions = nil
  if !box_provider
    if all_box.length == 1
      # There is only one provider, just use that.
      all_versions = all_box.values.first
      box_provider = all_box.keys.first
    else
      raise Errors::BoxRemoveMultiProvider,
        name: box_name,
        providers: all_box.keys.map(&:to_s).sort.join(", ")
    end
  else
    all_versions = all_box[box_provider]
    if !all_versions
      raise Errors::BoxRemoveProviderNotFound,
        name: box_name,
        provider: box_provider.to_s,
        providers: all_box.keys.map(&:to_s).sort.join(", ")
    end
  end

  if !box_version
    if all_versions.length == 1
      # There is only one version, just use that.
      box_version = all_versions.first
    elsif not box_remove_all_versions
      # There are multiple versions, we can't choose.
      raise Errors::BoxRemoveMultiVersion,
        name: box_name,
        provider: box_provider.to_s,
        versions: all_versions.sort.map { |k| " * #{k}" }.join("\n")
    end
  elsif !all_versions.include?(box_version)
    raise Errors::BoxRemoveVersionNotFound,
      name: box_name,
      provider: box_provider.to_s,
      version: box_version,
      versions: all_versions.sort.map { |k| " * #{k}" }.join("\n")
  end

  versions_to_remove = [box_version]
  versions_to_remove = all_versions if box_remove_all_versions

  versions_to_remove.sort.each do |version_to_remove|
    box = env[:box_collection].find(
      box_name, box_provider, box_version)

    # Verify that this box is not in use by an active machine,
    # otherwise warn the user.
    users = box.in_use?(env[:machine_index]) || []
    users = users.find_all { |u| u.valid?(env[:home_path]) }
    if !users.empty?
      # Build up the output to show the user.
      users = users.map do |entry|
        "#{entry.name} (ID: #{entry.id})"
      end.join("\n")

      force_key = :force_confirm_box_remove
      message   = I18n.t(
        "vagrant.commands.box.remove_in_use_query",
        name: box.name,
        provider: box.provider,
        version: box.version,
        users: users) + " "

      # Ask the user if we should do this
      stack = Builder.new.tap do |b|
        b.use Confirm, message, force_key
      end

      # Keep used boxes, even if "force" is applied
      keep_used_boxes = env[:keep_used_boxes]

      result = env[:action_runner].run(stack, env)
      if !result[:result] || keep_used_boxes
        # They said "no", so continue with the next box
        next
      end
    end

    env[:ui].info(I18n.t("vagrant.commands.box.removing",
                        name: box.name,
                        provider: box.provider,
                        version: box.version))
    box.destroy!
    env[:box_collection].clean(box.name)

    # Passes on the removed box to the rest of the middleware chain
    env[:box_removed] = box
  end

  @app.call(env)
end