vagrant-google 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ module VagrantPlugins
15
+ module Google
16
+ module Action
17
+ # This can be used with "Call" built-in to check if the machine
18
+ # is created and branch in the middleware.
19
+ class IsCreated
20
+ def initialize(app, env)
21
+ @app = app
22
+ end
23
+
24
+ def call(env)
25
+ env[:result] = env[:machine].state.id != :not_created
26
+ @app.call(env)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ module VagrantPlugins
15
+ module Google
16
+ module Action
17
+ class MessageAlreadyCreated
18
+ def initialize(app, env)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+ env[:ui].info(I18n.t("vagrant_google.already_created"))
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ module VagrantPlugins
15
+ module Google
16
+ module Action
17
+ class MessageNotCreated
18
+ def initialize(app, env)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+ env[:ui].info(I18n.t("vagrant_google.not_created"))
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ module VagrantPlugins
15
+ module Google
16
+ module Action
17
+ class MessageWillNotDestroy
18
+ def initialize(app, env)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+ env[:ui].info(I18n.t("vagrant_google.will_not_destroy", name: env[:machine].name))
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,54 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require "log4r"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This action reads the SSH info for the machine and puts it into the
20
+ # `:machine_ssh_info` key in the environment.
21
+ class ReadSSHInfo
22
+ def initialize(app, env)
23
+ @app = app
24
+ @logger = Log4r::Logger.new("vagrant_google::action::read_ssh_info")
25
+ end
26
+
27
+ def call(env)
28
+ env[:machine_ssh_info] = read_ssh_info(env[:google_compute], env[:machine])
29
+
30
+ @app.call(env)
31
+ end
32
+
33
+ def read_ssh_info(google, machine)
34
+ return nil if machine.id.nil?
35
+ # Find the machine
36
+ zone = machine.provider_config.zone
37
+ server = google.servers.get(machine.id, zone)
38
+ if server.nil?
39
+ # The machine can't be found
40
+ @logger.info("Machine '#{zone}:#{machine.id}'couldn't be found, assuming it got destroyed.")
41
+ machine.id = nil
42
+ return nil
43
+ end
44
+
45
+ # Read SSH network info
46
+ return {
47
+ :host => server.public_ip_address,
48
+ :port => 22
49
+ }
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require "log4r"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This action reads the state of the machine and puts it in the
20
+ # `:machine_state_id` key in the environment.
21
+ class ReadState
22
+ def initialize(app, env)
23
+ @app = app
24
+ @logger = Log4r::Logger.new("vagrant_google::action::read_state")
25
+ end
26
+
27
+ def call(env)
28
+ env[:machine_state_id] = read_state(env[:google_compute], env[:machine])
29
+
30
+ @app.call(env)
31
+ end
32
+
33
+ def read_state(google, machine)
34
+ return :not_created if machine.id.nil?
35
+
36
+ # Find the machine
37
+ zone = machine.provider_config.zone
38
+ # TODO(erjohnso): not sure why this is necessary, 'server' should be nil
39
+ begin
40
+ server = google.servers.get(machine.id, zone)
41
+ rescue Exception => e
42
+ @logger.info("TODO: this shouldn't be happening. Call should return nil")
43
+ @logger.info(e.message)
44
+ server = nil
45
+ end
46
+ if server.nil? || [:"shutting-down", :terminated].include?(server.state.to_sym)
47
+ # The machine can't be found
48
+ @logger.info("Machine '#{zone}:#{machine.id}' not found or terminated, assuming it got destroyed.")
49
+ machine.id = nil
50
+ return :not_created
51
+ end
52
+
53
+ # Return the state
54
+ return server.state.to_sym
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,136 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require "log4r"
15
+ require 'vagrant/util/retryable'
16
+ require 'vagrant-google/util/timer'
17
+
18
+ module VagrantPlugins
19
+ module Google
20
+ module Action
21
+ # This runs the configured instance.
22
+ class RunInstance
23
+ include Vagrant::Util::Retryable
24
+
25
+ def initialize(app, env)
26
+ @app = app
27
+ @logger = Log4r::Logger.new("vagrant_google::action::run_instance")
28
+ end
29
+
30
+ def call(env)
31
+ # Initialize metrics if they haven't been
32
+ env[:metrics] ||= {}
33
+
34
+ # Get the zone we're going to booting up in
35
+ zone = env[:machine].provider_config.zone
36
+
37
+ # Get the configs
38
+ zone_config = env[:machine].provider_config.get_zone_config(zone)
39
+ image = zone_config.image
40
+ name = zone_config.name
41
+ machine_type = zone_config.machine_type
42
+ network = zone_config.network
43
+ metadata = zone_config.metadata
44
+
45
+ # Launch!
46
+ env[:ui].info(I18n.t("vagrant_google.launching_instance"))
47
+ env[:ui].info(" -- Name: #{name}")
48
+ env[:ui].info(" -- Type: #{machine_type}")
49
+ env[:ui].info(" -- Image: #{image}")
50
+ env[:ui].info(" -- Zone: #{zone}") if zone
51
+ env[:ui].info(" -- Network: #{network}") if network
52
+ env[:ui].info(" -- Metadata: '#{metadata}'")
53
+ begin
54
+ request_start_time = Time.now().to_i
55
+ disk = env[:google_compute].disks.create(
56
+ name: name,
57
+ size_gb: 10,
58
+ zone_name: zone,
59
+ source_image: image
60
+ )
61
+ disk.wait_for { disk.ready? }
62
+
63
+ defaults = {
64
+ :name => name,
65
+ :zone_name => zone,
66
+ :machine_type => machine_type,
67
+ :image => image,
68
+ :network => network,
69
+ :metadata => metadata,
70
+ # Second arg to get_as_boot_disk is 'autodelete_disk', defaulting
71
+ # to true
72
+ :disks => [disk.get_as_boot_disk(true, true)],
73
+ }
74
+ server = env[:google_compute].servers.create(defaults)
75
+ @logger.info("Machine '#{zone}:#{name}' created.")
76
+ rescue Fog::Compute::Google::NotFound => e
77
+ raise
78
+ rescue Fog::Compute::Google::Error => e
79
+ raise Errors::FogError, :message => e.message
80
+ end
81
+
82
+ # Immediately save the name since the instance has been created
83
+ env[:machine].id = server.name
84
+ server.reload
85
+
86
+ env[:ui].info(I18n.t("vagrant_google.waiting_for_ready"))
87
+ begin
88
+ server.wait_for { ready? }
89
+ env[:metrics]["instance_ready_time"] = Time.now().to_i - request_start_time
90
+ @logger.info("Time for instance ready: #{env[:metrics]["instance_ready_time"]}")
91
+ env[:ui].info(I18n.t("vagrant_google.ready"))
92
+ rescue
93
+ env[:interrupted] = true
94
+ end
95
+
96
+ if !env[:terminated]
97
+ env[:metrics]["instance_ssh_time"] = Util::Timer.time do
98
+ # Wait for SSH to be ready.
99
+ env[:ui].info(I18n.t("vagrant_google.waiting_for_ssh"))
100
+ while true
101
+ # If we're interrupted just back out
102
+ break if env[:interrupted]
103
+ break if env[:machine].communicate.ready?
104
+ sleep 2
105
+ end
106
+ end
107
+ @logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
108
+ env[:ui].info(I18n.t("vagrant_google.ready_ssh"))
109
+ end
110
+
111
+ # Terminate the instance if we were interrupted
112
+ terminate(env) if env[:interrupted]
113
+
114
+ @app.call(env)
115
+ end
116
+
117
+ def recover(env)
118
+ return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
119
+
120
+ if env[:machine].provider.state.id != :not_created
121
+ # Undo the import
122
+ terminate(env)
123
+ end
124
+ end
125
+
126
+ def terminate(env)
127
+ destroy_env = env.dup
128
+ destroy_env.delete(:interrupted)
129
+ destroy_env[:config_validate] = false
130
+ destroy_env[:force_confirm_destroy] = true
131
+ env[:action_runner].run(Action.action_destroy, destroy_env)
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,84 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require "log4r"
15
+ require "vagrant/util/subprocess"
16
+ require "vagrant/util/scoped_hash_override"
17
+
18
+ module VagrantPlugins
19
+ module Google
20
+ module Action
21
+ # This middleware uses `rsync` to sync the folders over to the
22
+ # Google instance.
23
+ class SyncFolders
24
+ include Vagrant::Util::ScopedHashOverride
25
+
26
+ def initialize(app, env)
27
+ @app = app
28
+ @logger = Log4r::Logger.new("vagrant_google::action::sync_folders")
29
+ end
30
+
31
+ def call(env)
32
+ @app.call(env)
33
+
34
+ ssh_info = env[:machine].ssh_info
35
+
36
+ env[:machine].config.vm.synced_folders.each do |id, data|
37
+ data = scoped_hash_override(data, :google)
38
+
39
+ # Ignore disabled shared folders
40
+ next if data[:disabled]
41
+
42
+ hostpath = File.expand_path(data[:hostpath], env[:root_path])
43
+ guestpath = data[:guestpath]
44
+
45
+ # Make sure there is a trailing slash on the host path to
46
+ # avoid creating an additional directory with rsync
47
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
48
+
49
+ env[:ui].info(I18n.t("vagrant_google.rsync_folder",
50
+ :hostpath => hostpath,
51
+ :guestpath => guestpath))
52
+
53
+ # Create the guest path
54
+ env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
55
+ env[:machine].communicate.sudo(
56
+ "chown #{ssh_info[:username]} '#{guestpath}'")
57
+
58
+ # patch from https://github.com/tmatilai/vagrant-aws/commit/4a043a96076c332220ec4ec19470c4af5597dd51
59
+ def ssh_key_options(ssh_info)
60
+ # Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
61
+ Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
62
+ end
63
+
64
+ # Rsync over to the guest path using the SSH info
65
+ command = [
66
+ "rsync", "--verbose", "--archive", "-z",
67
+ "--exclude", ".vagrant/",
68
+ "-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no #{ssh_key_options(ssh_info)}",
69
+ hostpath,
70
+ "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
71
+
72
+ r = Vagrant::Util::Subprocess.execute(*command)
73
+ if r.exit_code != 0
74
+ raise Errors::RsyncError,
75
+ :guestpath => guestpath,
76
+ :hostpath => hostpath,
77
+ :stderr => r.stderr
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require "log4r"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This terminates the running instance.
20
+ class TerminateInstance
21
+ def initialize(app, env)
22
+ @app = app
23
+ @logger = Log4r::Logger.new("vagrant_google::action::terminate_instance")
24
+ end
25
+
26
+ def call(env)
27
+ server = env[:google_compute].servers.get(env[:machine].id, env[:machine].provider_config.zone)
28
+
29
+ # Destroy the server and remove the tracking ID
30
+ env[:ui].info(I18n.t("vagrant_google.terminating"))
31
+ server.destroy if not server.nil?
32
+ env[:machine].id = nil
33
+
34
+ @app.call(env)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require "vagrant-google/util/timer"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This is the same as the builtin provision except it times the
20
+ # provisioner runs.
21
+ class TimedProvision < Vagrant::Action::Builtin::Provision
22
+ def run_provisioner(env, name, p)
23
+ timer = Util::Timer.time do
24
+ super
25
+ end
26
+
27
+ env[:metrics] ||= {}
28
+ env[:metrics]["provisioner_times"] ||= []
29
+ env[:metrics]["provisioner_times"] << [name, timer]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ module VagrantPlugins
15
+ module Google
16
+ module Action
17
+ class WarnNetworks
18
+ def initialize(app, env)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+ if env[:machine].config.vm.networks.length > 0
24
+ env[:ui].warn(I18n.t("vagrant_google.warn_networks"))
25
+ end
26
+
27
+ @app.call(env)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end