vagrant-unbundled 2.2.6.2 → 2.2.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (287) hide show
  1. checksums.yaml +4 -4
  2. data/.hashibot.hcl +14 -0
  3. data/CHANGELOG.md +213 -2
  4. data/Gemfile +1 -1
  5. data/README.md +9 -51
  6. data/RELEASE.md +1 -1
  7. data/bin/vagrant +23 -0
  8. data/contrib/README.md +1 -0
  9. data/contrib/bash/completion.sh +13 -1
  10. data/contrib/sudoers/linux-suse +2 -2
  11. data/contrib/zsh/_vagrant +738 -0
  12. data/contrib/zsh/generate_zsh_completion.rb +165 -0
  13. data/lib/vagrant.rb +25 -4
  14. data/lib/vagrant/action.rb +8 -0
  15. data/lib/vagrant/action/builder.rb +184 -38
  16. data/lib/vagrant/action/builtin/box_add.rb +20 -8
  17. data/lib/vagrant/action/builtin/box_check_outdated.rb +12 -15
  18. data/lib/vagrant/action/builtin/cleanup_disks.rb +56 -0
  19. data/lib/vagrant/action/builtin/cloud_init_setup.rb +122 -0
  20. data/lib/vagrant/action/builtin/cloud_init_wait.rb +30 -0
  21. data/lib/vagrant/action/builtin/delayed.rb +26 -0
  22. data/lib/vagrant/action/builtin/disk.rb +52 -0
  23. data/lib/vagrant/action/builtin/handle_box.rb +3 -1
  24. data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +28 -9
  25. data/lib/vagrant/action/builtin/has_provisioner.rb +36 -0
  26. data/lib/vagrant/action/builtin/mixin_provisioners.rb +20 -1
  27. data/lib/vagrant/action/builtin/mixin_synced_folders.rb +20 -21
  28. data/lib/vagrant/action/builtin/set_hostname.rb +5 -1
  29. data/lib/vagrant/action/builtin/ssh_run.rb +21 -3
  30. data/lib/vagrant/action/builtin/synced_folders.rb +16 -0
  31. data/lib/vagrant/action/builtin/trigger.rb +37 -0
  32. data/lib/vagrant/action/hook.rb +76 -23
  33. data/lib/vagrant/action/runner.rb +12 -27
  34. data/lib/vagrant/action/warden.rb +28 -22
  35. data/lib/vagrant/box.rb +11 -4
  36. data/lib/vagrant/box_collection.rb +1 -1
  37. data/lib/vagrant/box_metadata.rb +17 -3
  38. data/lib/vagrant/bundler.rb +298 -59
  39. data/lib/vagrant/cli.rb +4 -2
  40. data/lib/vagrant/errors.rb +61 -1
  41. data/lib/vagrant/machine.rb +64 -11
  42. data/lib/vagrant/machine_index.rb +28 -1
  43. data/lib/vagrant/plugin/manager.rb +25 -14
  44. data/lib/vagrant/plugin/v2/command.rb +7 -2
  45. data/lib/vagrant/plugin/v2/components.rb +6 -0
  46. data/lib/vagrant/plugin/v2/manager.rb +67 -0
  47. data/lib/vagrant/plugin/v2/plugin.rb +13 -0
  48. data/lib/vagrant/plugin/v2/synced_folder.rb +50 -0
  49. data/lib/vagrant/plugin/v2/trigger.rb +64 -25
  50. data/lib/vagrant/shared_helpers.rb +36 -0
  51. data/lib/vagrant/ui.rb +51 -5
  52. data/lib/vagrant/util.rb +1 -0
  53. data/lib/vagrant/util/ansi_escape_code_remover.rb +1 -1
  54. data/lib/vagrant/util/caps.rb +48 -0
  55. data/lib/vagrant/util/credential_scrubber.rb +1 -1
  56. data/lib/vagrant/util/curl_helper.rb +8 -5
  57. data/lib/vagrant/util/directory.rb +19 -0
  58. data/lib/vagrant/util/downloader.rb +10 -5
  59. data/lib/vagrant/util/file_checksum.rb +6 -2
  60. data/lib/vagrant/util/guest_hosts.rb +68 -0
  61. data/lib/vagrant/util/guest_inspection.rb +9 -1
  62. data/lib/vagrant/util/install_cli_autocomplete.rb +118 -0
  63. data/lib/vagrant/util/io.rb +7 -27
  64. data/lib/vagrant/util/ipv4_interfaces.rb +15 -0
  65. data/lib/vagrant/util/is_port_open.rb +8 -20
  66. data/lib/vagrant/util/map_command_options.rb +33 -0
  67. data/lib/vagrant/util/mime.rb +92 -0
  68. data/lib/vagrant/util/network_ip.rb +11 -1
  69. data/lib/vagrant/util/numeric.rb +69 -0
  70. data/lib/vagrant/util/platform.rb +10 -2
  71. data/lib/vagrant/util/powershell.rb +1 -1
  72. data/lib/vagrant/util/subprocess.rb +9 -1
  73. data/lib/vagrant/util/template_renderer.rb +2 -2
  74. data/lib/vagrant/util/uploader.rb +7 -4
  75. data/lib/vagrant/vagrantfile.rb +1 -1
  76. data/plugins/commands/autocomplete/command/install.rb +49 -0
  77. data/plugins/commands/autocomplete/command/root.rb +64 -0
  78. data/plugins/commands/autocomplete/plugin.rb +18 -0
  79. data/plugins/commands/box/command/outdated.rb +14 -2
  80. data/plugins/commands/cap/command.rb +5 -1
  81. data/plugins/commands/cloud/auth/login.rb +20 -23
  82. data/plugins/commands/cloud/auth/logout.rb +2 -10
  83. data/plugins/commands/cloud/auth/middleware/add_downloader_authentication.rb +57 -0
  84. data/plugins/commands/cloud/auth/whoami.rb +18 -20
  85. data/plugins/commands/cloud/box/create.rb +33 -29
  86. data/plugins/commands/cloud/box/delete.rb +30 -24
  87. data/plugins/commands/cloud/box/show.rb +41 -31
  88. data/plugins/commands/cloud/box/update.rb +34 -26
  89. data/plugins/commands/cloud/client/client.rb +50 -81
  90. data/plugins/commands/cloud/list.rb +3 -4
  91. data/plugins/commands/cloud/locales/en.yml +10 -10
  92. data/plugins/commands/cloud/plugin.rb +10 -0
  93. data/plugins/commands/cloud/provider/create.rb +38 -28
  94. data/plugins/commands/cloud/provider/delete.rb +39 -29
  95. data/plugins/commands/cloud/provider/update.rb +37 -28
  96. data/plugins/commands/cloud/provider/upload.rb +44 -34
  97. data/plugins/commands/cloud/publish.rb +185 -108
  98. data/plugins/commands/cloud/search.rb +34 -21
  99. data/plugins/commands/cloud/util.rb +266 -162
  100. data/plugins/commands/cloud/version/create.rb +33 -28
  101. data/plugins/commands/cloud/version/delete.rb +35 -28
  102. data/plugins/commands/cloud/version/release.rb +35 -29
  103. data/plugins/commands/cloud/version/revoke.rb +36 -29
  104. data/plugins/commands/cloud/version/update.rb +29 -25
  105. data/plugins/commands/destroy/command.rb +6 -2
  106. data/plugins/commands/login/plugin.rb +0 -13
  107. data/plugins/commands/snapshot/command/save.rb +13 -8
  108. data/plugins/commands/ssh_config/command.rb +1 -1
  109. data/plugins/communicators/ssh/communicator.rb +25 -24
  110. data/plugins/communicators/winrm/config.rb +1 -1
  111. data/plugins/communicators/winrm/helper.rb +1 -1
  112. data/plugins/communicators/winrm/shell.rb +1 -1
  113. data/plugins/communicators/winssh/communicator.rb +126 -38
  114. data/plugins/communicators/winssh/config.rb +3 -7
  115. data/plugins/guests/alpine/cap/change_host_name.rb +10 -11
  116. data/plugins/guests/alpine/cap/rsync.rb +1 -1
  117. data/plugins/guests/alpine/plugin.rb +16 -0
  118. data/plugins/guests/alt/cap/change_host_name.rb +40 -53
  119. data/plugins/guests/arch/cap/change_host_name.rb +5 -14
  120. data/plugins/guests/arch/cap/configure_networks.rb +27 -10
  121. data/plugins/guests/arch/cap/smb.rb +1 -1
  122. data/plugins/guests/atomic/cap/change_host_name.rb +5 -14
  123. data/plugins/guests/centos/cap/flavor.rb +24 -0
  124. data/plugins/guests/centos/guest.rb +9 -0
  125. data/plugins/guests/centos/plugin.rb +20 -0
  126. data/plugins/guests/darwin/cap/change_host_name.rb +10 -6
  127. data/plugins/guests/darwin/cap/darwin_version.rb +40 -0
  128. data/plugins/guests/darwin/cap/mount_smb_shared_folder.rb +1 -1
  129. data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +109 -13
  130. data/plugins/guests/darwin/plugin.rb +15 -0
  131. data/plugins/guests/debian/cap/change_host_name.rb +12 -11
  132. data/plugins/guests/debian/cap/configure_networks.rb +14 -6
  133. data/plugins/guests/esxi/cap/public_key.rb +3 -1
  134. data/plugins/guests/freebsd/cap/change_host_name.rb +10 -6
  135. data/plugins/guests/gentoo/cap/change_host_name.rb +14 -22
  136. data/plugins/guests/haiku/cap/rsync.rb +19 -0
  137. data/plugins/guests/haiku/plugin.rb +15 -0
  138. data/plugins/guests/linux/cap/change_host_name.rb +46 -0
  139. data/plugins/guests/linux/cap/halt.rb +9 -1
  140. data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +25 -34
  141. data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +10 -11
  142. data/plugins/guests/linux/cap/persist_mount_shared_folder.rb +75 -0
  143. data/plugins/guests/linux/cap/reboot.rb +53 -0
  144. data/plugins/guests/linux/plugin.rb +20 -0
  145. data/plugins/guests/omnios/cap/change_host_name.rb +10 -16
  146. data/plugins/guests/openbsd/cap/change_host_name.rb +10 -6
  147. data/plugins/guests/photon/cap/change_host_name.rb +9 -15
  148. data/plugins/guests/pld/cap/change_host_name.rb +11 -17
  149. data/plugins/guests/redhat/cap/change_host_name.rb +14 -5
  150. data/plugins/guests/redhat/cap/flavor.rb +3 -1
  151. data/plugins/guests/redhat/cap/nfs_client.rb +2 -2
  152. data/plugins/guests/redhat/cap/smb.rb +20 -0
  153. data/plugins/guests/redhat/plugin.rb +5 -0
  154. data/plugins/guests/slackware/cap/change_host_name.rb +11 -17
  155. data/plugins/guests/solaris11/plugin.rb +5 -0
  156. data/plugins/guests/suse/cap/change_host_name.rb +31 -9
  157. data/plugins/guests/windows/cap/public_key.rb +3 -3
  158. data/plugins/guests/windows/cap/reboot.rb +10 -5
  159. data/plugins/hosts/darwin/cap/fs_iso.rb +49 -0
  160. data/plugins/hosts/darwin/cap/nfs.rb +11 -0
  161. data/plugins/hosts/darwin/plugin.rb +15 -0
  162. data/plugins/hosts/linux/cap/fs_iso.rb +49 -0
  163. data/plugins/hosts/linux/cap/nfs.rb +21 -2
  164. data/plugins/hosts/linux/cap/rdp.rb +1 -1
  165. data/plugins/hosts/linux/plugin.rb +10 -0
  166. data/plugins/hosts/windows/cap/fs_iso.rb +48 -0
  167. data/plugins/hosts/windows/cap/rdp.rb +1 -1
  168. data/plugins/hosts/windows/plugin.rb +15 -0
  169. data/plugins/kernel_v2/config/cloud_init.rb +133 -0
  170. data/plugins/kernel_v2/config/disk.rb +221 -0
  171. data/plugins/kernel_v2/config/ssh_connect.rb +24 -0
  172. data/plugins/kernel_v2/config/vm.rb +230 -15
  173. data/plugins/kernel_v2/config/vm_provisioner.rb +17 -3
  174. data/plugins/kernel_v2/config/vm_trigger.rb +6 -5
  175. data/plugins/providers/docker/action.rb +8 -17
  176. data/plugins/providers/docker/action/forwarded_ports.rb +2 -0
  177. data/plugins/providers/docker/action/prepare_forwarded_port_collision_params.rb +61 -0
  178. data/plugins/providers/docker/cap/has_communicator.rb +11 -0
  179. data/plugins/providers/docker/communicator.rb +1 -1
  180. data/plugins/providers/docker/driver.rb +73 -10
  181. data/plugins/providers/docker/errors.rb +4 -0
  182. data/plugins/providers/docker/executor/local.rb +7 -1
  183. data/plugins/providers/docker/plugin.rb +5 -0
  184. data/plugins/providers/hyperv/action.rb +3 -1
  185. data/plugins/providers/hyperv/action/configure.rb +8 -0
  186. data/plugins/providers/hyperv/action/export.rb +4 -2
  187. data/plugins/providers/hyperv/cap/cleanup_disks.rb +54 -0
  188. data/plugins/providers/hyperv/cap/configure_disks.rb +200 -0
  189. data/plugins/providers/hyperv/cap/validate_disk_ext.rb +34 -0
  190. data/plugins/providers/hyperv/config.rb +5 -0
  191. data/plugins/providers/hyperv/driver.rb +90 -9
  192. data/plugins/providers/hyperv/plugin.rb +25 -0
  193. data/plugins/providers/hyperv/scripts/attach_disk_drive.ps1 +28 -0
  194. data/plugins/providers/hyperv/scripts/dismount_vhd.ps1 +13 -0
  195. data/plugins/providers/hyperv/scripts/get_vhd.ps1 +16 -0
  196. data/plugins/providers/hyperv/scripts/get_vm_status.ps1 +1 -1
  197. data/plugins/providers/hyperv/scripts/list_hdds.ps1 +17 -0
  198. data/plugins/providers/hyperv/scripts/new_vhd.ps1 +31 -0
  199. data/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 +25 -0
  200. data/plugins/providers/hyperv/scripts/resize_disk_drive.ps1 +18 -0
  201. data/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +24 -0
  202. data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +3 -3
  203. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +14 -6
  204. data/plugins/providers/virtualbox/action.rb +14 -1
  205. data/plugins/providers/virtualbox/action/clean_machine_folder.rb +10 -1
  206. data/plugins/providers/virtualbox/action/export.rb +4 -2
  207. data/plugins/providers/virtualbox/action/forward_ports.rb +2 -2
  208. data/plugins/providers/virtualbox/action/import.rb +8 -4
  209. data/plugins/providers/virtualbox/action/prepare_clone_snapshot.rb +4 -2
  210. data/plugins/providers/virtualbox/action/snapshot_delete.rb +4 -2
  211. data/plugins/providers/virtualbox/action/snapshot_restore.rb +4 -2
  212. data/plugins/providers/virtualbox/cap/cleanup_disks.rb +85 -0
  213. data/plugins/providers/virtualbox/cap/configure_disks.rb +440 -0
  214. data/plugins/providers/virtualbox/cap/mount_options.rb +35 -0
  215. data/plugins/providers/virtualbox/cap/validate_disk_ext.rb +34 -0
  216. data/plugins/providers/virtualbox/driver/base.rb +15 -0
  217. data/plugins/providers/virtualbox/driver/meta.rb +17 -2
  218. data/plugins/providers/virtualbox/driver/version_5_0.rb +217 -2
  219. data/plugins/providers/virtualbox/driver/version_6_1.rb +39 -0
  220. data/plugins/providers/virtualbox/model/storage_controller.rb +135 -0
  221. data/plugins/providers/virtualbox/model/storage_controller_array.rb +98 -0
  222. data/plugins/providers/virtualbox/plugin.rb +38 -0
  223. data/plugins/providers/virtualbox/provider.rb +2 -1
  224. data/plugins/providers/virtualbox/synced_folder.rb +1 -0
  225. data/plugins/provisioners/ansible/cap/guest/alpine/ansible_install.rb +44 -0
  226. data/plugins/provisioners/ansible/cap/guest/arch/ansible_install.rb +20 -3
  227. data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +4 -5
  228. data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +2 -2
  229. data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +2 -2
  230. data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +8 -4
  231. data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +2 -2
  232. data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +2 -1
  233. data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
  234. data/plugins/provisioners/ansible/plugin.rb +5 -0
  235. data/plugins/provisioners/ansible/provisioner/base.rb +1 -1
  236. data/plugins/provisioners/container/client.rb +203 -0
  237. data/plugins/provisioners/container/config.rb +83 -0
  238. data/plugins/provisioners/container/installer.rb +13 -0
  239. data/plugins/provisioners/container/plugin.rb +23 -0
  240. data/plugins/provisioners/container/provisioner.rb +28 -0
  241. data/plugins/provisioners/docker/cap/{redhat → centos}/docker_install.rb +10 -7
  242. data/plugins/provisioners/docker/cap/centos/docker_start_service.rb +24 -0
  243. data/plugins/provisioners/docker/client.rb +4 -175
  244. data/plugins/provisioners/docker/config.rb +2 -72
  245. data/plugins/provisioners/docker/installer.rb +3 -5
  246. data/plugins/provisioners/docker/plugin.rb +6 -6
  247. data/plugins/provisioners/docker/provisioner.rb +4 -10
  248. data/plugins/provisioners/podman/cap/centos/podman_install.rb +35 -0
  249. data/plugins/provisioners/podman/cap/linux/podman_installed.rb +13 -0
  250. data/plugins/provisioners/podman/cap/redhat/podman_install.rb +26 -0
  251. data/plugins/provisioners/podman/client.rb +12 -0
  252. data/plugins/provisioners/podman/config.rb +28 -0
  253. data/plugins/provisioners/podman/installer.rb +33 -0
  254. data/plugins/provisioners/podman/plugin.rb +38 -0
  255. data/plugins/provisioners/podman/provisioner.rb +52 -0
  256. data/plugins/provisioners/salt/provisioner.rb +4 -0
  257. data/plugins/provisioners/shell/config.rb +1 -6
  258. data/plugins/provisioners/shell/provisioner.rb +61 -26
  259. data/plugins/synced_folders/nfs/synced_folder.rb +3 -1
  260. data/plugins/synced_folders/smb/cap/default_fstab_modification.rb +11 -0
  261. data/plugins/synced_folders/smb/cap/mount_options.rb +56 -0
  262. data/plugins/synced_folders/smb/plugin.rb +20 -0
  263. data/plugins/synced_folders/smb/synced_folder.rb +2 -2
  264. data/plugins/synced_folders/unix_mount_helpers.rb +14 -0
  265. data/scripts/website_push_www.sh +1 -1
  266. data/templates/commands/init/Vagrantfile.erb +1 -1
  267. data/templates/guests/arch/{network_dhcp.erb → default_network/network_dhcp.erb} +0 -0
  268. data/templates/guests/arch/{network_static.erb → default_network/network_static.erb} +0 -0
  269. data/templates/guests/arch/{network_static6.erb → default_network/network_static6.erb} +0 -0
  270. data/templates/guests/arch/systemd_networkd/network_dhcp.erb +6 -0
  271. data/templates/guests/arch/systemd_networkd/network_static.erb +9 -0
  272. data/templates/guests/arch/systemd_networkd/network_static6.erb +9 -0
  273. data/templates/guests/linux/etc_fstab.erb +6 -0
  274. data/templates/locales/en.yml +235 -6
  275. data/templates/locales/providers_docker.yml +6 -0
  276. data/templates/nfs/exports_darwin.erb +7 -0
  277. data/vagrant.gemspec +14 -15
  278. data/version.txt +1 -1
  279. metadata +3577 -3855
  280. data/lib/vagrant/action/builtin/after_trigger.rb +0 -31
  281. data/lib/vagrant/action/builtin/before_trigger.rb +0 -28
  282. data/plugins/commands/login/client.rb +0 -253
  283. data/plugins/commands/login/command.rb +0 -137
  284. data/plugins/commands/login/errors.rb +0 -24
  285. data/plugins/commands/login/locales/en.yml +0 -49
  286. data/plugins/provisioners/docker/cap/redhat/docker_start_service.rb +0 -16
  287. data/scripts/website_push_docs.sh +0 -40
@@ -0,0 +1,165 @@
1
+ require 'open3'
2
+
3
+ HEAD = """#compdef _vagrant vagrant
4
+
5
+ # ZSH completion for Vagrant
6
+ #
7
+ # To use this completion add this to ~/.zshrc
8
+ # fpath=(/path/to/this/dir $fpath)
9
+ # compinit
10
+ #
11
+ # For development reload the function after making changes
12
+ # unfunction _vagrant && autoload -U _vagrant
13
+ """
14
+
15
+ BOX_LIST_FUNCTION = """
16
+ __box_list ()
17
+ {
18
+ _wanted application expl 'command' compadd $(command vagrant box list | awk '{print $1}' )
19
+ }
20
+ """
21
+
22
+ PLUGIN_LIST_FUNCTION = """
23
+ __plugin_list ()
24
+ {
25
+ _wanted application expl 'command' compadd $(command vagrant plugin list | awk '{print $1}')
26
+ }
27
+ """
28
+
29
+ ADD_FEATURE_FLAGS = ["remove", "repackage", "update", "repair", "uninstall"]
30
+ VAGRANT_COMMAND = "vagrant"
31
+
32
+ FLAG_REGEX = /--(\S)*/
33
+ CMDS_REGEX = /^(\s){1,}(\w)(\S)*/
34
+
35
+ def make_string_script_safe(s)
36
+ s.gsub("[","(").gsub("]",")").gsub("-","_").gsub("'", "")
37
+ end
38
+
39
+ def remove_square_brakets(s)
40
+ s.gsub("[","(").gsub("]",")")
41
+ end
42
+
43
+ def format_flags(group_name, flags)
44
+ group_name = make_string_script_safe(group_name)
45
+ opts_str = "local -a #{group_name} && #{group_name}=(\n"
46
+ flags.each do |flag, desc|
47
+ opts_str = opts_str + " '#{remove_square_brakets(flag)}=[#{make_string_script_safe(desc)}]'\n"
48
+ end
49
+ opts_str + ")"
50
+ end
51
+
52
+ def format_subcommand(group_name, cmds)
53
+ opts_str = "local -a #{group_name} && #{group_name}=(\n"
54
+ cmds.each do |cmd, desc|
55
+ opts_str = opts_str + " '#{cmd}:#{desc}'\n"
56
+ end
57
+ opts_str + ")"
58
+ end
59
+
60
+ def format_case(group_name, cmds, cmd_list, feature_string)
61
+ case_str = """case $state in
62
+ (command)
63
+ _describe -t commands 'command' #{group_name}
64
+ return
65
+ ;;
66
+
67
+ (options)
68
+ case $line[1] in
69
+ """
70
+
71
+ cmds.each do |cmd, desc|
72
+ if cmd_list.include?(cmd)
73
+ case_append = """ #{cmd})
74
+ _arguments -s -S : $#{make_string_script_safe(cmd)}_arguments #{feature_string if ADD_FEATURE_FLAGS.include?(cmd)} ;;
75
+ """
76
+ else
77
+ case_append = """ #{cmd})
78
+ __vagrant-#{cmd} ;;
79
+ """
80
+ end
81
+ case_str = case_str + case_append
82
+ end
83
+
84
+ case_str = case_str + """esac
85
+ ;;
86
+ esac
87
+ """
88
+ end
89
+
90
+ def extract_flags(top_level_commands)
91
+ flags = top_level_commands.map { |c| [c.match(FLAG_REGEX)[0], c.split(" ")[-1].strip] if c.strip.start_with?("--") }.compact
92
+ end
93
+
94
+ def extract_subcommand(top_level_commands)
95
+ cmds = top_level_commands.map { |c| [c.match(CMDS_REGEX)[0].strip, c.split(" ")[-1].strip] if c.match(CMDS_REGEX) }.compact
96
+ end
97
+
98
+ def get_top_level_commands(root_command, cmd_list)
99
+ stdout, stderr, status = Open3.capture3("vagrant #{root_command} -h")
100
+ top_level_commands = stdout.split("\n")
101
+
102
+ root_subcommand = extract_subcommand(top_level_commands)
103
+ commands = format_subcommand("sub_commands", root_subcommand)
104
+ if root_command == "box"
105
+ feature_string = "':feature:__box_list'"
106
+ elsif root_command == "plugin"
107
+ feature_string = "':feature:__plugin_list'"
108
+ else
109
+ feature_string = ""
110
+ end
111
+ case_string = format_case("sub_commands", root_subcommand, cmd_list, feature_string)
112
+
113
+ flags_def = ""
114
+ root_subcommand.each do |cmd, desc|
115
+ next if !cmd_list.include?(cmd)
116
+ stdout, stderr, status = Open3.capture3("vagrant #{root_command} #{cmd} -h")
117
+ cmd_help = stdout.split("\n")
118
+ flags_def = flags_def + format_flags("#{cmd}_arguments", extract_flags(cmd_help)) + "\n\n"
119
+ end
120
+
121
+ return commands, flags_def, case_string
122
+ end
123
+
124
+ def format_script(root_command, subcommands, funciton_name)
125
+ top_level_commands, top_level_args, state_case = get_top_level_commands(root_command, subcommands)
126
+
127
+ script = """
128
+ function #{funciton_name} () {
129
+
130
+ #{top_level_commands}
131
+
132
+ #{top_level_args}
133
+
134
+ _arguments -C ':command:->command' '*::options:->options'
135
+
136
+ #{state_case}
137
+ }
138
+ """
139
+ end
140
+
141
+ def generate_script
142
+ subcommand_list = {
143
+ "" => ["cloud", "destroy", "global-status", "halt", "help", "login", "init", "package", "port", "powershell", "provision", "push", "rdp", "reload", "resume", "ssh", "ssh-config", "status", "suspend", "up", "upload", "validate", "version", "winrm", "winrm-config"],
144
+ "box" => ["add", "list", "outdated", "prune", "remove", "repackage", "update"],
145
+ "snapshot" => ["delete", "list", "pop", "push", "restore", "save"],
146
+ "plugin" => ["install", "expunge", "license", "list", "repair", "uninstall", "update"],
147
+ }
148
+
149
+ script = """#{HEAD}
150
+ #{BOX_LIST_FUNCTION}
151
+ #{PLUGIN_LIST_FUNCTION}
152
+ """
153
+
154
+ subcommand_list.each do |cmd, opts|
155
+ if cmd != ""
156
+ function_name = "__vagrant-#{cmd}"
157
+ else
158
+ function_name = "_vagrant"
159
+ end
160
+ script = script + format_script(cmd, opts, function_name)
161
+ end
162
+ script
163
+ end
164
+
165
+ puts generate_script
@@ -9,6 +9,31 @@ class Log4r::BasicFormatter
9
9
  end
10
10
  end
11
11
 
12
+
13
+ require "optparse"
14
+
15
+ module Vagrant
16
+ # This is a customized OptionParser for Vagrant plugins. It
17
+ # will automatically add any default CLI options defined
18
+ # outside of command implementations to the local option
19
+ # parser instances in use
20
+ class OptionParser < ::OptionParser
21
+ def initialize(*_)
22
+ super
23
+ Vagrant.default_cli_options.each do |opt_proc|
24
+ opt_proc.call(self)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ # Inject the option parser into the vagrant plugins
31
+ # module so it is automatically used when defining
32
+ # command options
33
+ module VagrantPlugins
34
+ OptionParser = Vagrant::OptionParser
35
+ end
36
+
12
37
  require "vagrant/shared_helpers"
13
38
  require "rubygems"
14
39
  require "vagrant/util"
@@ -68,10 +93,6 @@ if ENV["VAGRANT_LOG"] && ENV["VAGRANT_LOG"] != ""
68
93
  date_pattern: "%F %T"
69
94
  )
70
95
  end
71
- # Vagrant Cloud gem uses RestClient to make HTTP requests, so
72
- # log them if debug is enabled and use Vagrants logger
73
- require 'rest_client'
74
- RestClient.log = logger
75
96
 
76
97
  Log4r::Outputter.stderr.formatter = Vagrant::Util::LoggingFormatter.new(base_formatter)
77
98
  logger = nil
@@ -2,6 +2,7 @@ require 'vagrant/action/builder'
2
2
 
3
3
  module Vagrant
4
4
  module Action
5
+ autoload :Hook, 'vagrant/action/hook'
5
6
  autoload :Runner, 'vagrant/action/runner'
6
7
  autoload :Warden, 'vagrant/action/warden'
7
8
 
@@ -12,14 +13,20 @@ module Vagrant
12
13
  autoload :BoxCheckOutdated, "vagrant/action/builtin/box_check_outdated"
13
14
  autoload :BoxRemove, "vagrant/action/builtin/box_remove"
14
15
  autoload :Call, "vagrant/action/builtin/call"
16
+ autoload :CleanupDisks, "vagrant/action/builtin/cleanup_disks"
17
+ autoload :CloudInitSetup, "vagrant/action/builtin/cloud_init_setup"
18
+ autoload :CloudInitWait, "vagrant/action/builtin/cloud_init_wait"
15
19
  autoload :Confirm, "vagrant/action/builtin/confirm"
16
20
  autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
21
+ autoload :Delayed, "vagrant/action/builtin/delayed"
17
22
  autoload :DestroyConfirm, "vagrant/action/builtin/destroy_confirm"
23
+ autoload :Disk, "vagrant/action/builtin/disk"
18
24
  autoload :EnvSet, "vagrant/action/builtin/env_set"
19
25
  autoload :GracefulHalt, "vagrant/action/builtin/graceful_halt"
20
26
  autoload :HandleBox, "vagrant/action/builtin/handle_box"
21
27
  autoload :HandleBoxUrl, "vagrant/action/builtin/handle_box_url"
22
28
  autoload :HandleForwardedPortCollisions, "vagrant/action/builtin/handle_forwarded_port_collisions"
29
+ autoload :HasProvisioner, "vagrant/action/builtin/has_provisioner"
23
30
  autoload :IsEnvSet, "vagrant/action/builtin/is_env_set"
24
31
  autoload :IsState, "vagrant/action/builtin/is_state"
25
32
  autoload :Lock, "vagrant/action/builtin/lock"
@@ -32,6 +39,7 @@ module Vagrant
32
39
  autoload :SSHRun, "vagrant/action/builtin/ssh_run"
33
40
  autoload :SyncedFolders, "vagrant/action/builtin/synced_folders"
34
41
  autoload :SyncedFolderCleanup, "vagrant/action/builtin/synced_folder_cleanup"
42
+ autoload :Trigger, "vagrant/action/builtin/trigger"
35
43
  autoload :WaitForCommunicator, "vagrant/action/builtin/wait_for_communicator"
36
44
  end
37
45
 
@@ -17,6 +17,11 @@ module Vagrant
17
17
  # Vagrant::Action.run(app)
18
18
  #
19
19
  class Builder
20
+ # Container for Action arguments
21
+ MiddlewareArguments = Struct.new(:parameters, :block, :keywords, keyword_init: true)
22
+ # Item within the stack
23
+ StackItem = Struct.new(:middleware, :arguments, keyword_init: true)
24
+
20
25
  # This is the stack of middlewares added. This should NOT be used
21
26
  # directly.
22
27
  #
@@ -28,8 +33,8 @@ module Vagrant
28
33
  # see {#use} instead.
29
34
  #
30
35
  # @return [Builder]
31
- def self.build(middleware, *args, &block)
32
- new.use(middleware, *args, &block)
36
+ def self.build(middleware, *args, **keywords, &block)
37
+ new.use(middleware, *args, **keywords, &block)
33
38
  end
34
39
 
35
40
  def initialize
@@ -58,12 +63,21 @@ module Vagrant
58
63
  # of the middleware.
59
64
  #
60
65
  # @param [Class] middleware The middleware class
61
- def use(middleware, *args, &block)
66
+ def use(middleware, *args, **keywords, &block)
67
+ item = StackItem.new(
68
+ middleware: middleware,
69
+ arguments: MiddlewareArguments.new(
70
+ parameters: args,
71
+ keywords: keywords,
72
+ block: block
73
+ )
74
+ )
75
+
62
76
  if middleware.kind_of?(Builder)
63
77
  # Merge in the other builder's stack into our own
64
78
  self.stack.concat(middleware.stack)
65
79
  else
66
- self.stack << [middleware, args, block]
80
+ self.stack << item
67
81
  end
68
82
 
69
83
  self
@@ -71,8 +85,22 @@ module Vagrant
71
85
 
72
86
  # Inserts a middleware at the given index or directly before the
73
87
  # given middleware object.
74
- def insert(index, middleware, *args, &block)
75
- index = self.index(index) unless index.is_a?(Integer)
88
+ def insert(idx_or_item, middleware, *args, **keywords, &block)
89
+ item = StackItem.new(
90
+ middleware: middleware,
91
+ arguments: MiddlewareArguments.new(
92
+ parameters: args,
93
+ keywords: keywords,
94
+ block: block
95
+ )
96
+ )
97
+
98
+ if idx_or_item.is_a?(Integer)
99
+ index = idx_or_item
100
+ else
101
+ index = self.index(idx_or_item)
102
+ end
103
+
76
104
  raise "no such middleware to insert before: #{index.inspect}" unless index
77
105
 
78
106
  if middleware.kind_of?(Builder)
@@ -80,27 +108,32 @@ module Vagrant
80
108
  stack.insert(index, stack_item)
81
109
  end
82
110
  else
83
- stack.insert(index, [middleware, args, block])
111
+ stack.insert(index, item)
84
112
  end
85
113
  end
86
114
 
87
115
  alias_method :insert_before, :insert
88
116
 
89
117
  # Inserts a middleware after the given index or middleware object.
90
- def insert_after(index, middleware, *args, &block)
91
- index = self.index(index) unless index.is_a?(Integer)
118
+ def insert_after(idx_or_item, middleware, *args, **keywords, &block)
119
+ if idx_or_item.is_a?(Integer)
120
+ index = idx_or_item
121
+ else
122
+ index = self.index(idx_or_item)
123
+ end
124
+
92
125
  raise "no such middleware to insert after: #{index.inspect}" unless index
93
126
  insert(index + 1, middleware, *args, &block)
94
127
  end
95
128
 
96
129
  # Replaces the given middlware object or index with the new
97
130
  # middleware.
98
- def replace(index, middleware, *args, &block)
131
+ def replace(index, middleware, *args, **keywords, &block)
99
132
  if index.is_a?(Integer)
100
133
  delete(index)
101
- insert(index, middleware, *args, &block)
134
+ insert(index, middleware, *args, **keywords, &block)
102
135
  else
103
- insert_before(index, middleware, *args, &block)
136
+ insert_before(index, middleware, *args, **keywords, &block)
104
137
  delete(index)
105
138
  end
106
139
  end
@@ -122,8 +155,10 @@ module Vagrant
122
155
  # @return [Integer]
123
156
  def index(object)
124
157
  stack.each_with_index do |item, i|
125
- return i if item[0] == object
126
- return i if item[0].respond_to?(:name) && item[0].name == object
158
+ return i if item == object
159
+ return i if item.middleware == object
160
+ return i if item.middleware.respond_to?(:name) &&
161
+ item.middleware.name == object
127
162
  end
128
163
 
129
164
  nil
@@ -132,42 +167,153 @@ module Vagrant
132
167
  # Converts the builder stack to a runnable action sequence.
133
168
  #
134
169
  # @param [Hash] env The action environment hash
135
- # @return [Object] A callable object
170
+ # @return [Warden] A callable object
136
171
  def to_app(env)
137
- app_stack = nil
172
+ # Start with a duplicate of ourself which can
173
+ # be modified
174
+ builder = self.dup
175
+
176
+ # Apply all dynamic modifications of the stack. This
177
+ # will generate dynamic hooks for all actions within
178
+ # the stack, load any triggers for action classes, and
179
+ # apply them to the builder's stack
180
+ builder.apply_dynamic_updates(env)
181
+
182
+ # Now that the stack is fully expanded, apply any
183
+ # action hooks that may be defined so they are on
184
+ # the outermost locations of the stack
185
+ builder.apply_action_name(env)
186
+
187
+ # Wrap the middleware stack with the Warden to provide a consistent
188
+ # and predictable behavior upon exceptions.
189
+ Warden.new(builder.stack.dup, env)
190
+ end
191
+
192
+ # Find any action hooks or triggers which have been defined
193
+ # for items within the stack. Update the stack with any
194
+ # hooks or triggers found.
195
+ #
196
+ # @param [Hash] env Call environment
197
+ # @return [Builder] self
198
+ def apply_dynamic_updates(env)
199
+ if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
200
+ triggers = env[:triggers]
201
+ end
202
+
203
+ # Use a Hook as a convenient interface for injecting
204
+ # any applicable trigger actions within the stack
205
+ machine_name = env[:machine].name if env[:machine]
206
+
207
+ # Iterate over all items in the stack and apply new items
208
+ # into the hook as they are found. Must be sure to dup the
209
+ # stack here since we are modifying the stack in the loop.
210
+ stack.dup.each do |item|
211
+ hook = Hook.new
212
+
213
+ action = item.first
214
+ next if action.is_a?(Proc)
215
+
216
+ # Start with adding any action triggers that may be defined
217
+ if triggers && !triggers.find(action, :before, machine_name, :action).empty?
218
+ hook.prepend(Vagrant::Action::Builtin::Trigger,
219
+ action.name, triggers, :before, :action)
220
+ end
221
+
222
+ if triggers && !triggers.find(action, :after, machine_name, :action).empty?
223
+ hook.append(Vagrant::Action::Builtin::Trigger,
224
+ action.name, triggers, :after, :action)
225
+ end
138
226
 
139
- # If we have action hooks, then we apply them
140
- if env[:action_hooks]
141
- builder = self.dup
227
+ # Next look for any hook triggers that may be defined against
228
+ # the dynamically generated action class hooks
229
+ if triggers && !triggers.find(action, :before, machine_name, :hook).empty?
230
+ hook.prepend(Vagrant::Action::Builtin::Trigger,
231
+ action.name, triggers, :before, :hook)
232
+ end
142
233
 
143
- # These are the options to pass into hook application.
144
- options = {}
234
+ if triggers && !triggers.find(action, :after, machine_name, :hook).empty?
235
+ hook.append(Vagrant::Action::Builtin::Trigger,
236
+ action.name, triggers, :after, :hook)
237
+ end
145
238
 
146
- # If we already ran through once and did append/prepends,
147
- # then don't do it again.
148
- if env[:action_hooks_already_ran]
149
- options[:no_prepend_or_append] = true
239
+ # Finally load any registered hooks for dynamically generated
240
+ # action class based hooks
241
+ Vagrant.plugin("2").manager.find_action_hooks(action).each do |hook_proc|
242
+ hook_proc.call(hook)
150
243
  end
151
244
 
152
- # Specify that we already ran, so in the future we don't repeat
153
- # the prepend/append hooks.
154
- env[:action_hooks_already_ran] = true
245
+ hook.apply(self, root: item)
246
+ end
247
+
248
+ # Apply the hook to ourself to update the stack
249
+ self
250
+ end
251
+
252
+ # If action hooks have not already been set, this method
253
+ # will perform three tasks:
254
+ # 1. Load any hook triggers defined for the action_name
255
+ # 2. Load any action_hooks defined from plugins
256
+ # 3. Load any action triggers based on machine action called (not action classes)
257
+ #
258
+ # @param [Hash] env Call environment
259
+ # @return [Builder]
260
+ def apply_action_name(env)
261
+ env[:builder_raw_applied] ||= []
262
+ return self if !env[:action_name]
263
+
264
+ hook = Hook.new
265
+ machine_name = env[:machine].name if env[:machine]
155
266
 
156
- # Apply all the hooks to the new builder instance
157
- env[:action_hooks].each do |hook|
158
- hook.apply(builder, options)
267
+ # Start with loading any hook triggers if applicable
268
+ if Vagrant::Util::Experimental.feature_enabled?("typed_triggers") && env[:triggers]
269
+ if !env[:triggers].find(env[:action_name], :before, machine_name, :hook).empty?
270
+ hook.prepend(Vagrant::Action::Builtin::Trigger,
271
+ env[:action_name], env[:triggers], :before, :hook)
272
+ end
273
+ if !env[:triggers].find(env[:action_name], :after, machine_name, :hook).empty?
274
+ hook.append(Vagrant::Action::Builtin::Trigger,
275
+ env[:action_name], env[:triggers], :after, :hook)
159
276
  end
277
+ end
160
278
 
161
- # The stack is now the result of the new builder
162
- app_stack = builder.stack.dup
279
+ # Next we load up all the action hooks that plugins may
280
+ # have defined
281
+ action_hooks = Vagrant.plugin("2").manager.action_hooks(env[:action_name])
282
+ action_hooks.each do |hook_proc|
283
+ hook_proc.call(hook)
163
284
  end
164
285
 
165
- # If we don't have a stack then default to using our own
166
- app_stack ||= stack.dup
286
+ # Finally load any action triggers defined. The action triggers
287
+ # are the originally implemented trigger style. They run before
288
+ # and after specific provider actions (like :up, :halt, etc) and
289
+ # are different from true action triggers
290
+ if env[:triggers] && !env[:builder_raw_applied].include?(env[:raw_action_name])
291
+ env[:builder_raw_applied] << env[:raw_action_name]
167
292
 
168
- # Wrap the middleware stack with the Warden to provide a consistent
169
- # and predictable behavior upon exceptions.
170
- Warden.new(app_stack, env)
293
+ if !env[:triggers].find(env[:raw_action_name], :before, machine_name, :action, all: true).empty?
294
+ hook.prepend(Vagrant::Action::Builtin::Trigger,
295
+ env[:raw_action_name], env[:triggers], :before, :action, all: true)
296
+ end
297
+ if !env[:triggers].find(env[:raw_action_name], :after, machine_name, :action, all: true).empty?
298
+ # NOTE: These after triggers need to be delayed before running to
299
+ # allow the rest of the call stack to complete before being
300
+ # run. The delayed action is prepended to the stack (not appended)
301
+ # to ensure it is called first, which results in it properly
302
+ # waiting for everything to finish before itself completing.
303
+ builder = self.class.build(Vagrant::Action::Builtin::Trigger,
304
+ env[:raw_action_name], env[:triggers], :after, :action, all: true)
305
+ hook.prepend(Vagrant::Action::Builtin::Delayed, builder)
306
+ end
307
+ end
308
+
309
+ # If the hooks are empty, then there was nothing to apply and
310
+ # we can just send ourself back
311
+ return self if hook.empty?
312
+
313
+ # Apply all the hooks to the new builder instance
314
+ hook.apply(self)
315
+
316
+ self
171
317
  end
172
318
  end
173
319
  end