vmreverter 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/Gemfile +5 -0
- data/LICENSE +12 -0
- data/README.md +121 -0
- data/Rakefile +11 -0
- data/bin/vmreverter +9 -0
- data/components.LICENSE.puppet_acceptance +17 -0
- data/lib/vmreverter/cli.rb +50 -0
- data/lib/vmreverter/config_tester.rb +63 -0
- data/lib/vmreverter/hypervisor/aws.rb +121 -0
- data/lib/vmreverter/hypervisor/vsphere.rb +96 -0
- data/lib/vmreverter/hypervisor/vsphere_helper.rb +187 -0
- data/lib/vmreverter/hypervisor.rb +34 -0
- data/lib/vmreverter/logger.rb +170 -0
- data/lib/vmreverter/options.rb +104 -0
- data/lib/vmreverter/shared/error_handler.rb +20 -0
- data/lib/vmreverter/shared.rb +13 -0
- data/lib/vmreverter/version.rb +3 -0
- data/lib/vmreverter/vmmanager.rb +60 -0
- data/lib/vmreverter.rb +29 -0
- data/vmreverter.gemspec +38 -0
- metadata +179 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MmJiODIzNGFjNTY0ZTZhNWI3NDViN2U4ZWU1ZDQwNDQyYTQxYTAzNA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NzZkZjlmN2YwMmY5NWMzYWVmOTJjMzQ0MGEzNzJhZThhMTYxOGUyNg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZjUyZTljN2JiMDY1NzRjZGFmOTI2MTk3ZmNmZDg2YzE1NTk4NTNhZjQ4YWUx
|
10
|
+
MDhmODUwZTAzYmYwNjgyNGRkYWRiOTJhZDJiOTJiMzRkYzFkNzBiZjA2Mjkx
|
11
|
+
YmZhYjc5ZjQ1ZmY4NWMyYzk4MTliMGE1MDE4OTAyMTk3ZTI3NGY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzAxYWZhZTU1ZmE1NzQzYTU0MDhiZDlmZjgwODdkZGM2YmU4ZjY4MDU4OGVh
|
14
|
+
N2ZjYjE3Y2FmNDFkMGM4ODU4NjE4YTExZDgxMjc0MDRjN2U3OWQ2YjdhYzgy
|
15
|
+
NzQwMGFhYzk4MTM0NDU5ZGNiMmIzNTU5M2ZmMmY5MjczYTQ2ZWU=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Copyright (c) 2014, Scott MacGregor
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
9
|
+
|
10
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# VM Reverter
|
2
|
+
|
3
|
+
This gem is used to revert a collection of virtual machines from many hypervisor frameworks using a yaml file back to specific snapshots.
|
4
|
+
|
5
|
+
## Supported Hypervisors
|
6
|
+
|
7
|
+
* VMWare VSphere Server [vshpere] ~> rbvmomi
|
8
|
+
* AWS [aws] ~> Blimpy / Fog
|
9
|
+
|
10
|
+
## Vsphere Credentials
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
# ~/.fog
|
14
|
+
:default:
|
15
|
+
:vsphere_server: 'vsphere.mydomain.com'
|
16
|
+
:vsphere_username: 'john_doe'
|
17
|
+
:vsphere_password: '$3cr3+_$@uc3'
|
18
|
+
```
|
19
|
+
## Configuration File
|
20
|
+
|
21
|
+
### Required YAML Header:
|
22
|
+
|
23
|
+
* HOSTS
|
24
|
+
* vm-name
|
25
|
+
|
26
|
+
### Required Fields:
|
27
|
+
|
28
|
+
* snapshots
|
29
|
+
* hypervisor
|
30
|
+
|
31
|
+
### Optional fields:
|
32
|
+
|
33
|
+
* power - overide the saved state of the power of the snapshot [up|down|destroy]
|
34
|
+
* tag - add a meta tag to a host
|
35
|
+
|
36
|
+
## Configuration File - Revert
|
37
|
+
|
38
|
+
revert.conf
|
39
|
+
|
40
|
+
```yaml
|
41
|
+
HOSTS:
|
42
|
+
test-server01:
|
43
|
+
hypervisor: vsphere
|
44
|
+
snapshot: gold-image
|
45
|
+
tag: interesting
|
46
|
+
power: up
|
47
|
+
test-server02:
|
48
|
+
hypervisor: vsphere
|
49
|
+
snapshot: gold-image
|
50
|
+
test-server03:
|
51
|
+
hypervisor: aws
|
52
|
+
aws-options:
|
53
|
+
ami-size: m1.small
|
54
|
+
ami-region: us-west-2
|
55
|
+
security-group: clients
|
56
|
+
```
|
57
|
+
|
58
|
+
|
59
|
+
### Configuration Example - Stop VMS
|
60
|
+
|
61
|
+
This configuration will remove the hosts from aws.
|
62
|
+
|
63
|
+
```yaml
|
64
|
+
HOSTS:
|
65
|
+
test-server01:
|
66
|
+
hypervisor: aws
|
67
|
+
power: down
|
68
|
+
test-server02:
|
69
|
+
hypervisor: vsphere
|
70
|
+
power: down
|
71
|
+
```
|
72
|
+
|
73
|
+
|
74
|
+
### Configuration Example - Destruction
|
75
|
+
|
76
|
+
This configuration will remove the hosts from the hypervisor (aws only).
|
77
|
+
|
78
|
+
```yaml
|
79
|
+
HOSTS:
|
80
|
+
test-server01:
|
81
|
+
hypervisor: aws
|
82
|
+
power: destroy
|
83
|
+
test-server02:
|
84
|
+
hypervisor: aws
|
85
|
+
power: destroy
|
86
|
+
```
|
87
|
+
|
88
|
+
## CLI Usage
|
89
|
+
|
90
|
+
Using local conf file and turning on all machines after reverting.
|
91
|
+
|
92
|
+
```
|
93
|
+
$> vmreverter -c ./revert.conf
|
94
|
+
```
|
95
|
+
## Tested Against
|
96
|
+
|
97
|
+
* Ruby 1.9.3
|
98
|
+
* VSphere 5.5
|
99
|
+
|
100
|
+
## TODO
|
101
|
+
|
102
|
+
* Unit Tests
|
103
|
+
* API Mocks
|
104
|
+
|
105
|
+
Further Hypervisor implementations:
|
106
|
+
|
107
|
+
* OpenStack ~> Blimpy
|
108
|
+
* VirtualBox ~> Vagrant
|
109
|
+
|
110
|
+
|
111
|
+
## Legal notes
|
112
|
+
|
113
|
+
This is some wildly refactored code (..legal speak..) from the puppet_acceptance gem. puppet labs, puppet_acceptance, or its authors do not endorse this code.
|
114
|
+
|
115
|
+
Changes include namespace swaps, class additions, class removals, method additions, method removals, and complete code refactoring.
|
116
|
+
|
117
|
+
All original code maintains its copyright from its original author(puppetlabs) and licensing of Apache 2, and only change sets from git rev
|
118
|
+
|
119
|
+
https://github.com/puppetlabs/puppet-acceptance/commit/68272162d0b30905f498a4d71ff641374d3eb8f0
|
120
|
+
|
121
|
+
onward (circa Feb 2014) within the vmreverter namespace will include permissive of BSD-3 LICENSING as such approved by law.
|
data/Rakefile
ADDED
data/bin/vmreverter
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
puppet-acceptance - Puppet's system level acceptance test harness
|
2
|
+
|
3
|
+
Copyright (C) 2011-2013 Puppet Labs Inc
|
4
|
+
|
5
|
+
Puppet Labs can be contacted at: info@puppetlabs.com
|
6
|
+
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
you may not use this file except in compliance with the License.
|
9
|
+
You may obtain a copy of the License at
|
10
|
+
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
See the License for the specific language governing permissions and
|
17
|
+
limitations under the License.
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Vmreverter
|
2
|
+
class CLI
|
3
|
+
def initialize
|
4
|
+
@options = Vmreverter::Options.parse_args
|
5
|
+
@logger = Vmreverter::Logger.new(@options)
|
6
|
+
@options[:logger] = @logger
|
7
|
+
|
8
|
+
if not @options[:config]
|
9
|
+
report_and_raise(@logger, ArgumentError.new("Missing config, specify one (-c or --config)!"), "CLI: initialize")
|
10
|
+
end
|
11
|
+
|
12
|
+
@logger.debug("Options")
|
13
|
+
@options.each do |opt, val|
|
14
|
+
if val and val != []
|
15
|
+
@logger.debug("\t#{opt.to_s}:")
|
16
|
+
if val.kind_of?(Array)
|
17
|
+
val.each do |v|
|
18
|
+
@logger.debug("\t\t#{v.to_s}")
|
19
|
+
end
|
20
|
+
else
|
21
|
+
@logger.debug("\t\t#{val.to_s}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@config = Vmreverter::ConfigTester.new(@options[:config], @options)
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute!
|
31
|
+
|
32
|
+
begin
|
33
|
+
trap(:INT) do
|
34
|
+
@logger.warn "Interrupt received; exiting..."
|
35
|
+
exit(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
@vmmanager = Vmreverter::VMManager.new(@config, @options, @logger)
|
40
|
+
@vmmanager.invoke
|
41
|
+
@vmmanager.close_connection
|
42
|
+
rescue => e
|
43
|
+
raise e
|
44
|
+
end
|
45
|
+
|
46
|
+
end #trap
|
47
|
+
end #execute!
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Vmreverter
|
4
|
+
# Config was taken by Ruby.
|
5
|
+
class ConfigTester
|
6
|
+
|
7
|
+
attr_accessor :logger
|
8
|
+
def initialize(config_file, options)
|
9
|
+
@options = options
|
10
|
+
@logger = options[:logger]
|
11
|
+
@config = load_file(config_file)
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](key)
|
15
|
+
@config[key]
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_file(config_file)
|
19
|
+
if config_file.is_a? Hash
|
20
|
+
config = config_file
|
21
|
+
else
|
22
|
+
config = YAML.load_file(config_file)
|
23
|
+
|
24
|
+
# Make sure the tag array is present for all hosts
|
25
|
+
config['HOSTS'].each_key do |host|
|
26
|
+
config['HOSTS'][host]['tags'] ||= []
|
27
|
+
|
28
|
+
report_and_raise(@logger, RuntimeError.new("Missing hypervisor: (#{host})"), "ConfigTester::load_file") unless config['HOSTS'][host].include? "hypervisor"
|
29
|
+
hypervisor = config['HOSTS'][host]['hypervisor'].downcase
|
30
|
+
#check to see if this host has a hypervisor
|
31
|
+
report_and_raise(@logger, RuntimeError.new("Invalid hypervisor: #{hypervisor} (#{host})"), "ConfigTester::load_file") unless Vmreverter::HYPERVISOR_TYPES.include? hypervisor
|
32
|
+
|
33
|
+
#check to see if this host has a hypervisor
|
34
|
+
report_and_raise(@logger, RuntimeError.new("Missing snapshot: (#{host})"), "ConfigTester::load_file") unless config['HOSTS'][host].include? "snapshot"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
# Merge some useful date into the config hash
|
41
|
+
config['CONFIG'] ||= {}
|
42
|
+
|
43
|
+
config
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Print out test configuration
|
48
|
+
def dump
|
49
|
+
|
50
|
+
# Access "tags" for each host
|
51
|
+
@config["HOSTS"].each_key do|host|
|
52
|
+
@config["HOSTS"][host]['tags'].each do |tag|
|
53
|
+
@logger.notify "Tags for #{host} #{tag}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Access @config keys/values
|
58
|
+
@config["CONFIG"].each_key do|cfg|
|
59
|
+
@logger.notify "Config Key|Val: #{cfg} #{@config["CONFIG"][cfg].inspect}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Vmreverter
|
2
|
+
class AWS
|
3
|
+
|
4
|
+
#AWS support will dynamically create a Security Group for you if you specify ports in the Blimpfile, this means you can easily stand up a machine with specific ports open.
|
5
|
+
#Blimpy uses a unique hash of the ports to avoid re-creating the Security Groups unless necessary.
|
6
|
+
#Blimpy will import your ~/.ssh/id_rsa.pub or ~/.ssh/id_dsa.pub into a Key Pair in every region that you use in your Blimpfiles.
|
7
|
+
def initialize(blimpy_hosts, options, config)
|
8
|
+
@options = options
|
9
|
+
@config = config
|
10
|
+
@logger = options[:logger]
|
11
|
+
@blimpy_hosts = blimpy_hosts
|
12
|
+
require 'rubygems' unless defined?(Gem)
|
13
|
+
require 'yaml' unless defined?(YAML)
|
14
|
+
begin
|
15
|
+
require 'blimpy'
|
16
|
+
rescue LoadError
|
17
|
+
raise "Unable to load Blimpy, please ensure its installed"
|
18
|
+
end
|
19
|
+
|
20
|
+
@fleet = Blimpy.fleet do |fleet|
|
21
|
+
@blimpy_hosts.each do |host|
|
22
|
+
#use snapshot provided for this host - This is an AMI!
|
23
|
+
# host
|
24
|
+
# ami-size: m1.small
|
25
|
+
# ami-region: 'us-west-2'
|
26
|
+
# security-group: 'Clients'
|
27
|
+
|
28
|
+
if not host['snapshot']
|
29
|
+
raise "No snapshot/ami provided for AWS provisioning"
|
30
|
+
end
|
31
|
+
|
32
|
+
@logger.debug "Configuring hypervision AWS for host #{host.name}(#{host['snapshot']}:#{host['amisize']}) "
|
33
|
+
|
34
|
+
fleet.add(:aws) do |ship|
|
35
|
+
ship.name = host.name
|
36
|
+
ship.group = host['security-group']
|
37
|
+
ship.image_id = host['snapshot']
|
38
|
+
ship.flavor = host['amisize'] || 'm1.small'
|
39
|
+
ship.region = host['ami-region'] || 'us-west-2'
|
40
|
+
ship.tags = host['tags']
|
41
|
+
ship.username = 'root'
|
42
|
+
end #fleet
|
43
|
+
@logger.debug "Configuration completed."
|
44
|
+
end #blimpy_hosts
|
45
|
+
end#fleet
|
46
|
+
|
47
|
+
return self
|
48
|
+
end #init
|
49
|
+
|
50
|
+
def invoke
|
51
|
+
if (@config['HOSTS'][name]['launch'] == :on)
|
52
|
+
revert
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def close_connection
|
57
|
+
@fleet = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def revert
|
63
|
+
@logger.notify "Begin Launching AWS Hosts"
|
64
|
+
|
65
|
+
# Attempt to start the fleet, we wrap it with some error handling that deals
|
66
|
+
# with generic Fog errors and retrying in case these errors are transient.
|
67
|
+
fleet_retries = 0
|
68
|
+
begin
|
69
|
+
@fleet.start
|
70
|
+
rescue Fog::Errors::Error => ex
|
71
|
+
fleet_retries += 1
|
72
|
+
if fleet_retries <= 3
|
73
|
+
sleep_time = rand(10) + 10
|
74
|
+
@logger.notify("Calling fleet.destroy, sleeping #{sleep_time} seconds and retrying fleet.start due to Fog::Errors::Error (#{ex.message}), retry attempt #{fleet_retries}.")
|
75
|
+
begin
|
76
|
+
timeout(30) do
|
77
|
+
@fleet.destroy
|
78
|
+
end
|
79
|
+
rescue
|
80
|
+
end
|
81
|
+
sleep sleep_time
|
82
|
+
retry
|
83
|
+
else
|
84
|
+
@logger.error("Retried Fog #{fleet_retries} times, giving up and throwing the exception")
|
85
|
+
raise ex
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# https://github.com/rtyler/blimpy/blob/2d2c711bfcb129f5eb0346f08da62e0cfcde7917/lib/blimpy/fleet.rb#L135
|
91
|
+
def power toggle=:on
|
92
|
+
@logger.notify "Power #{toggle} AWS boxes"
|
93
|
+
if (toggle == :off)
|
94
|
+
start = Time.now
|
95
|
+
@fleet.stop
|
96
|
+
@logger.notify "Spent %.2f seconds halting" % (Time.now - start)
|
97
|
+
else (toggle == :on)
|
98
|
+
start = Time.now
|
99
|
+
@fleet.start
|
100
|
+
@logger.notify "Spent %.2f seconds booting" % (Time.now - start)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def destroy
|
105
|
+
#fleet = Blimpy.fleet do |fleet|
|
106
|
+
# @blimpy_hosts.each do |host|
|
107
|
+
# fleet.add(:aws) do |ship|
|
108
|
+
# ship.name = host.name
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
#end
|
112
|
+
|
113
|
+
@logger.notify "Destroying Blimpy boxes"
|
114
|
+
#fleet.destroy
|
115
|
+
@fleet.destroy
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Apache Licensed - (github/puppetlabs) ripped from puppet_acceptance. ** See Legal notes
|
2
|
+
# Changes include namespace swaps, method removal, method additions, and complete code refactoring
|
3
|
+
module Vmreverter
|
4
|
+
class Vsphere
|
5
|
+
|
6
|
+
def initialize(vsphere_hosts, options, config)
|
7
|
+
@options = options
|
8
|
+
@config = config
|
9
|
+
@logger = options[:logger]
|
10
|
+
@vsphere_hosts = vsphere_hosts
|
11
|
+
require 'yaml' unless defined?(YAML)
|
12
|
+
vsphere_credentials = VsphereHelper.load_config options[:auth]
|
13
|
+
|
14
|
+
@logger.notify "Connecting to vSphere at #{vsphere_credentials[:server]}" + " with credentials for #{vsphere_credentials[:user]}"
|
15
|
+
|
16
|
+
@vsphere_helper = VsphereHelper.new( vsphere_credentials )
|
17
|
+
|
18
|
+
#Transpose Hash for @vsphere_vms = {"test-server01" => "gold-image", "test-server02" => "silver-image"}
|
19
|
+
@vsphere_vms = {}
|
20
|
+
@vsphere_hosts.each do |host|
|
21
|
+
@vsphere_vms[host] = config['HOSTS'][host]['snapshot']
|
22
|
+
end
|
23
|
+
|
24
|
+
#Index Hosts Available via rbvmomi
|
25
|
+
vms = @vsphere_helper.find_vms(@vsphere_vms.keys)
|
26
|
+
|
27
|
+
# Test if host exists and host's snapshot requested exists
|
28
|
+
@vsphere_vms.each_pair do |name, snap|
|
29
|
+
#Find Host in Index
|
30
|
+
report_and_raise(@logger, RuntimeError.new("Couldn't find VM #{name} in vSphere!"), "VSphere::initialize") unless vm = vms[name]
|
31
|
+
#snap ~> config['HOSTS'][vm]['snapshot']
|
32
|
+
report_and_raise(@logger, RuntimeError.new("Could not find snapshot '#{snap}' for VM #{vm.name}!"), "VSphere::initialize") unless @vsphere_helper.find_snapshot(vm, snap)
|
33
|
+
end
|
34
|
+
|
35
|
+
return self
|
36
|
+
end
|
37
|
+
|
38
|
+
def invoke
|
39
|
+
revert
|
40
|
+
end
|
41
|
+
|
42
|
+
def close_connection
|
43
|
+
@vsphere_helper.close_connection
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def revert
|
49
|
+
@logger.notify "Begin Reverting"
|
50
|
+
@vsphere_vms.each_pair do |name, snap|
|
51
|
+
|
52
|
+
vm = @vsphere_helper.find_vms(@vsphere_vms.keys)[name]
|
53
|
+
@logger.notify "Reverting #{vm.name} to snapshot '#{snap}'"
|
54
|
+
start = Time.now
|
55
|
+
|
56
|
+
# This will block for each snapshot...
|
57
|
+
# The code to issue them all and then wait until they are all done sucks
|
58
|
+
snapshot = @vsphere_helper.find_snapshot(vm, snap)
|
59
|
+
snapshot.RevertToSnapshot_Task.wait_for_completion
|
60
|
+
|
61
|
+
time = Time.now - start
|
62
|
+
@logger.notify "Spent %.2f seconds reverting" % time
|
63
|
+
|
64
|
+
if (@config['HOSTS'][name]['power'] == 'up')
|
65
|
+
host_power_on(vm)
|
66
|
+
elsif (@config['HOSTS'][name]['power'] == 'down')
|
67
|
+
host_power_off(vm)
|
68
|
+
else
|
69
|
+
@logger.notify "VM #{name} defaulting to snapshot '#{snap}' power setting"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def host_power_on(vm)
|
76
|
+
unless vm.runtime.powerState == "poweredOn"
|
77
|
+
@logger.notify "Booting #{vm.name}"
|
78
|
+
start = Time.now
|
79
|
+
vm.PowerOnVM_Task.wait_for_completion
|
80
|
+
@logger.notify "Spent %.2f seconds booting #{vm.name}" % (Time.now - start)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def host_power_off(vm)
|
85
|
+
unless vm.runtime.powerState == "poweredOff"
|
86
|
+
@logger.notify "Shutting down #{vm.name}"
|
87
|
+
start = Time.now
|
88
|
+
vm.PowerOffVM_Task.wait_for_completion
|
89
|
+
@logger.notify "Spent %.2f seconds halting #{vm.name}" % (Time.now - start)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|