vagrant-google 1.0.0 → 2.0.0.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +140 -95
- data/CHANGELOG.md +18 -0
- data/README.md +20 -18
- data/example_boxes/gce-test/Vagrantfile +1 -0
- data/google-test.box +0 -0
- data/google.box +0 -0
- data/lib/vagrant-google/action.rb +3 -4
- data/lib/vagrant-google/action/assign_instance_groups.rb +14 -10
- data/lib/vagrant-google/action/connect_google.rb +11 -5
- data/lib/vagrant-google/action/read_ssh_info.rb +2 -2
- data/lib/vagrant-google/action/read_state.rb +2 -2
- data/lib/vagrant-google/action/run_instance.rb +56 -22
- data/lib/vagrant-google/action/stop_instance.rb +0 -2
- data/lib/vagrant-google/action/terminate_instance.rb +2 -0
- data/lib/vagrant-google/config.rb +28 -24
- data/lib/vagrant-google/provider.rb +5 -0
- data/lib/vagrant-google/version.rb +1 -1
- data/locales/en.yml +3 -6
- data/tasks/acceptance.rake +8 -4
- data/test/acceptance/skeletons/generic/Vagrantfile +5 -4
- data/test/acceptance/skeletons/instance_groups/Vagrantfile +6 -5
- data/test/acceptance/skeletons/multi_instance/Vagrantfile +6 -4
- data/test/acceptance/skeletons/preemptible/Vagrantfile +8 -7
- data/test/acceptance/skeletons/scopes/Vagrantfile +6 -5
- data/test/unit/base.rb +3 -1
- data/test/unit/common/config_test.rb +28 -36
- data/vagrant-google.gemspec +11 -10
- data/vagrant-spec.config.rb +1 -1
- data/vagrantfile_examples/Vagrantfile.simple +2 -0
- metadata +59 -32
- data/lib/vagrant-google/action/sync_folders.rb +0 -106
data/google-test.box
CHANGED
Binary file
|
data/google.box
CHANGED
Binary file
|
@@ -66,7 +66,7 @@ module VagrantPlugins
|
|
66
66
|
end
|
67
67
|
|
68
68
|
b2.use Provision
|
69
|
-
b2.use
|
69
|
+
b2.use SyncedFolders
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -134,7 +134,7 @@ module VagrantPlugins
|
|
134
134
|
b1.use Call, IsTerminated do |env2, b2|
|
135
135
|
if env2[:result]
|
136
136
|
b2.use Provision
|
137
|
-
b2.use
|
137
|
+
b2.use SyncedFolders
|
138
138
|
b2.use WarnNetworks
|
139
139
|
b2.use WarnSshKeys
|
140
140
|
b2.use StartInstance
|
@@ -145,7 +145,7 @@ module VagrantPlugins
|
|
145
145
|
end
|
146
146
|
else
|
147
147
|
b1.use Provision
|
148
|
-
b1.use
|
148
|
+
b1.use SyncedFolders
|
149
149
|
b1.use WarnNetworks
|
150
150
|
b1.use WarnSshKeys
|
151
151
|
b1.use RunInstance
|
@@ -186,7 +186,6 @@ module VagrantPlugins
|
|
186
186
|
autoload :RunInstance, action_root.join("run_instance")
|
187
187
|
autoload :StartInstance, action_root.join("start_instance")
|
188
188
|
autoload :StopInstance, action_root.join("stop_instance")
|
189
|
-
autoload :SyncFolders, action_root.join("sync_folders")
|
190
189
|
autoload :TerminateInstance, action_root.join("terminate_instance")
|
191
190
|
autoload :TimedProvision, action_root.join("timed_provision")
|
192
191
|
autoload :WarnNetworks, action_root.join("warn_networks")
|
@@ -34,6 +34,8 @@ module VagrantPlugins
|
|
34
34
|
zone_config = env[:machine].provider_config.get_zone_config(zone)
|
35
35
|
instance_name = zone_config.name
|
36
36
|
instance_group_name = zone_config.instance_group
|
37
|
+
network = zone_config.network
|
38
|
+
subnetwork = zone_config.subnetwork
|
37
39
|
|
38
40
|
if instance_group_name
|
39
41
|
group = env[:google_compute].instance_groups.get(instance_group_name,
|
@@ -44,7 +46,9 @@ module VagrantPlugins
|
|
44
46
|
instance_group_config = {
|
45
47
|
name: instance_group_name,
|
46
48
|
zone: zone,
|
47
|
-
description: "Created by Vagrant"
|
49
|
+
description: "Created by Vagrant",
|
50
|
+
network: network,
|
51
|
+
subnetwork: subnetwork,
|
48
52
|
}
|
49
53
|
env[:google_compute].instance_groups.create(instance_group_config)
|
50
54
|
end
|
@@ -52,17 +56,17 @@ module VagrantPlugins
|
|
52
56
|
# Add the machine to instance group
|
53
57
|
env[:ui].info(I18n.t("vagrant_google.instance_group_add"))
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
+
# Fixup with add_instance_group_instance after adding to fog
|
60
|
+
# See https://github.com/fog/fog-google/issues/308
|
61
|
+
response = env[:google_compute].add_instance_group_instances(
|
62
|
+
instance_group_name,
|
63
|
+
zone,
|
64
|
+
[instance_name]
|
59
65
|
)
|
60
|
-
unless response.
|
61
|
-
operation = env[:google_compute].operations.get(
|
62
|
-
operation.body["name"], zone
|
63
|
-
)
|
66
|
+
unless response.status == "DONE"
|
67
|
+
operation = env[:google_compute].operations.get(response.name, zone)
|
64
68
|
env[:ui].info(I18n.t("vagrant_google.waiting_for_operation",
|
65
|
-
name: operation.
|
69
|
+
name: operation.name))
|
66
70
|
operation.wait_for { ready? }
|
67
71
|
end
|
68
72
|
end
|
@@ -35,11 +35,8 @@ module VagrantPlugins
|
|
35
35
|
:google_project => provider_config.google_project_id,
|
36
36
|
:google_client_email => provider_config.google_client_email
|
37
37
|
}
|
38
|
-
|
39
|
-
|
40
|
-
else
|
41
|
-
fog_config[:google_json_key_location] = provider_config.google_json_key_location
|
42
|
-
end
|
38
|
+
|
39
|
+
fog_config[:google_json_key_location] = find_key(provider_config.google_json_key_location, env)
|
43
40
|
|
44
41
|
@logger.info("Connecting to Google...")
|
45
42
|
env[:google_compute] = Fog::Compute.new(fog_config)
|
@@ -47,6 +44,15 @@ module VagrantPlugins
|
|
47
44
|
@app.call(env)
|
48
45
|
@logger.info("...Connected!")
|
49
46
|
end
|
47
|
+
|
48
|
+
# If the key is not found, try expanding from root location (see #159)
|
49
|
+
def find_key(location, env)
|
50
|
+
if File.file?(File.expand_path(location))
|
51
|
+
return File.expand_path(location)
|
52
|
+
else
|
53
|
+
return File.expand_path(location, env[:root_path])
|
54
|
+
end
|
55
|
+
end
|
50
56
|
end
|
51
57
|
end
|
52
58
|
end
|
@@ -47,13 +47,13 @@ module VagrantPlugins
|
|
47
47
|
|
48
48
|
# Default to use public ip address
|
49
49
|
ssh_info = {
|
50
|
-
:host => server.
|
50
|
+
:host => server.public_ip_addresses[0],
|
51
51
|
:port => 22
|
52
52
|
}
|
53
53
|
|
54
54
|
if use_private_ip then
|
55
55
|
ssh_info = {
|
56
|
-
:host => server.
|
56
|
+
:host => server.private_ip_addresses[0],
|
57
57
|
:port => 22
|
58
58
|
}
|
59
59
|
end
|
@@ -43,7 +43,7 @@ module VagrantPlugins
|
|
43
43
|
@logger.info(e.message)
|
44
44
|
server = nil
|
45
45
|
end
|
46
|
-
if server.nil? || [:"shutting-down", :terminated].include?(server.
|
46
|
+
if server.nil? || [:"shutting-down", :terminated].include?(server.status.to_sym)
|
47
47
|
# The machine can't be found
|
48
48
|
@logger.info("Machine '#{zone}:#{machine.id}' not found or terminated, assuming it got destroyed.")
|
49
49
|
machine.id = nil
|
@@ -51,7 +51,7 @@ module VagrantPlugins
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# Return the state
|
54
|
-
return server.
|
54
|
+
return server.status.to_sym
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -43,6 +43,7 @@ module VagrantPlugins
|
|
43
43
|
# Get the configs
|
44
44
|
zone_config = env[:machine].provider_config.get_zone_config(zone)
|
45
45
|
image = zone_config.image
|
46
|
+
image_family = zone_config.image_family
|
46
47
|
instance_group = zone_config.instance_group
|
47
48
|
name = zone_config.name
|
48
49
|
machine_type = zone_config.machine_type
|
@@ -52,6 +53,7 @@ module VagrantPlugins
|
|
52
53
|
network = zone_config.network
|
53
54
|
subnetwork = zone_config.subnetwork
|
54
55
|
metadata = zone_config.metadata
|
56
|
+
labels = zone_config.labels
|
55
57
|
tags = zone_config.tags
|
56
58
|
can_ip_forward = zone_config.can_ip_forward
|
57
59
|
use_private_ip = zone_config.use_private_ip
|
@@ -61,21 +63,25 @@ module VagrantPlugins
|
|
61
63
|
on_host_maintenance = zone_config.on_host_maintenance
|
62
64
|
autodelete_disk = zone_config.autodelete_disk
|
63
65
|
service_accounts = zone_config.service_accounts
|
66
|
+
project_id = zone_config.google_project_id
|
64
67
|
|
65
68
|
# Launch!
|
66
69
|
env[:ui].info(I18n.t("vagrant_google.launching_instance"))
|
67
70
|
env[:ui].info(" -- Name: #{name}")
|
71
|
+
env[:ui].info(" -- Project: #{project_id}")
|
68
72
|
env[:ui].info(" -- Type: #{machine_type}")
|
69
73
|
env[:ui].info(" -- Disk type: #{disk_type}")
|
70
74
|
env[:ui].info(" -- Disk size: #{disk_size} GB")
|
71
75
|
env[:ui].info(" -- Disk name: #{disk_name}")
|
72
76
|
env[:ui].info(" -- Image: #{image}")
|
77
|
+
env[:ui].info(" -- Image family: #{image_family}")
|
73
78
|
env[:ui].info(" -- Instance Group: #{instance_group}")
|
74
79
|
env[:ui].info(" -- Zone: #{zone}") if zone
|
75
80
|
env[:ui].info(" -- Network: #{network}") if network
|
76
81
|
env[:ui].info(" -- Subnetwork: #{subnetwork}") if subnetwork
|
77
82
|
env[:ui].info(" -- Metadata: '#{metadata}'")
|
78
|
-
env[:ui].info(" --
|
83
|
+
env[:ui].info(" -- Labels: '#{labels}'")
|
84
|
+
env[:ui].info(" -- Network tags: '#{tags}'")
|
79
85
|
env[:ui].info(" -- IP Forward: #{can_ip_forward}")
|
80
86
|
env[:ui].info(" -- Use private IP: #{use_private_ip}")
|
81
87
|
env[:ui].info(" -- External IP: #{external_ip}")
|
@@ -84,6 +90,36 @@ module VagrantPlugins
|
|
84
90
|
env[:ui].info(" -- On Maintenance: #{on_host_maintenance}")
|
85
91
|
env[:ui].info(" -- Autodelete Disk: #{autodelete_disk}")
|
86
92
|
env[:ui].info(" -- Scopes: #{service_accounts}")
|
93
|
+
|
94
|
+
# Munge image configs
|
95
|
+
image = env[:google_compute].images.get(image).self_link
|
96
|
+
|
97
|
+
# If image_family is set, get the latest image image from the family.
|
98
|
+
unless image_family.nil?
|
99
|
+
image = env[:google_compute].images.get_from_family(image_family).self_link
|
100
|
+
end
|
101
|
+
|
102
|
+
# Munge network configs
|
103
|
+
if network != 'default'
|
104
|
+
network = "projects/#{project_id}/global/networks/#{network}"
|
105
|
+
subnetwork = "projects/#{project_id}/regions/#{zone.split('-')[0..1].join('-')}/subnetworks/#{subnetwork}"
|
106
|
+
else
|
107
|
+
network = "global/networks/default"
|
108
|
+
end
|
109
|
+
|
110
|
+
if external_ip == false
|
111
|
+
# No external IP
|
112
|
+
network_interfaces = [ { :network => network, :subnetwork => subnetwork } ]
|
113
|
+
else
|
114
|
+
network_interfaces = [ { :network => network, :subnetwork => subnetwork, :access_configs => [{:name => 'External NAT', :type => 'ONE_TO_ONE_NAT'}]} ]
|
115
|
+
end
|
116
|
+
|
117
|
+
# Munge scheduling configs
|
118
|
+
scheduling = { :automatic_restart => auto_restart, :on_host_maintenance => on_host_maintenance, :preemptible => preemptible}
|
119
|
+
|
120
|
+
# Munge service_accounts / scopes config
|
121
|
+
service_accounts = [ { :scopes => service_accounts } ]
|
122
|
+
|
87
123
|
begin
|
88
124
|
request_start_time = Time.now.to_i
|
89
125
|
|
@@ -96,24 +132,24 @@ module VagrantPlugins
|
|
96
132
|
if disk_name.nil?
|
97
133
|
# no disk_name... disk_name defaults to instance name
|
98
134
|
disk = env[:google_compute].disks.create(
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
135
|
+
name: name,
|
136
|
+
size_gb: disk_size,
|
137
|
+
type: disk_type,
|
138
|
+
zone_name: zone,
|
139
|
+
source_image: image
|
104
140
|
)
|
105
|
-
disk_created_by_vagrant = true
|
106
141
|
disk.wait_for { disk.ready? }
|
142
|
+
disk_created_by_vagrant = true
|
107
143
|
else
|
108
144
|
disk = env[:google_compute].disks.get(disk_name, zone)
|
109
145
|
if disk.nil?
|
110
146
|
# disk not found... create it with name
|
111
147
|
disk = env[:google_compute].disks.create(
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
148
|
+
name: disk_name,
|
149
|
+
size_gb: disk_size,
|
150
|
+
type: disk_type,
|
151
|
+
zone_name: zone,
|
152
|
+
source_image: image
|
117
153
|
)
|
118
154
|
disk.wait_for { disk.ready? }
|
119
155
|
disk_created_by_vagrant = true
|
@@ -122,22 +158,20 @@ module VagrantPlugins
|
|
122
158
|
|
123
159
|
defaults = {
|
124
160
|
:name => name,
|
125
|
-
:
|
161
|
+
:zone => zone,
|
126
162
|
:machine_type => machine_type,
|
127
163
|
:disk_size => disk_size,
|
128
164
|
:disk_type => disk_type,
|
129
165
|
:image => image,
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
133
|
-
:tags => tags,
|
166
|
+
:network_interfaces => network_interfaces,
|
167
|
+
:metadata => { :items => metadata.each.map { |k, v| {:key => k.to_s, :value => v.to_s} } },
|
168
|
+
:labels => labels,
|
169
|
+
:tags => { :items => tags },
|
134
170
|
:can_ip_forward => can_ip_forward,
|
135
171
|
:use_private_ip => use_private_ip,
|
136
172
|
:external_ip => external_ip,
|
137
|
-
:preemptible => preemptible,
|
138
|
-
:auto_restart => auto_restart,
|
139
|
-
:on_host_maintenance => on_host_maintenance,
|
140
173
|
:disks => [disk.get_as_boot_disk(true, autodelete_disk)],
|
174
|
+
:scheduling => scheduling,
|
141
175
|
:service_accounts => service_accounts
|
142
176
|
}
|
143
177
|
server = env[:google_compute].servers.create(defaults)
|
@@ -176,7 +210,7 @@ module VagrantPlugins
|
|
176
210
|
end
|
177
211
|
end
|
178
212
|
@logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
|
179
|
-
env[:ui].info(I18n.t("vagrant_google.ready_ssh"))
|
213
|
+
env[:ui].info(I18n.t("vagrant_google.ready_ssh")) unless env[:interrupted]
|
180
214
|
end
|
181
215
|
|
182
216
|
# Terminate the instance if we were interrupted
|
@@ -205,7 +239,7 @@ module VagrantPlugins
|
|
205
239
|
def get_disk_type(env, disk_type, zone)
|
206
240
|
begin
|
207
241
|
# TODO(temikus): Outsource parsing logic to fog-google
|
208
|
-
disk_type = env[:google_compute].get_disk_type(disk_type, zone).
|
242
|
+
disk_type = env[:google_compute].get_disk_type(disk_type, zone).self_link
|
209
243
|
rescue Fog::Errors::NotFound
|
210
244
|
raise Errors::DiskTypeError,
|
211
245
|
:disktype => disk_type
|
@@ -28,6 +28,8 @@ module VagrantPlugins
|
|
28
28
|
|
29
29
|
# Destroy the server and remove the tracking ID
|
30
30
|
# destroy() is called with 'false' to disable asynchronous execution.
|
31
|
+
# TODO: Add "override_async" option for faster test
|
32
|
+
# TODO: Look at fog logic for possibly making sync faster
|
31
33
|
env[:ui].info(I18n.t("vagrant_google.terminating"))
|
32
34
|
server.destroy(false) unless server.nil?
|
33
35
|
env[:machine].id = nil
|
@@ -22,11 +22,6 @@ module VagrantPlugins
|
|
22
22
|
# @return [String]
|
23
23
|
attr_accessor :google_client_email
|
24
24
|
|
25
|
-
# The path to the Service Account private key
|
26
|
-
#
|
27
|
-
# @return [String]
|
28
|
-
attr_accessor :google_key_location
|
29
|
-
|
30
25
|
# The path to the Service Account json-formatted private key
|
31
26
|
#
|
32
27
|
# @return [String]
|
@@ -42,6 +37,11 @@ module VagrantPlugins
|
|
42
37
|
# @return [String]
|
43
38
|
attr_accessor :image
|
44
39
|
|
40
|
+
# The image family of the instance to use.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
attr_accessor :image_family
|
44
|
+
|
45
45
|
# The instance group name to put the instance in.
|
46
46
|
#
|
47
47
|
# @return [String]
|
@@ -92,6 +92,11 @@ module VagrantPlugins
|
|
92
92
|
# @return [Array]
|
93
93
|
attr_accessor :tags
|
94
94
|
|
95
|
+
# Labels to apply to the instance
|
96
|
+
#
|
97
|
+
# @return [Hash<String, String>]
|
98
|
+
attr_accessor :labels
|
99
|
+
|
95
100
|
# whether to enable ip forwarding
|
96
101
|
#
|
97
102
|
# @return Boolean
|
@@ -152,10 +157,10 @@ module VagrantPlugins
|
|
152
157
|
|
153
158
|
def initialize(zone_specific=false)
|
154
159
|
@google_client_email = UNSET_VALUE
|
155
|
-
@google_key_location = UNSET_VALUE
|
156
160
|
@google_json_key_location = UNSET_VALUE
|
157
161
|
@google_project_id = UNSET_VALUE
|
158
162
|
@image = UNSET_VALUE
|
163
|
+
@image_family = UNSET_VALUE
|
159
164
|
@instance_group = UNSET_VALUE
|
160
165
|
@machine_type = UNSET_VALUE
|
161
166
|
@disk_size = UNSET_VALUE
|
@@ -166,6 +171,7 @@ module VagrantPlugins
|
|
166
171
|
@network = UNSET_VALUE
|
167
172
|
@subnetwork = UNSET_VALUE
|
168
173
|
@tags = []
|
174
|
+
@labels = {}
|
169
175
|
@can_ip_forward = UNSET_VALUE
|
170
176
|
@external_ip = UNSET_VALUE
|
171
177
|
@use_private_ip = UNSET_VALUE
|
@@ -190,7 +196,7 @@ module VagrantPlugins
|
|
190
196
|
# image and machine type name for zones. Example:
|
191
197
|
#
|
192
198
|
# google.zone_config "us-central1-f" do |zone|
|
193
|
-
# zone.image = "
|
199
|
+
# zone.image = "ubuntu-1604-xenial-v20180306"
|
194
200
|
# zone.machine_type = "n1-standard-4"
|
195
201
|
# end
|
196
202
|
#
|
@@ -216,11 +222,6 @@ module VagrantPlugins
|
|
216
222
|
@__zone_config[zone] << block if block_given?
|
217
223
|
end
|
218
224
|
|
219
|
-
def expand_path(path, root_path)
|
220
|
-
return path if not path
|
221
|
-
return Pathname.new(path).expand_path(root_path)
|
222
|
-
end
|
223
|
-
|
224
225
|
#-------------------------------------------------------------------
|
225
226
|
# Internal methods.
|
226
227
|
#-------------------------------------------------------------------
|
@@ -255,12 +256,14 @@ module VagrantPlugins
|
|
255
256
|
# Try to get access keys from standard Google environment variables; they
|
256
257
|
# will default to nil if the environment variables are not present.
|
257
258
|
@google_client_email = ENV['GOOGLE_CLIENT_EMAIL'] if @google_client_email == UNSET_VALUE
|
258
|
-
@google_key_location = ENV['GOOGLE_KEY_LOCATION'] if @google_key_location == UNSET_VALUE
|
259
259
|
@google_json_key_location = ENV['GOOGLE_JSON_KEY_LOCATION'] if @google_json_key_location == UNSET_VALUE
|
260
260
|
@google_project_id = ENV['GOOGLE_PROJECT_ID'] if @google_project_id == UNSET_VALUE
|
261
261
|
|
262
|
-
#
|
263
|
-
@image =
|
262
|
+
# Default image is nil
|
263
|
+
@image = nil if @image == UNSET_VALUE
|
264
|
+
|
265
|
+
# Default image family is nil
|
266
|
+
@image_family = nil if @image_family == UNSET_VALUE
|
264
267
|
|
265
268
|
# Default instance group name is nil
|
266
269
|
@instance_group = nil if @instance_group == UNSET_VALUE
|
@@ -352,20 +355,16 @@ module VagrantPlugins
|
|
352
355
|
if @zone
|
353
356
|
config = get_zone_config(@zone)
|
354
357
|
|
355
|
-
|
356
|
-
config.google_json_key_location = expand_path(config.google_json_key_location, machine.env.root_path)
|
357
|
-
|
358
|
+
# TODO: Check why provider-level settings are validated in the zone config
|
358
359
|
errors << I18n.t("vagrant_google.config.google_project_id_required") if \
|
359
360
|
config.google_project_id.nil?
|
360
361
|
errors << I18n.t("vagrant_google.config.google_client_email_required") if \
|
361
362
|
config.google_client_email.nil?
|
362
|
-
errors << I18n.t("vagrant_google.config.google_duplicate_key_location") if \
|
363
|
-
!config.google_key_location.nil? and !config.google_json_key_location.nil?
|
364
363
|
errors << I18n.t("vagrant_google.config.google_key_location_required") if \
|
365
|
-
config.
|
364
|
+
config.google_json_key_location.nil?
|
366
365
|
errors << I18n.t("vagrant_google.config.private_key_missing") unless \
|
367
|
-
File.exist?(config.
|
368
|
-
File.exist?(config.google_json_key_location.to_s)
|
366
|
+
File.exist?(File.expand_path(config.google_json_key_location.to_s)) or
|
367
|
+
File.exist?(File.expand_path(config.google_json_key_location.to_s, machine.env.root_path))
|
369
368
|
|
370
369
|
if config.preemptible
|
371
370
|
errors << I18n.t("vagrant_google.config.auto_restart_invalid_on_preemptible") if \
|
@@ -373,9 +372,14 @@ module VagrantPlugins
|
|
373
372
|
errors << I18n.t("vagrant_google.config.on_host_maintenance_invalid_on_preemptible") unless \
|
374
373
|
config.on_host_maintenance == "TERMINATE"
|
375
374
|
end
|
375
|
+
|
376
|
+
if config.image_family
|
377
|
+
errors << I18n.t("vagrant_google.config.image_and_image_family_set") if \
|
378
|
+
config.image
|
379
|
+
end
|
376
380
|
end
|
377
381
|
|
378
|
-
errors << I18n.t("vagrant_google.config.image_required") if config.image.nil?
|
382
|
+
errors << I18n.t("vagrant_google.config.image_required") if config.image.nil? && config.image_family.nil?
|
379
383
|
errors << I18n.t("vagrant_google.config.name_required") if @name.nil?
|
380
384
|
|
381
385
|
{ "Google Provider" => errors }
|