vagrant-unbundled 2.2.6.2 → 2.2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.hashibot.hcl +12 -0
  3. data/CHANGELOG.md +37 -2
  4. data/contrib/bash/completion.sh +13 -1
  5. data/lib/vagrant/action.rb +1 -0
  6. data/lib/vagrant/action/builtin/box_add.rb +9 -3
  7. data/lib/vagrant/action/builtin/box_check_outdated.rb +12 -15
  8. data/lib/vagrant/action/builtin/disk.rb +39 -0
  9. data/lib/vagrant/action/builtin/mixin_provisioners.rb +19 -1
  10. data/lib/vagrant/action/builtin/ssh_run.rb +21 -3
  11. data/lib/vagrant/action/warden.rb +9 -0
  12. data/lib/vagrant/box_metadata.rb +17 -3
  13. data/lib/vagrant/errors.rb +4 -0
  14. data/lib/vagrant/ui.rb +8 -3
  15. data/lib/vagrant/util/file_checksum.rb +6 -2
  16. data/lib/vagrant/util/is_port_open.rb +1 -2
  17. data/lib/vagrant/util/numeric.rb +61 -0
  18. data/plugins/commands/box/command/outdated.rb +14 -2
  19. data/plugins/commands/cloud/publish.rb +1 -1
  20. data/plugins/commands/snapshot/command/save.rb +13 -8
  21. data/plugins/guests/alpine/cap/rsync.rb +1 -1
  22. data/plugins/guests/alpine/plugin.rb +16 -0
  23. data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +86 -13
  24. data/plugins/guests/linux/cap/reboot.rb +42 -0
  25. data/plugins/guests/linux/plugin.rb +10 -0
  26. data/plugins/guests/redhat/cap/nfs_client.rb +2 -2
  27. data/plugins/guests/suse/cap/change_host_name.rb +2 -2
  28. data/plugins/hosts/darwin/cap/nfs.rb +11 -0
  29. data/plugins/hosts/darwin/plugin.rb +5 -0
  30. data/plugins/hosts/linux/cap/nfs.rb +20 -2
  31. data/plugins/kernel_v2/config/disk.rb +168 -0
  32. data/plugins/kernel_v2/config/vm.rb +82 -1
  33. data/plugins/kernel_v2/config/vm_provisioner.rb +4 -1
  34. data/plugins/providers/docker/driver.rb +22 -10
  35. data/plugins/providers/docker/errors.rb +4 -0
  36. data/plugins/providers/docker/executor/local.rb +7 -1
  37. data/plugins/providers/virtualbox/action.rb +1 -0
  38. data/plugins/providers/virtualbox/action/clean_machine_folder.rb +10 -1
  39. data/plugins/providers/virtualbox/driver/meta.rb +1 -0
  40. data/plugins/providers/virtualbox/driver/version_6_1.rb +16 -0
  41. data/plugins/providers/virtualbox/plugin.rb +1 -0
  42. data/plugins/provisioners/ansible/cap/guest/arch/ansible_install.rb +20 -3
  43. data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +4 -5
  44. data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +2 -2
  45. data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +2 -2
  46. data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +8 -4
  47. data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +2 -2
  48. data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +2 -1
  49. data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
  50. data/templates/commands/init/Vagrantfile.erb +1 -1
  51. data/templates/locales/en.yml +32 -2
  52. data/templates/locales/providers_docker.yml +2 -0
  53. data/templates/nfs/exports_darwin.erb +7 -0
  54. data/vagrant.gemspec +3 -4
  55. data/version.txt +1 -1
  56. metadata +7273 -773
@@ -11,6 +11,7 @@ require "vagrant/util/experimental"
11
11
 
12
12
  require File.expand_path("../vm_provisioner", __FILE__)
13
13
  require File.expand_path("../vm_subvm", __FILE__)
14
+ require File.expand_path("../disk", __FILE__)
14
15
 
15
16
  module VagrantPlugins
16
17
  module Kernel_V2
@@ -43,6 +44,7 @@ module VagrantPlugins
43
44
  attr_accessor :post_up_message
44
45
  attr_accessor :usable_port_range
45
46
  attr_reader :provisioners
47
+ attr_reader :disks
46
48
 
47
49
  # This is an experimental feature that isn't public yet.
48
50
  attr_accessor :clone
@@ -73,6 +75,7 @@ module VagrantPlugins
73
75
  @hostname = UNSET_VALUE
74
76
  @post_up_message = UNSET_VALUE
75
77
  @provisioners = []
78
+ @disks = []
76
79
  @usable_port_range = UNSET_VALUE
77
80
 
78
81
  # Internal state
@@ -123,6 +126,28 @@ module VagrantPlugins
123
126
  end
124
127
  end
125
128
 
129
+ # Merge defined disks
130
+ other_disks = other.instance_variable_get(:@disks)
131
+ new_disks = []
132
+ @disks.each do |p|
133
+ other_p = other_disks.find { |o| p.id == o.id }
134
+ if other_p
135
+ # there is an override. take it.
136
+ other_p.config = p.config.merge(other_p.config)
137
+
138
+ # Remove duplicate disk config from other
139
+ p = other_p
140
+ other_disks.delete(other_p)
141
+ end
142
+
143
+ # there is an override, merge it into the
144
+ new_disks << p.dup
145
+ end
146
+ other_disks.each do |p|
147
+ new_disks << p.dup
148
+ end
149
+ result.instance_variable_set(:@disks, new_disks)
150
+
126
151
  # Merge the providers by prepending any configuration blocks we
127
152
  # have for providers onto the new configuration.
128
153
  other_providers = other.instance_variable_get(:@__providers)
@@ -384,6 +409,38 @@ module VagrantPlugins
384
409
  @__defined_vms[name].config_procs << [options[:config_version], block] if block
385
410
  end
386
411
 
412
+ # Stores disk config options from Vagrantfile
413
+ #
414
+ # @param [Symbol] type
415
+ # @param [Hash] options
416
+ # @param [Block] block
417
+ def disk(type, **options, &block)
418
+ disk_config = VagrantConfigDisk.new(type)
419
+
420
+ # Remove provider__option options before set_options, otherwise will
421
+ # show up as missing setting
422
+ # Extract provider hash options as well
423
+ provider_options = {}
424
+ options.delete_if do |p,o|
425
+ if o.is_a?(Hash) || p.to_s.include?("__")
426
+ provider_options[p] = o
427
+ true
428
+ end
429
+ end
430
+
431
+ disk_config.set_options(options)
432
+
433
+ # Add provider config
434
+ disk_config.add_provider_config(provider_options, &block)
435
+
436
+ if !Vagrant::Util::Experimental.feature_enabled?("disk_base_config")
437
+ @logger.warn("Disk config defined, but experimental feature is not enabled. To use this feature, enable it with the experimental flag `disk_base_config`. Disk will not be added to internal config, and will be ignored.")
438
+ return
439
+ end
440
+
441
+ @disks << disk_config
442
+ end
443
+
387
444
  #-------------------------------------------------------------------
388
445
  # Internal methods, don't call these.
389
446
  #-------------------------------------------------------------------
@@ -547,6 +604,10 @@ module VagrantPlugins
547
604
  end
548
605
  end
549
606
 
607
+ @disks.each do |d|
608
+ d.finalize!
609
+ end
610
+
550
611
  if !current_dir_shared && !@__synced_folders["/vagrant"]
551
612
  synced_folder(".", "/vagrant")
552
613
  end
@@ -609,7 +670,7 @@ module VagrantPlugins
609
670
  errors << I18n.t("vagrant.config.vm.clone_and_box")
610
671
  end
611
672
 
612
- errors << I18n.t("vagrant.config.vm.hostname_invalid_characters") if \
673
+ errors << I18n.t("vagrant.config.vm.hostname_invalid_characters", name: machine.name) if \
613
674
  @hostname && @hostname !~ /^[a-z0-9][-.a-z0-9]*$/i
614
675
 
615
676
  if @box_version
@@ -748,6 +809,26 @@ module VagrantPlugins
748
809
  end
749
810
  end
750
811
 
812
+ # Validate disks
813
+ # Check if there is more than one primrary disk defined and throw an error
814
+ primary_disks = @disks.select { |d| d.primary && d.type == :disk }
815
+ if primary_disks.size > 1
816
+ errors << I18n.t("vagrant.config.vm.multiple_primary_disks_error",
817
+ name: machine.name)
818
+ end
819
+
820
+ disk_names = @disks.map { |d| d.name }
821
+ duplicate_names = disk_names.detect{ |d| disk_names.count(d) > 1 }
822
+ if duplicate_names && duplicate_names.size
823
+ errors << I18n.t("vagrant.config.vm.multiple_disk_names_error",
824
+ name: duplicate_names)
825
+ end
826
+
827
+ @disks.each do |d|
828
+ error = d.validate(machine)
829
+ errors.concat error if !error.empty?
830
+ end
831
+
751
832
  # We're done with VM level errors so prepare the section
752
833
  errors = { "vm" => errors }
753
834
 
@@ -9,7 +9,10 @@ module VagrantPlugins
9
9
 
10
10
  # Unique name for this provisioner
11
11
  #
12
- # @return [String]
12
+ # Accepts a string, but is ultimately forced into a symbol in the top level method inside
13
+ # #Config::VM.provision method while being parsed from a Vagrantfile
14
+ #
15
+ # @return [Symbol]
13
16
  attr_reader :name
14
17
 
15
18
  # Internal unique name for this provisioner
@@ -15,19 +15,31 @@ module VagrantPlugins
15
15
  @executor = Executor::Local.new
16
16
  end
17
17
 
18
+ # Returns the id for a new container built from `docker build`. Raises
19
+ # an exception if the id was unable to be captured from the output
20
+ #
21
+ # @return [String] id - ID matched from the docker build output.
18
22
  def build(dir, **opts, &block)
19
- args = Array(opts[:extra_args])
20
- args << dir
21
- result = execute('docker', 'build', *args, &block)
22
- matches = result.scan(/Successfully built (.+)$/i)
23
- if matches.empty?
24
- # This will cause a stack trace in Vagrant, but it is a bug
25
- # if this happens anyways.
26
- raise "UNKNOWN OUTPUT: #{result}"
23
+ args = Array(opts[:extra_args])
24
+ args << dir
25
+ opts = {with_stderr: true}
26
+ result = execute('docker', 'build', *args, opts, &block)
27
+ matches = result.match(/Successfully built (?<id>.+)$/i)
28
+ if !matches
29
+ # Check for the new output format 'writing image sha256...'
30
+ # In this case, docker builtkit is enabled. Its format is different
31
+ # from standard docker
32
+ @logger.warn("Could not determine docker container ID. Scanning for buildkit output instead")
33
+ matches = result.match(/writing image .+:(?<id>[0-9a-z]+) done/i)
34
+ if !matches
35
+ # This will cause a stack trace in Vagrant, but it is a bug
36
+ # if this happens anyways.
37
+ raise Errors::BuildError, result: result
38
+ end
27
39
  end
28
40
 
29
- # Return the last match, and the capture of it
30
- matches[-1][0]
41
+ # Return the matched group `id`
42
+ matches[:id]
31
43
  end
32
44
 
33
45
  def create(params, **opts, &block)
@@ -5,6 +5,10 @@ module VagrantPlugins
5
5
  error_namespace("docker_provider.errors")
6
6
  end
7
7
 
8
+ class BuildError < DockerError
9
+ error_key(:build_error)
10
+ end
11
+
8
12
  class CommunicatorNonDocker < DockerError
9
13
  error_key(:communicator_non_docker)
10
14
  end
@@ -27,7 +27,13 @@ module VagrantPlugins
27
27
  stdout: result.stdout
28
28
  end
29
29
 
30
- result.stdout
30
+ if opts
31
+ if opts[:with_stderr]
32
+ return result.stdout + " " + result.stderr
33
+ else
34
+ return result.stdout
35
+ end
36
+ end
31
37
  end
32
38
 
33
39
  def windows?
@@ -79,6 +79,7 @@ module VagrantPlugins
79
79
  b.use ForwardPorts
80
80
  b.use SetHostname
81
81
  b.use SaneDefaults
82
+ b.use Disk
82
83
  b.use Customize, "pre-boot"
83
84
  b.use Boot
84
85
  b.use Customize, "post-boot"
@@ -13,7 +13,16 @@ module VagrantPlugins
13
13
  end
14
14
 
15
15
  def call(env)
16
- clean_machine_folder(env[:machine].provider.driver.read_machine_folder)
16
+ machine_folder = env[:machine].provider.driver.read_machine_folder
17
+
18
+ begin
19
+ clean_machine_folder(machine_folder)
20
+ rescue Errno::EPERM
21
+ raise Vagrant::Errors::MachineFolderNotAccessible,
22
+ name: env[:machine].name,
23
+ path: machine_folder
24
+ end
25
+
17
26
  @app.call(env)
18
27
  end
19
28
 
@@ -64,6 +64,7 @@ module VagrantPlugins
64
64
  "5.1" => Version_5_1,
65
65
  "5.2" => Version_5_2,
66
66
  "6.0" => Version_6_0,
67
+ "6.1" => Version_6_1,
67
68
  }
68
69
 
69
70
  if @@version.start_with?("4.2.14")
@@ -0,0 +1,16 @@
1
+ require File.expand_path("../version_6_0", __FILE__)
2
+
3
+ module VagrantPlugins
4
+ module ProviderVirtualBox
5
+ module Driver
6
+ # Driver for VirtualBox 6.1.x
7
+ class Version_6_1 < Version_6_0
8
+ def initialize(uuid)
9
+ super
10
+
11
+ @logger = Log4r::Logger.new("vagrant::provider::virtualbox_6_1")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -59,6 +59,7 @@ module VagrantPlugins
59
59
  autoload :Version_5_1, File.expand_path("../driver/version_5_1", __FILE__)
60
60
  autoload :Version_5_2, File.expand_path("../driver/version_5_2", __FILE__)
61
61
  autoload :Version_6_0, File.expand_path("../driver/version_6_0", __FILE__)
62
+ autoload :Version_6_1, File.expand_path("../driver/version_6_1", __FILE__)
62
63
  end
63
64
 
64
65
  module Model
@@ -1,4 +1,5 @@
1
1
  require_relative "../../../errors"
2
+ require_relative "../pip/pip"
2
3
 
3
4
  module VagrantPlugins
4
5
  module Ansible
@@ -7,15 +8,31 @@ module VagrantPlugins
7
8
  module Arch
8
9
  module AnsibleInstall
9
10
 
10
- def self.ansible_install(machine, install_mode, ansible_version, pip_args)
11
- if install_mode != :default
12
- raise Ansible::Errors::AnsiblePipInstallIsNotSupported
11
+ def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
12
+ case install_mode
13
+ when :pip
14
+ pip_setup machine, pip_install_cmd
15
+ Pip::pip_install machine, "ansible", ansible_version, pip_args, true
16
+
17
+ when :pip_args_only
18
+ pip_setup machine, pip_install_cmd
19
+ Pip::pip_install machine, "", "", pip_args, false
20
+
13
21
  else
14
22
  machine.communicate.sudo "pacman -Syy --noconfirm"
15
23
  machine.communicate.sudo "pacman -S --noconfirm ansible"
16
24
  end
17
25
  end
18
26
 
27
+ private
28
+
29
+ def self.pip_setup(machine, pip_install_cmd = "")
30
+ machine.communicate.sudo "pacman -Syy --noconfirm"
31
+ machine.communicate.sudo "pacman -S --noconfirm base-devel curl git python"
32
+
33
+ Pip::get_pip machine, pip_install_cmd
34
+ end
35
+
19
36
  end
20
37
  end
21
38
  end
@@ -7,8 +7,7 @@ module VagrantPlugins
7
7
  module Debian
8
8
  module AnsibleInstall
9
9
 
10
-
11
- def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
10
+ def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
12
11
  case install_mode
13
12
  when :pip
14
13
  pip_setup machine, pip_install_cmd
@@ -33,12 +32,12 @@ INLINE_CRIPT
33
32
 
34
33
  machine.communicate.sudo install_backports_if_wheezy_release
35
34
  machine.communicate.sudo "apt-get update -y -qq"
36
- machine.communicate.sudo "apt-get install -y -qq ansible"
35
+ machine.communicate.sudo "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" ansible"
37
36
  end
38
37
 
39
- def self.pip_setup(machine, pip_install_cmd="")
38
+ def self.pip_setup(machine, pip_install_cmd = "")
40
39
  machine.communicate.sudo "apt-get update -y -qq"
41
- machine.communicate.sudo "apt-get install -y -qq build-essential curl git libssl-dev libffi-dev python-dev"
40
+ machine.communicate.sudo "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --option \"Dpkg::Options::=--force-confold\" build-essential curl git libssl-dev libffi-dev python-dev"
42
41
  Pip::get_pip machine, pip_install_cmd
43
42
  end
44
43
 
@@ -8,7 +8,7 @@ module VagrantPlugins
8
8
  module Fedora
9
9
  module AnsibleInstall
10
10
 
11
- def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
11
+ def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
12
12
  case install_mode
13
13
  when :pip
14
14
  pip_setup machine, pip_install_cmd
@@ -25,7 +25,7 @@ module VagrantPlugins
25
25
 
26
26
  private
27
27
 
28
- def self.pip_setup(machine, pip_install_cmd="")
28
+ def self.pip_setup(machine, pip_install_cmd = "")
29
29
  rpm_package_manager = Facts::rpm_package_manager(machine)
30
30
 
31
31
  machine.communicate.sudo "#{rpm_package_manager} install -y curl gcc gmp-devel libffi-devel openssl-devel python-crypto python-devel python-dnf python-setuptools redhat-rpm-config"
@@ -7,11 +7,11 @@ module VagrantPlugins
7
7
  module FreeBSD
8
8
  module AnsibleInstall
9
9
 
10
- def self.ansible_install(machine, install_mode, ansible_version, pip_args)
10
+ def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
11
11
  if install_mode != :default
12
12
  raise Ansible::Errors::AnsiblePipInstallIsNotSupported
13
13
  else
14
- machine.communicate.sudo "yes | pkg install ansible"
14
+ machine.communicate.sudo "pkg install -qy py36-ansible"
15
15
  end
16
16
  end
17
17
 
@@ -16,19 +16,23 @@ module VagrantPlugins
16
16
  end
17
17
 
18
18
  args_array = [pip_args, upgrade_arg, "#{package}#{version_arg}"]
19
+ args_array.reject! { |a| a.nil? || a.empty? }
19
20
 
20
- machine.communicate.sudo "pip install #{args_array.join(' ')}"
21
+ pip_install = "pip install"
22
+ pip_install += " #{args_array.join(' ')}" unless args_array.empty?
23
+
24
+ machine.communicate.sudo pip_install
21
25
  end
22
26
 
23
- def self.get_pip(machine, pip_install_cmd=DEFAULT_PIP_INSTALL_CMD)
27
+ def self.get_pip(machine, pip_install_cmd = DEFAULT_PIP_INSTALL_CMD)
24
28
  # The objective here is to get pip either by default
25
- # or by the argument passed in. The objective is not
29
+ # or by the argument passed in. The objective is not
26
30
  # to circumvent the pip setup by passing in nothing.
27
31
  # Thus, we stick with the default on an empty string.
28
32
  # Typecast added in the check for safety.
29
33
 
30
34
  if pip_install_cmd.to_s.empty?
31
- pip_install_cmd=DEFAULT_PIP_INSTALL_CMD
35
+ pip_install_cmd = DEFAULT_PIP_INSTALL_CMD
32
36
  end
33
37
 
34
38
  machine.ui.detail I18n.t("vagrant.provisioners.ansible.installing_pip")
@@ -8,7 +8,7 @@ module VagrantPlugins
8
8
  module RedHat
9
9
  module AnsibleInstall
10
10
 
11
- def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
11
+ def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
12
12
  case install_mode
13
13
  when :pip
14
14
  pip_setup machine, pip_install_cmd
@@ -33,7 +33,7 @@ module VagrantPlugins
33
33
  machine.communicate.sudo "#{rpm_package_manager} -y --enablerepo=epel install ansible"
34
34
  end
35
35
 
36
- def self.pip_setup(machine, pip_install_cmd="")
36
+ def self.pip_setup(machine, pip_install_cmd = "")
37
37
  rpm_package_manager = Facts::rpm_package_manager(machine)
38
38
 
39
39
  machine.communicate.sudo("#{rpm_package_manager} -y install curl gcc libffi-devel openssl-devel python-crypto python-devel python-setuptools")
@@ -1,3 +1,4 @@
1
+ require_relative "../../../errors"
1
2
 
2
3
  module VagrantPlugins
3
4
  module Ansible
@@ -6,7 +7,7 @@ module VagrantPlugins
6
7
  module SUSE
7
8
  module AnsibleInstall
8
9
 
9
- def self.ansible_install(machine, install_mode, ansible_version, pip_args)
10
+ def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd = "")
10
11
  if install_mode != :default
11
12
  raise Ansible::Errors::AnsiblePipInstallIsNotSupported
12
13
  else