vagrant-unbundled 1.9.1.1 → 1.9.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +126 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/bin/vagrant +11 -0
- data/contrib/bash/completion.sh +9 -9
- data/lib/vagrant.rb +4 -2
- data/lib/vagrant/action/builtin/box_add.rb +13 -8
- data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +67 -14
- data/lib/vagrant/action/builtin/provision.rb +10 -5
- data/lib/vagrant/action/general/package_setup_files.rb +51 -0
- data/lib/vagrant/action/general/package_setup_folders.rb +37 -0
- data/lib/vagrant/batch_action.rb +4 -2
- data/lib/vagrant/box_collection.rb +17 -5
- data/lib/vagrant/bundler.rb +110 -12
- data/lib/vagrant/cli.rb +1 -1
- data/lib/vagrant/environment.rb +4 -4
- data/lib/vagrant/errors.rb +32 -0
- data/lib/vagrant/shared_helpers.rb +14 -0
- data/lib/vagrant/ui.rb +3 -3
- data/lib/vagrant/util.rb +7 -1
- data/lib/vagrant/util/command_deprecation.rb +56 -0
- data/lib/vagrant/util/credential_scrubber.rb +29 -0
- data/lib/vagrant/util/guest_inspection.rb +47 -0
- data/lib/vagrant/util/platform.rb +217 -27
- data/lib/vagrant/util/powershell.rb +25 -0
- data/lib/vagrant/util/safe_exec.rb +9 -1
- data/lib/vagrant/util/ssh.rb +1 -1
- data/lib/vagrant/util/subprocess.rb +21 -2
- data/lib/vagrant/util/which.rb +6 -4
- data/plugins/commands/box/command/list.rb +1 -1
- data/plugins/commands/package/command.rb +3 -2
- data/plugins/commands/plugin/action.rb +2 -1
- data/plugins/commands/plugin/action/expunge_plugins.rb +20 -5
- data/plugins/commands/plugin/action/install_gem.rb +0 -8
- data/plugins/commands/plugin/command/expunge.rb +18 -5
- data/plugins/commands/plugin/command/mixin_install_opts.rb +1 -4
- data/plugins/commands/plugin/gem_helper.rb +5 -1
- data/plugins/commands/up/command.rb +1 -1
- data/plugins/commands/validate/command.rb +31 -0
- data/plugins/commands/validate/plugin.rb +17 -0
- data/plugins/communicators/ssh/communicator.rb +50 -25
- data/plugins/communicators/winrm/communicator.rb +8 -54
- data/plugins/communicators/winrm/config.rb +3 -0
- data/plugins/communicators/winrm/helper.rb +1 -1
- data/plugins/communicators/winrm/shell.rb +38 -32
- data/plugins/communicators/winssh/communicator.rb +161 -0
- data/plugins/communicators/winssh/config.rb +30 -0
- data/plugins/communicators/winssh/plugin.rb +21 -0
- data/plugins/guests/arch/cap/change_host_name.rb +0 -3
- data/plugins/guests/arch/cap/configure_networks.rb +1 -1
- data/plugins/guests/atomic/cap/change_host_name.rb +0 -3
- data/plugins/guests/darwin/cap/change_host_name.rb +0 -4
- data/plugins/guests/debian/cap/change_host_name.rb +0 -3
- data/plugins/guests/debian/cap/configure_networks.rb +2 -1
- data/plugins/guests/elementary/guest.rb +10 -0
- data/plugins/guests/elementary/plugin.rb +15 -0
- data/plugins/guests/esxi/cap/public_key.rb +63 -0
- data/plugins/guests/esxi/plugin.rb +11 -0
- data/plugins/guests/freebsd/cap/change_host_name.rb +0 -4
- data/plugins/guests/gentoo/cap/change_host_name.rb +7 -5
- data/plugins/guests/gentoo/cap/configure_networks.rb +57 -21
- data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +20 -53
- data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +10 -58
- data/plugins/guests/linux/cap/network_interfaces.rb +8 -1
- data/plugins/guests/linux/cap/nfs.rb +5 -14
- data/plugins/guests/linux/guest.rb +3 -3
- data/plugins/guests/omnios/cap/change_host_name.rb +0 -3
- data/plugins/guests/openbsd/cap/change_host_name.rb +0 -4
- data/plugins/guests/photon/cap/change_host_name.rb +0 -3
- data/plugins/guests/pld/cap/change_host_name.rb +0 -3
- data/plugins/guests/redhat/cap/change_host_name.rb +2 -9
- data/plugins/guests/redhat/cap/configure_networks.rb +43 -21
- data/plugins/guests/slackware/cap/change_host_name.rb +0 -3
- data/plugins/guests/suse/cap/change_host_name.rb +0 -3
- data/plugins/guests/tinycore/cap/mount_nfs.rb +3 -8
- data/plugins/guests/windows/cap/configure_networks.rb +0 -4
- data/plugins/guests/windows/cap/mount_shared_folder.rb +13 -1
- data/plugins/guests/windows/scripts/mount_volume.ps1.erb +1 -1
- data/plugins/hosts/windows/cap/ps.rb +6 -1
- data/plugins/kernel_v2/config/vm.rb +6 -4
- data/plugins/providers/docker/action.rb +4 -7
- data/plugins/providers/docker/action/build.rb +1 -1
- data/plugins/providers/docker/action/create.rb +3 -0
- data/plugins/providers/docker/config.rb +27 -1
- data/plugins/providers/docker/driver.rb +15 -2
- data/plugins/providers/docker/driver/compose.rb +287 -0
- data/plugins/providers/docker/errors.rb +16 -0
- data/plugins/providers/docker/provider.rb +25 -10
- data/plugins/providers/hyperv/action.rb +33 -8
- data/plugins/providers/hyperv/action/export.rb +39 -0
- data/plugins/providers/hyperv/action/import.rb +23 -4
- data/plugins/providers/hyperv/action/package.rb +16 -0
- data/plugins/providers/hyperv/action/package_metadata_json.rb +34 -0
- data/plugins/providers/hyperv/action/package_setup_files.rb +16 -0
- data/plugins/providers/hyperv/action/package_setup_folders.rb +18 -0
- data/plugins/providers/hyperv/action/package_vagrantfile.rb +34 -0
- data/plugins/providers/hyperv/config.rb +20 -4
- data/plugins/providers/hyperv/driver.rb +12 -0
- data/plugins/providers/hyperv/scripts/export_vm.ps1 +15 -0
- data/plugins/providers/hyperv/scripts/get_network_mac.ps1 +28 -0
- data/plugins/providers/hyperv/scripts/has_vmcx_support.ps1 +11 -0
- data/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 +10 -4
- data/plugins/providers/hyperv/scripts/import_vm_xml.ps1 +9 -3
- data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +37 -0
- data/plugins/providers/virtualbox/action/package_setup_files.rb +7 -42
- data/plugins/providers/virtualbox/action/package_setup_folders.rb +6 -26
- data/plugins/providers/virtualbox/driver/base.rb +10 -0
- data/plugins/providers/virtualbox/driver/version_5_0.rb +11 -11
- data/plugins/providers/virtualbox/driver/version_5_1.rb +3 -721
- data/plugins/providers/virtualbox/provider.rb +9 -5
- data/plugins/providers/virtualbox/synced_folder.rb +1 -1
- data/plugins/providers/virtualbox/util/compile_forwarded_ports.rb +3 -1
- data/plugins/provisioners/ansible/cap/guest/arch/ansible_install.rb +2 -2
- data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +8 -8
- data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +9 -5
- data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +1 -1
- data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +5 -3
- data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +7 -3
- data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +1 -1
- data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
- data/plugins/provisioners/ansible/config/guest.rb +7 -1
- data/plugins/provisioners/ansible/provisioner/guest.rb +1 -1
- data/plugins/provisioners/chef/cap/freebsd/chef_install.rb +18 -0
- data/plugins/provisioners/chef/cap/freebsd/chef_installed.rb +22 -0
- data/plugins/provisioners/chef/plugin.rb +10 -0
- data/plugins/provisioners/docker/cap/linux/docker_installed.rb +1 -0
- data/plugins/provisioners/salt/bootstrap-salt.ps1 +4 -4
- data/plugins/provisioners/shell/config.rb +2 -2
- data/plugins/provisioners/shell/provisioner.rb +66 -4
- data/plugins/pushes/atlas/push.rb +6 -0
- data/plugins/pushes/local-exec/config.rb +2 -2
- data/plugins/synced_folders/unix_mount_helpers.rb +105 -0
- data/templates/commands/init/Vagrantfile.erb +6 -0
- data/templates/commands/init/Vagrantfile.min.erb +3 -0
- data/templates/guests/debian/network_dhcp.erb +2 -2
- data/templates/guests/gentoo/network_systemd.erb +16 -0
- data/templates/guests/redhat/network_dhcp.erb +1 -0
- data/templates/guests/redhat/network_static.erb +1 -1
- data/templates/guests/redhat/network_static6.erb +1 -1
- data/templates/locales/en.yml +72 -3
- data/templates/locales/providers_docker.yml +15 -0
- data/test/acceptance/provider-virtualbox/linked_clone_spec.rb +1 -1
- data/test/unit/plugins/commands/init/command_test.rb +7 -0
- data/test/unit/plugins/commands/up/command_test.rb +65 -0
- data/test/unit/plugins/commands/validate/command_test.rb +52 -0
- data/test/unit/plugins/communicators/ssh/communicator_test.rb +58 -2
- data/test/unit/plugins/communicators/winrm/communicator_test.rb +14 -26
- data/test/unit/plugins/communicators/winrm/helper_test.rb +12 -0
- data/test/unit/plugins/communicators/winrm/shell_test.rb +54 -15
- data/test/unit/plugins/communicators/winssh/communicator_test.rb +525 -0
- data/test/unit/plugins/guests/arch/cap/configure_networks_test.rb +5 -0
- data/test/unit/plugins/guests/esxi/cap/public_key_test.rb +48 -0
- data/test/unit/plugins/guests/linux/cap/mount_nfs_test.rb +1 -1
- data/test/unit/plugins/guests/linux/cap/mount_smb_shared_folder.rb +71 -0
- data/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb +43 -0
- data/test/unit/plugins/guests/linux/cap/network_interfaces_test.rb +10 -10
- data/test/unit/plugins/guests/redhat/cap/configure_networks_test.rb +132 -12
- data/test/unit/plugins/guests/windows/cap/mount_shared_folder_test.rb +23 -0
- data/test/unit/plugins/providers/docker/driver_compose_test.rb +268 -0
- data/test/unit/plugins/provisioners/ansible/config/guest_test.rb +9 -0
- data/test/unit/plugins/provisioners/ansible/provisioner_test.rb +2 -2
- data/test/unit/plugins/pushes/atlas/push_test.rb +151 -150
- data/test/unit/templates/guests/debian/network_dhcp_test.rb +1 -0
- data/test/unit/templates/guests/gentoo/systemd_network_test.rb +73 -0
- data/test/unit/templates/guests/redhat/network_dhcp_test.rb +18 -0
- data/test/unit/vagrant/action/builtin/box_add_test.rb +27 -0
- data/test/unit/vagrant/action/builtin/handle_forwarded_port_collisions_test.rb +170 -0
- data/test/unit/vagrant/action/builtin/provision_test.rb +208 -0
- data/test/unit/vagrant/box_collection_test.rb +98 -0
- data/test/unit/vagrant/environment_test.rb +17 -0
- data/test/unit/vagrant/shared_helpers_test.rb +12 -0
- data/test/unit/vagrant/util/command_deprecation_test.rb +106 -0
- data/test/unit/vagrant/util/env_test.rb +43 -0
- data/test/unit/vagrant/util/platform_test.rb +8 -0
- data/test/unit/vagrant/util/subprocess_test.rb +61 -0
- data/test/vagrant-spec/Vagrantfile.spec +78 -0
- data/test/vagrant-spec/boxes/.keep +0 -0
- data/test/vagrant-spec/configs/vagrant-spec.config.virtualbox.rb +10 -0
- data/test/vagrant-spec/scripts/centos-run.virtualbox.sh +8 -0
- data/test/vagrant-spec/scripts/centos-setup.virtualbox.sh +14 -0
- data/test/vagrant-spec/scripts/ubuntu-run.virtualbox.sh +8 -0
- data/test/vagrant-spec/scripts/ubuntu-setup.virtualbox.sh +12 -0
- data/vagrant.gemspec +6 -11
- data/version.txt +1 -1
- metadata +1694 -1835
- data/plugins/communicators/winrm/scripts/elevated_shell.ps1.erb +0 -101
@@ -259,9 +259,11 @@ module VagrantPlugins
|
|
259
259
|
default_id = nil
|
260
260
|
|
261
261
|
if type == :forwarded_port
|
262
|
-
# For forwarded ports, set the default ID to the
|
263
|
-
#
|
264
|
-
|
262
|
+
# For forwarded ports, set the default ID to be the
|
263
|
+
# concat of host_ip, proto and host_port. This would ensure Vagrant
|
264
|
+
# caters for port forwarding in an IP aliased environment where
|
265
|
+
# different host IP addresses are to be listened on the same port.
|
266
|
+
default_id = "#{options[:host_ip]}#{options[:protocol]}#{options[:host]}"
|
265
267
|
end
|
266
268
|
|
267
269
|
options[:id] = default_id || SecureRandom.uuid
|
@@ -697,7 +699,7 @@ module VagrantPlugins
|
|
697
699
|
end
|
698
700
|
|
699
701
|
if options[:host]
|
700
|
-
key = "#{options[:protocol]}#{options[:host]}"
|
702
|
+
key = "#{options[:host_ip]}#{options[:protocol]}#{options[:host]}"
|
701
703
|
if fp_used.include?(key)
|
702
704
|
errors << I18n.t("vagrant.config.vm.network_fp_host_not_unique",
|
703
705
|
host: options[:host].to_s,
|
@@ -177,14 +177,12 @@ module VagrantPlugins
|
|
177
177
|
Vagrant::Action::Builder.new.tap do |b|
|
178
178
|
b.use Call, IsState, :not_created do |env, b2|
|
179
179
|
if env[:result]
|
180
|
-
|
181
|
-
next
|
180
|
+
raise Errors::ContainerNotCreatedError
|
182
181
|
end
|
183
182
|
|
184
183
|
b2.use Call, IsState, :running do |env2, b3|
|
185
184
|
if !env2[:result]
|
186
|
-
|
187
|
-
next
|
185
|
+
raise Errors::ContainerNotRunningError
|
188
186
|
end
|
189
187
|
|
190
188
|
b3.use PrepareSSH
|
@@ -199,13 +197,12 @@ module VagrantPlugins
|
|
199
197
|
Vagrant::Action::Builder.new.tap do |b|
|
200
198
|
b.use Call, IsState, :not_created do |env, b2|
|
201
199
|
if env[:result]
|
202
|
-
|
203
|
-
next
|
200
|
+
raise Errors::ContainerNotCreatedError
|
204
201
|
end
|
205
202
|
|
206
203
|
b2.use Call, IsState, :running do |env2, b3|
|
207
204
|
if !env2[:result]
|
208
|
-
raise
|
205
|
+
raise Errors::ContainerNotRunningError
|
209
206
|
end
|
210
207
|
|
211
208
|
b3.use SSHRun
|
@@ -43,7 +43,7 @@ module VagrantPlugins
|
|
43
43
|
dockerfile = machine.provider_config.dockerfile
|
44
44
|
dockerfile_path = File.join(build_dir, dockerfile)
|
45
45
|
|
46
|
-
args.push("--file
|
46
|
+
args.push("--file").push(dockerfile_path)
|
47
47
|
machine.ui.output(
|
48
48
|
I18n.t("docker_provider.building_named_dockerfile",
|
49
49
|
file: machine.provider_config.dockerfile))
|
@@ -129,6 +129,9 @@ module VagrantPlugins
|
|
129
129
|
# Don't include SSH if we've explicitly asked not to
|
130
130
|
next if options[:id] == "ssh" && !include_ssh
|
131
131
|
|
132
|
+
# Skip port if it is disabled
|
133
|
+
next if options[:disabled]
|
134
|
+
|
132
135
|
# If the guest port is 0, put it in the random group
|
133
136
|
if options[:guest] == 0
|
134
137
|
random << options[:host]
|
@@ -19,6 +19,18 @@ module VagrantPlugins
|
|
19
19
|
# @return [String]
|
20
20
|
attr_accessor :build_dir
|
21
21
|
|
22
|
+
# Use docker-compose to manage the lifecycle and environment for
|
23
|
+
# containers instead of using docker directly.
|
24
|
+
#
|
25
|
+
# @return [Boolean]
|
26
|
+
attr_accessor :compose
|
27
|
+
|
28
|
+
# Configuration Hash used for build the docker-compose composition
|
29
|
+
# file. This can be used for adding networks or volumes.
|
30
|
+
#
|
31
|
+
# @return [Hash]
|
32
|
+
attr_accessor :compose_configuration
|
33
|
+
|
22
34
|
# An optional file name of a Dockerfile to be used when building
|
23
35
|
# the image. This requires Docker >1.5.0.
|
24
36
|
#
|
@@ -138,6 +150,8 @@ module VagrantPlugins
|
|
138
150
|
@build_args = []
|
139
151
|
@build_dir = UNSET_VALUE
|
140
152
|
@cmd = UNSET_VALUE
|
153
|
+
@compose = UNSET_VALUE
|
154
|
+
@compose_configuration = {}
|
141
155
|
@create_args = UNSET_VALUE
|
142
156
|
@dockerfile = UNSET_VALUE
|
143
157
|
@env = {}
|
@@ -201,6 +215,7 @@ module VagrantPlugins
|
|
201
215
|
@build_args = [] if @build_args == UNSET_VALUE
|
202
216
|
@build_dir = nil if @build_dir == UNSET_VALUE
|
203
217
|
@cmd = [] if @cmd == UNSET_VALUE
|
218
|
+
@compose = false if @compose == UNSET_VALUE
|
204
219
|
@create_args = [] if @create_args == UNSET_VALUE
|
205
220
|
@dockerfile = nil if @dockerfile == UNSET_VALUE
|
206
221
|
@env ||= {}
|
@@ -228,13 +243,20 @@ module VagrantPlugins
|
|
228
243
|
# host VM. Other users can optionally disable this by setting the
|
229
244
|
# value explicitly to false in their Vagrantfile.
|
230
245
|
if @force_host_vm == UNSET_VALUE
|
231
|
-
@force_host_vm = !Vagrant::Util::Platform.linux?
|
246
|
+
@force_host_vm = !Vagrant::Util::Platform.linux? &&
|
247
|
+
!Vagrant::Util::Platform.darwin? &&
|
248
|
+
!Vagrant::Util::Platform.windows?
|
232
249
|
end
|
233
250
|
|
234
251
|
# The machine name must be a symbol
|
235
252
|
@vagrant_machine = @vagrant_machine.to_sym if @vagrant_machine
|
236
253
|
|
237
254
|
@expose.uniq!
|
255
|
+
|
256
|
+
if @compose_configuration.is_a?(Hash)
|
257
|
+
# Ensures configuration is using basic types
|
258
|
+
@compose_configuration = JSON.parse(@compose_configuration.to_json)
|
259
|
+
end
|
238
260
|
end
|
239
261
|
|
240
262
|
def validate(machine)
|
@@ -255,6 +277,10 @@ module VagrantPlugins
|
|
255
277
|
end
|
256
278
|
end
|
257
279
|
|
280
|
+
if !@compose_configuration.is_a?(Hash)
|
281
|
+
errors << I18n.t("docker_provider.errors.config.compose_configuration_hash")
|
282
|
+
end
|
283
|
+
|
258
284
|
if !@create_args.is_a?(Array)
|
259
285
|
errors << I18n.t("docker_provider.errors.config.create_args_array")
|
260
286
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require "json"
|
2
|
-
|
3
2
|
require "log4r"
|
4
3
|
|
4
|
+
require_relative "./driver/compose"
|
5
|
+
|
5
6
|
module VagrantPlugins
|
6
7
|
module DockerProvider
|
7
8
|
class Driver
|
@@ -45,7 +46,19 @@ module VagrantPlugins
|
|
45
46
|
run_cmd += expose.map { |p| ['--expose', "#{p}"] }
|
46
47
|
run_cmd += links.map { |k, v| ['--link', "#{k}:#{v}"] }
|
47
48
|
run_cmd += ports.map { |p| ['-p', p.to_s] }
|
48
|
-
run_cmd += volumes.map { |v|
|
49
|
+
run_cmd += volumes.map { |v|
|
50
|
+
v = v.to_s
|
51
|
+
if v.include?(":") && (Vagrant::Util::Platform.windows? || Vagrant::Util::Platform.wsl?)
|
52
|
+
host, guest = v.split(":", 2)
|
53
|
+
host = Vagrant::Util::Platform.windows_path(host)
|
54
|
+
# NOTE: Docker does not support UNC style paths (which also
|
55
|
+
# means that there's no long path support). Hopefully this
|
56
|
+
# will be fixed someday and the gsub below can be removed.
|
57
|
+
host.gsub!(/^[^A-Za-z]+/, "")
|
58
|
+
v = [host, guest].join(":")
|
59
|
+
end
|
60
|
+
['-v', v.to_s]
|
61
|
+
}
|
49
62
|
run_cmd += %W(--privileged) if params[:privileged]
|
50
63
|
run_cmd += %W(-h #{params[:hostname]}) if params[:hostname]
|
51
64
|
run_cmd << "-t" if params[:pty]
|
@@ -0,0 +1,287 @@
|
|
1
|
+
require "json"
|
2
|
+
require "log4r"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module DockerProvider
|
6
|
+
class Driver
|
7
|
+
class Compose < Driver
|
8
|
+
|
9
|
+
# @return [Integer] Maximum number of seconds to wait for lock
|
10
|
+
LOCK_TIMEOUT = 60
|
11
|
+
# @return [String] Compose file format version
|
12
|
+
COMPOSE_VERSION = "2".freeze
|
13
|
+
|
14
|
+
# @return [Pathname] data directory to store composition
|
15
|
+
attr_reader :data_directory
|
16
|
+
# @return [Vagrant::Machine]
|
17
|
+
attr_reader :machine
|
18
|
+
|
19
|
+
# Create a new driver instance
|
20
|
+
#
|
21
|
+
# @param [Vagrant::Machine] machine Machine instance for this driver
|
22
|
+
def initialize(machine)
|
23
|
+
if !Vagrant::Util::Which.which("vagrant-compose")
|
24
|
+
raise Errors::DockerComposeNotInstalledError
|
25
|
+
end
|
26
|
+
super()
|
27
|
+
@machine = machine
|
28
|
+
@data_directory = Pathname.new(machine.env.local_data_path).
|
29
|
+
join("docker-compose")
|
30
|
+
@data_directory.mkpath
|
31
|
+
@logger = Log4r::Logger.new("vagrant::docker::driver::compose")
|
32
|
+
@compose_lock = Mutex.new
|
33
|
+
@logger.debug("Docker compose driver initialize for machine `#{@machine.name}` (`#{@machine.id}`)")
|
34
|
+
@logger.debug("Data directory for composition file `#{@data_directory}`")
|
35
|
+
end
|
36
|
+
|
37
|
+
def build(dir, **opts, &block)
|
38
|
+
name = machine.name.to_s
|
39
|
+
@logger.debug("Applying build for `#{name}` using `#{dir}` directory.")
|
40
|
+
begin
|
41
|
+
update_composition do |composition|
|
42
|
+
services = composition["services"] ||= {}
|
43
|
+
services[name] ||= {}
|
44
|
+
services[name]["build"] = {"context" => dir}
|
45
|
+
# Extract custom dockerfile location if set
|
46
|
+
if opts[:extra_args] && opts[:extra_args].include?("--file")
|
47
|
+
services[name]["build"]["dockerfile"] = opts[:extra_args][opts[:extra_args].index("--file") + 1]
|
48
|
+
end
|
49
|
+
# Extract any build args that can be found
|
50
|
+
case opts[:build_args]
|
51
|
+
when Array
|
52
|
+
if opts[:build_args].include?("--build-arg")
|
53
|
+
idx = 0
|
54
|
+
build_args = {}
|
55
|
+
while(idx < opts[:build_args].size)
|
56
|
+
arg_value = opts[:build_args][idx]
|
57
|
+
idx += 1
|
58
|
+
if arg_value.start_with?("--build-arg")
|
59
|
+
if !arg_value.include?("=")
|
60
|
+
arg_value = opts[:build_args][idx]
|
61
|
+
idx += 1
|
62
|
+
end
|
63
|
+
key, val = arg_value.to_s.split("=", 2).to_s.split("=")
|
64
|
+
build_args[key] = val
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
when Hash
|
69
|
+
services[name]["build"]["args"] = opts[:build_args]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
rescue => error
|
73
|
+
@logger.error("Failed to apply build using `#{dir}` directory: #{error.class} - #{error}")
|
74
|
+
update_composition do |composition|
|
75
|
+
composition["services"].delete(name)
|
76
|
+
end
|
77
|
+
raise
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def create(params, **opts, &block)
|
82
|
+
# NOTE: Use the direct machine name as we don't
|
83
|
+
# need to worry about uniqueness with compose
|
84
|
+
name = machine.name.to_s
|
85
|
+
image = params.fetch(:image)
|
86
|
+
links = params.fetch(:links)
|
87
|
+
ports = Array(params[:ports])
|
88
|
+
volumes = Array(params[:volumes]).map do |v|
|
89
|
+
v = v.to_s
|
90
|
+
if v.include?(":") && (Vagrant::Util::Platform.windows? || Vagrant::Util::Platform.wsl?)
|
91
|
+
host, guest = v.split(":", 2)
|
92
|
+
host = Vagrant::Util::Platform.windows_path(host)
|
93
|
+
# NOTE: Docker does not support UNC style paths (which also
|
94
|
+
# means that there's no long path support). Hopefully this
|
95
|
+
# will be fixed someday and the gsub below can be removed.
|
96
|
+
host.gsub!(/^[^A-Za-z]+/, "")
|
97
|
+
v = [host, guest].join(":")
|
98
|
+
end
|
99
|
+
v
|
100
|
+
end
|
101
|
+
cmd = Array(params.fetch(:cmd))
|
102
|
+
env = Hash[*params.fetch(:env).flatten.map(&:to_s)]
|
103
|
+
expose = Array(params[:expose])
|
104
|
+
@logger.debug("Creating container `#{name}`")
|
105
|
+
begin
|
106
|
+
update_args = [:apply]
|
107
|
+
update_args.push(:detach) if params[:detach]
|
108
|
+
update_args << block
|
109
|
+
update_composition(*update_args) do |composition|
|
110
|
+
services = composition["services"] ||= {}
|
111
|
+
services[name] ||= {}
|
112
|
+
if params[:extra_args].is_a?(Hash)
|
113
|
+
services[name].merge!(
|
114
|
+
Hash[
|
115
|
+
params[:extra_args].map{ |k, v|
|
116
|
+
[k.to_s, v]
|
117
|
+
}
|
118
|
+
]
|
119
|
+
)
|
120
|
+
end
|
121
|
+
services[name].merge!(
|
122
|
+
"environment" => env,
|
123
|
+
"expose" => expose,
|
124
|
+
"ports" => ports,
|
125
|
+
"volumes" => volumes,
|
126
|
+
"links" => links,
|
127
|
+
"command" => cmd
|
128
|
+
)
|
129
|
+
services[name]["image"] = image if image
|
130
|
+
services[name]["hostname"] = params[:hostname] if params[:hostname]
|
131
|
+
services[name]["privileged"] = true if params[:privileged]
|
132
|
+
services[name]["pty"] = true if params[:pty]
|
133
|
+
end
|
134
|
+
rescue => error
|
135
|
+
@logger.error("Failed to create container `#{name}`: #{error.class} - #{error}")
|
136
|
+
update_composition do |composition|
|
137
|
+
composition["services"].delete(name)
|
138
|
+
end
|
139
|
+
raise
|
140
|
+
end
|
141
|
+
get_container_id(name)
|
142
|
+
end
|
143
|
+
|
144
|
+
def rm(cid)
|
145
|
+
if created?(cid)
|
146
|
+
destroy = false
|
147
|
+
synchronized do
|
148
|
+
compose_execute("rm", "-f", machine.name.to_s)
|
149
|
+
update_composition do |composition|
|
150
|
+
if composition["services"] && composition["services"].key?(machine.name.to_s)
|
151
|
+
@logger.info("Removing container `#{machine.name}`")
|
152
|
+
if composition["services"].size > 1
|
153
|
+
composition["services"].delete(machine.name.to_s)
|
154
|
+
else
|
155
|
+
destroy = true
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
if destroy
|
160
|
+
@logger.info("No containers remain. Destroying full environment.")
|
161
|
+
compose_execute("down", "--volumes", "--rmi", "local")
|
162
|
+
@logger.info("Deleting composition path `#{composition_path}`")
|
163
|
+
composition_path.delete
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def rmi(*_)
|
170
|
+
true
|
171
|
+
end
|
172
|
+
|
173
|
+
def created?(cid)
|
174
|
+
result = super
|
175
|
+
if !result
|
176
|
+
composition = get_composition
|
177
|
+
if composition["services"] && composition["services"].has_key?(machine.name.to_s)
|
178
|
+
result = true
|
179
|
+
end
|
180
|
+
end
|
181
|
+
result
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
# Lookup the ID for the container with the given name
|
187
|
+
#
|
188
|
+
# @param [String] name Name of container
|
189
|
+
# @return [String] Container ID
|
190
|
+
def get_container_id(name)
|
191
|
+
compose_execute("ps", "-q", name).chomp
|
192
|
+
end
|
193
|
+
|
194
|
+
# Execute a `docker-compose` command
|
195
|
+
def compose_execute(*cmd, **opts, &block)
|
196
|
+
synchronized do
|
197
|
+
execute("docker-compose", "-f", composition_path.to_s,
|
198
|
+
"-p", machine.env.cwd.basename.to_s, *cmd, **opts, &block)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Apply any changes made to the composition
|
203
|
+
def apply_composition!(*args)
|
204
|
+
block = args.detect{|arg| arg.is_a?(Proc) }
|
205
|
+
execute_args = ["up", "--remove-orphans"]
|
206
|
+
if args.include?(:detach)
|
207
|
+
execute_args << "-d"
|
208
|
+
end
|
209
|
+
machine.env.lock("compose", retry: true) do
|
210
|
+
if block
|
211
|
+
compose_execute(*execute_args, &block)
|
212
|
+
else
|
213
|
+
compose_execute(*execute_args)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Update the composition and apply changes if requested
|
219
|
+
#
|
220
|
+
# @param [Boolean] apply Apply composition changes
|
221
|
+
def update_composition(*args)
|
222
|
+
synchronized do
|
223
|
+
machine.env.lock("compose", retry: true) do
|
224
|
+
composition = get_composition
|
225
|
+
result = yield composition
|
226
|
+
write_composition(composition)
|
227
|
+
if args.include?(:apply) || (args.include?(:conditional) && result)
|
228
|
+
apply_composition!(*args)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# @return [Hash] current composition contents
|
235
|
+
def get_composition
|
236
|
+
composition = {"version" => COMPOSE_VERSION.dup}
|
237
|
+
if composition_path.exist?
|
238
|
+
composition = Vagrant::Util::DeepMerge.deep_merge(composition, YAML.load(composition_path.read))
|
239
|
+
end
|
240
|
+
composition = Vagrant::Util::DeepMerge.deep_merge(composition, machine.provider_config.compose_configuration.dup)
|
241
|
+
@logger.debug("Fetched composition with provider configuration applied: #{composition}")
|
242
|
+
composition
|
243
|
+
end
|
244
|
+
|
245
|
+
# Save the composition
|
246
|
+
#
|
247
|
+
# @param [Hash] composition New composition
|
248
|
+
def write_composition(composition)
|
249
|
+
@logger.debug("Saving composition to `#{composition_path}`: #{composition}")
|
250
|
+
tmp_file = Tempfile.new("vagrant-docker-compose")
|
251
|
+
tmp_file.write(composition.to_yaml)
|
252
|
+
tmp_file.close
|
253
|
+
synchronized do
|
254
|
+
FileUtils.mv(tmp_file.path, composition_path.to_s)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# @return [Pathname] path to the docker-compose.yml file
|
259
|
+
def composition_path
|
260
|
+
data_directory.join("docker-compose.yml")
|
261
|
+
end
|
262
|
+
|
263
|
+
def synchronized
|
264
|
+
if !@compose_lock.owned?
|
265
|
+
timeout = LOCK_TIMEOUT.to_f
|
266
|
+
until @compose_lock.owned?
|
267
|
+
if @compose_lock.try_lock
|
268
|
+
if timeout > 0
|
269
|
+
timeout -= sleep(1)
|
270
|
+
else
|
271
|
+
raise Errors::ComposeLockTimeoutError
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
got_lock = true
|
276
|
+
end
|
277
|
+
begin
|
278
|
+
result = yield
|
279
|
+
ensure
|
280
|
+
@compose_lock.unlock if got_lock
|
281
|
+
end
|
282
|
+
result
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|