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.
@@ -20,5 +20,6 @@ Vagrant.configure("2") do |config|
20
20
  override.ssh.username = ENV['GOOGLE_SSH_USER']
21
21
  override.ssh.private_key_path = ENV['GOOGLE_SSH_KEY_LOCATION']
22
22
  end
23
+ _google.image_family = "debian-9"
23
24
  end
24
25
  end
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 SyncFolders
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 SyncFolders
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 SyncFolders
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
- response = env[:google_compute].instance_groups.add_instance(
56
- group: instance_group_name,
57
- zone: zone,
58
- instance: instance_name
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.body["status"] == "DONE"
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.body["name"]))
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
- if provider_config.google_json_key_location.nil?
39
- fog_config[:google_key_location] = provider_config.google_key_location
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.public_ip_address,
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.private_ip_address,
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.state.to_sym)
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.state.to_sym
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(" -- Tags: '#{tags}'")
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
- name: name,
100
- size_gb: disk_size,
101
- type: disk_type,
102
- zone_name: zone,
103
- source_image: image
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
- name: disk_name,
113
- size_gb: disk_size,
114
- type: disk_type,
115
- zone_name: zone,
116
- source_image: image
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
- :zone_name => zone,
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
- :network => network,
131
- :subnetwork => subnetwork,
132
- :metadata => metadata,
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).body["selfLink"]
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
@@ -18,10 +18,8 @@ require 'vagrant-google/util/timer'
18
18
  module VagrantPlugins
19
19
  module Google
20
20
  module Action
21
-
22
21
  # This stops the running instance.
23
22
  class StopInstance
24
-
25
23
  include Vagrant::Util::Retryable
26
24
 
27
25
  def initialize(app, env)
@@ -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 = "debian-7-wheezy-v20150127"
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
- # Image must be nil, since we can't default that
263
- @image = "debian-8-jessie-v20160511" if @image == UNSET_VALUE
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
- config.google_key_location = expand_path(config.google_key_location, machine.env.root_path)
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.google_key_location.nil? and config.google_json_key_location.nil?
364
+ config.google_json_key_location.nil?
366
365
  errors << I18n.t("vagrant_google.config.private_key_missing") unless \
367
- File.exist?(config.google_key_location.to_s) or \
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 }