fission 0.3.0 → 0.4.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.md +3 -0
- data/README.md +1 -1
- data/lib/fission.rb +5 -6
- data/lib/fission/cli.rb +77 -7
- data/lib/fission/command.rb +43 -1
- data/lib/fission/command/clone.rb +19 -20
- data/lib/fission/command/delete.rb +29 -25
- data/lib/fission/command/snapshot_create.rb +11 -26
- data/lib/fission/command/snapshot_list.rb +13 -19
- data/lib/fission/command/snapshot_revert.rb +11 -26
- data/lib/fission/command/start.rb +11 -25
- data/lib/fission/command/status.rb +26 -10
- data/lib/fission/command/stop.rb +10 -21
- data/lib/fission/command/suspend.rb +21 -21
- data/lib/fission/command_helpers.rb +21 -0
- data/lib/fission/config.rb +35 -0
- data/lib/fission/fusion.rb +11 -3
- data/lib/fission/lease.rb +148 -0
- data/lib/fission/metadata.rb +55 -2
- data/lib/fission/response.rb +76 -0
- data/lib/fission/ui.rb +49 -0
- data/lib/fission/version.rb +1 -1
- data/lib/fission/vm.rb +653 -75
- data/spec/contexts/command.rb +12 -0
- data/spec/fission/cli_spec.rb +4 -11
- data/spec/fission/command/clone_spec.rb +45 -45
- data/spec/fission/command/delete_spec.rb +56 -43
- data/spec/fission/command/snapshot_create_spec.rb +29 -51
- data/spec/fission/command/snapshot_list_spec.rb +25 -26
- data/spec/fission/command/snapshot_revert_spec.rb +27 -53
- data/spec/fission/command/start_spec.rb +25 -69
- data/spec/fission/command/status_spec.rb +48 -13
- data/spec/fission/command/stop_spec.rb +25 -42
- data/spec/fission/command/suspend_spec.rb +54 -49
- data/spec/fission/command_helpers_spec.rb +30 -0
- data/spec/fission/command_spec.rb +19 -0
- data/spec/fission/config_spec.rb +24 -0
- data/spec/fission/fusion_spec.rb +6 -6
- data/spec/fission/lease_spec.rb +176 -0
- data/spec/fission/metadata_spec.rb +8 -8
- data/spec/fission/response_spec.rb +81 -0
- data/spec/fission/vm_spec.rb +869 -193
- data/spec/fission_spec.rb +0 -6
- data/spec/helpers/command_helpers.rb +12 -0
- data/spec/helpers/response_helpers.rb +21 -0
- data/spec/matchers/be_a_successful_response.rb +7 -0
- data/spec/matchers/be_an_unsuccessful_response.rb +10 -0
- data/spec/spec_helper.rb +7 -0
- metadata +24 -5
data/lib/fission/metadata.rb
CHANGED
@@ -3,8 +3,23 @@ module Fission
|
|
3
3
|
|
4
4
|
require 'cfpropertylist'
|
5
5
|
|
6
|
+
# Public: Gets/Sets the content (Hash).
|
6
7
|
attr_accessor :content
|
7
8
|
|
9
|
+
# Public: Deletes the Fusion metadata related to a VM. The VM should not be
|
10
|
+
# running when this method is called. It's highly recommended to call this
|
11
|
+
# method without the Fusion GUI application running. If the Fusion GUI is
|
12
|
+
# running this method should succeed, but it's been observed that Fusion
|
13
|
+
# will recreate the metadata which is deleted. This leads to 'missing' VMs
|
14
|
+
# in the Fusion GUI.
|
15
|
+
#
|
16
|
+
# vm_path - The absolute path to the directory of a VM.
|
17
|
+
#
|
18
|
+
# Examples
|
19
|
+
#
|
20
|
+
# Fission::Metadata.delete_vm_info '/vms/foo.vmwarevm'
|
21
|
+
#
|
22
|
+
# Returns nothing.
|
8
23
|
def self.delete_vm_info(vm_path)
|
9
24
|
metadata = new
|
10
25
|
metadata.load
|
@@ -13,24 +28,62 @@ module Fission
|
|
13
28
|
metadata.save
|
14
29
|
end
|
15
30
|
|
31
|
+
# Public: Reads the configured metadata file and populates the content
|
32
|
+
# variable with native ruby types.
|
33
|
+
#
|
34
|
+
# Examples
|
35
|
+
#
|
36
|
+
# metadata.load
|
37
|
+
#
|
38
|
+
# Returns nothing.
|
16
39
|
def load
|
17
|
-
raw_data = CFPropertyList::List.new :file => Fission.config
|
40
|
+
raw_data = CFPropertyList::List.new :file => Fission.config['plist_file']
|
18
41
|
@content = CFPropertyList.native_types raw_data.value
|
19
42
|
end
|
20
43
|
|
44
|
+
# Public: Saves a new version of the metadata file with the data in the
|
45
|
+
# content variable.
|
46
|
+
#
|
47
|
+
# Examples
|
48
|
+
#
|
49
|
+
# metadata.save
|
50
|
+
#
|
51
|
+
# Returns nothing.
|
21
52
|
def save
|
22
53
|
new_content = CFPropertyList::List.new
|
23
54
|
new_content.value = CFPropertyList.guess @content
|
24
|
-
new_content.save Fission.config
|
55
|
+
new_content.save Fission.config['plist_file'],
|
25
56
|
CFPropertyList::List::FORMAT_BINARY
|
26
57
|
end
|
27
58
|
|
59
|
+
# Public: Deletes the VM information from the 'restart document path'
|
60
|
+
# metadata. The 'restart document path' dictates which GUI consoles to
|
61
|
+
# display when Fusion starts.
|
62
|
+
#
|
63
|
+
# vm_path - The absolute path to the directory of a VM.
|
64
|
+
#
|
65
|
+
# Examples
|
66
|
+
#
|
67
|
+
# metadata.delete_vm_restart_document 'vms/foo.vmwarevm'
|
68
|
+
#
|
69
|
+
# Returns nothing.
|
28
70
|
def delete_vm_restart_document(vm_path)
|
29
71
|
if @content.has_key?('PLRestartDocumentPaths')
|
30
72
|
@content['PLRestartDocumentPaths'].delete_if { |p| p == vm_path }
|
31
73
|
end
|
32
74
|
end
|
33
75
|
|
76
|
+
# Public: Deletes the VM information from the 'favorites list' metadata.
|
77
|
+
# The 'favorites list' dictates which VMs are displayed in the Fusion VM
|
78
|
+
# libarary.
|
79
|
+
#
|
80
|
+
# vm_path - The absolute path to the directory of a VM.
|
81
|
+
#
|
82
|
+
# Examples
|
83
|
+
#
|
84
|
+
# metadata.delete_favorite_entry '/vms/foo.vmwarevm'
|
85
|
+
#
|
86
|
+
# Returns nothing.
|
34
87
|
def delete_vm_favorite_entry(vm_path)
|
35
88
|
@content['VMFavoritesListDefaults2'].delete_if { |vm| vm['path'] == vm_path }
|
36
89
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Fission
|
2
|
+
class Response
|
3
|
+
|
4
|
+
# Public: Gets/Sets the code (Integer).
|
5
|
+
attr_accessor :code
|
6
|
+
|
7
|
+
# Public: Gets/Sets the message (String).
|
8
|
+
attr_accessor :message
|
9
|
+
|
10
|
+
# Public: Gets/Sets the data (can be any of type as needed).
|
11
|
+
attr_accessor :data
|
12
|
+
|
13
|
+
# Public: Initialize a Response object.
|
14
|
+
#
|
15
|
+
# args - Hash of arguments:
|
16
|
+
# :code - Integer which denotes the code of the Response. This is
|
17
|
+
# similar in concept to command line exit codes. The
|
18
|
+
# convention is that 0 denotes success and any other value
|
19
|
+
# is unsuccessful (default: 1).
|
20
|
+
# :message - String which denotes the message of the Response. The
|
21
|
+
# convention is that this should only be used when the
|
22
|
+
# Response is unsuccessful (default: '').
|
23
|
+
# :data - Any valid ruby object. This is used to convey any
|
24
|
+
# data that needs to be used by a caller. The convention
|
25
|
+
# is that this should only be used when the Response is
|
26
|
+
# successful (default nil).
|
27
|
+
#
|
28
|
+
# Examples
|
29
|
+
#
|
30
|
+
# Response.new :code => 0, :data => [1, 2, 3, 4]
|
31
|
+
#
|
32
|
+
# Response.new :code => 0, :data => true
|
33
|
+
#
|
34
|
+
# Response.new :code => 5, :message => 'Something went wrong'
|
35
|
+
#
|
36
|
+
# Returns a new Response instance.
|
37
|
+
def initialize(args={})
|
38
|
+
@code = args.fetch :code, 1
|
39
|
+
@message = args.fetch :message, ''
|
40
|
+
@data = args.fetch :data, nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Public: Helper method to determine if a response is successful or not.
|
44
|
+
#
|
45
|
+
# Examples
|
46
|
+
#
|
47
|
+
# response.successful?
|
48
|
+
# # => true
|
49
|
+
#
|
50
|
+
# response.successful?
|
51
|
+
# # => false
|
52
|
+
#
|
53
|
+
# Returns a Boolean.
|
54
|
+
# Returns true if the code is 0.
|
55
|
+
# Returns false if the code is any other value.
|
56
|
+
def successful?
|
57
|
+
@code == 0
|
58
|
+
end
|
59
|
+
|
60
|
+
# Public: Helper method to create a new Response object when running a
|
61
|
+
# command line tool.
|
62
|
+
#
|
63
|
+
# cmd_output - This should be the output of the command.
|
64
|
+
#
|
65
|
+
# Returns a Response.
|
66
|
+
# The Response's code attribute will be set to the value of '$?'. The
|
67
|
+
# Response's message attribute will be set to the provided command output
|
68
|
+
# if, and only if, the Response is unsuccessful.
|
69
|
+
def self.from_command(cmd_output)
|
70
|
+
response = new :code => $?.exitstatus
|
71
|
+
response.message = cmd_output unless response.successful?
|
72
|
+
response
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
data/lib/fission/ui.rb
CHANGED
@@ -1,19 +1,68 @@
|
|
1
1
|
module Fission
|
2
2
|
class UI
|
3
|
+
|
4
|
+
# Internal: Returns the stdout value.
|
3
5
|
attr_reader :stdout
|
4
6
|
|
7
|
+
# Internal: Initialize a UI object.
|
8
|
+
#
|
9
|
+
# stdout - The object to use for stdout (default: $stdout). This provides
|
10
|
+
# an easy way to capture/silence output if needed.
|
11
|
+
#
|
12
|
+
# Examples
|
13
|
+
#
|
14
|
+
# Fission::UI.new
|
15
|
+
#
|
16
|
+
# str_io = StringIO.new
|
17
|
+
# Fission::UI.new str_io
|
5
18
|
def initialize(stdout=$stdout)
|
6
19
|
@stdout = stdout
|
7
20
|
end
|
8
21
|
|
22
|
+
# Internal: Outputs the specified argument to the configured stdout object.
|
23
|
+
# The 'puts' method will be called on the stdout object.
|
24
|
+
#
|
25
|
+
# s - The String to output.
|
26
|
+
#
|
27
|
+
# Examples
|
28
|
+
#
|
29
|
+
# ui.output "foo bar\n"
|
30
|
+
#
|
31
|
+
# Returns nothing.
|
9
32
|
def output(s)
|
10
33
|
@stdout.puts s
|
11
34
|
end
|
12
35
|
|
36
|
+
# Internal: Outputs the specified arguments printf style. The 'printf'
|
37
|
+
# method will be called on the stdout object. Currently, this assuems there
|
38
|
+
# are two data items.
|
39
|
+
#
|
40
|
+
# string - The printf String.
|
41
|
+
# key - The String for the first data item.
|
42
|
+
# value - The String for the second data item.
|
43
|
+
#
|
44
|
+
# Examples
|
45
|
+
#
|
46
|
+
# ui.output_printf "%s %s\n", 'foo', bar
|
47
|
+
#
|
48
|
+
# Returns nothing.
|
13
49
|
def output_printf(string, key, value)
|
14
50
|
@stdout.send :printf, string, key, value
|
15
51
|
end
|
16
52
|
|
53
|
+
# Internal: Outputs the specified argument to the configured stdout object
|
54
|
+
# and exits with the specified exit code.
|
55
|
+
#
|
56
|
+
# s - The String to output.
|
57
|
+
# exit_code - The Integer exit code.
|
58
|
+
#
|
59
|
+
# Examples
|
60
|
+
#
|
61
|
+
# ui.output_and_exit 'something went wrong', 99
|
62
|
+
#
|
63
|
+
# ui.output_and_exit 'all done', 0
|
64
|
+
#
|
65
|
+
# Returns nothing.
|
17
66
|
def output_and_exit(s, exit_code)
|
18
67
|
output s
|
19
68
|
exit exit_code
|
data/lib/fission/version.rb
CHANGED
data/lib/fission/vm.rb
CHANGED
@@ -1,158 +1,654 @@
|
|
1
1
|
module Fission
|
2
2
|
class VM
|
3
|
+
|
4
|
+
# Public: Gets the name of the VM as a String.
|
3
5
|
attr_reader :name
|
4
6
|
|
5
7
|
def initialize(name)
|
6
8
|
@name = name
|
7
9
|
end
|
8
10
|
|
11
|
+
# Public: Creates a snapshot for a VM. The VM must be running in order
|
12
|
+
# to create a snapshot. Snapshot names must be unique.
|
13
|
+
#
|
14
|
+
# name - The desired name of the snapshot. The name must be unique.
|
15
|
+
#
|
16
|
+
# Examples
|
17
|
+
#
|
18
|
+
# @vm.create_snapshot('foo_snap_1')
|
19
|
+
#
|
20
|
+
# Returns a Response with the result.
|
21
|
+
# If successful, the Response's data attribute will be nil.
|
22
|
+
# If there is an error, an unsuccessful Response will be returned.
|
9
23
|
def create_snapshot(name)
|
10
|
-
|
11
|
-
|
24
|
+
unless exists?
|
25
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
26
|
+
end
|
12
27
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
28
|
+
running_response = running?
|
29
|
+
return running_response unless running_response.successful?
|
30
|
+
|
31
|
+
unless running_response.data
|
32
|
+
message = 'The VM must be running in order to take a snapshot.'
|
33
|
+
return Response.new :code => 1, :message => message
|
18
34
|
end
|
35
|
+
|
36
|
+
conf_file_response = conf_file
|
37
|
+
return conf_file_response unless conf_file_response.successful?
|
38
|
+
|
39
|
+
snapshots_response = snapshots
|
40
|
+
return snapshots_response unless snapshots_response.successful?
|
41
|
+
|
42
|
+
if snapshots_response.data.include? name
|
43
|
+
message = "There is already a snapshot named '#{name}'."
|
44
|
+
return Response.new :code => 1, :message => message
|
45
|
+
end
|
46
|
+
|
47
|
+
command = "#{vmrun_cmd} snapshot "
|
48
|
+
command << "#{conf_file_response.data} \"#{name}\" 2>&1"
|
49
|
+
|
50
|
+
Response.from_command(`#{command}`)
|
19
51
|
end
|
20
52
|
|
53
|
+
# Public: Reverts the VM to the specified snapshot. The snapshot to revert
|
54
|
+
# to must exist and the Fusion GUI must not be running.
|
55
|
+
#
|
56
|
+
# name - The snapshot name to revert to.
|
57
|
+
#
|
58
|
+
# Examples
|
59
|
+
#
|
60
|
+
# @vm.revert_to_snapshot('foo_snap_1')
|
61
|
+
#
|
62
|
+
# Returns a Response with the result.
|
63
|
+
# If successful, the Response's data attribute will be nil.
|
64
|
+
# If there is an error, an unsuccessful Response will be returned.
|
21
65
|
def revert_to_snapshot(name)
|
22
|
-
|
23
|
-
|
66
|
+
unless exists?
|
67
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
68
|
+
end
|
24
69
|
|
25
|
-
if
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
70
|
+
if Fusion.running?
|
71
|
+
message = 'It looks like the Fusion GUI is currently running. '
|
72
|
+
message << 'A VM cannot be reverted to a snapshot when the Fusion GUI is running. '
|
73
|
+
message << 'Exit the Fusion GUI and try again.'
|
74
|
+
return Response.new :code => 1, :message => message
|
30
75
|
end
|
76
|
+
|
77
|
+
conf_file_response = conf_file
|
78
|
+
return conf_file_response unless conf_file_response.successful?
|
79
|
+
|
80
|
+
snapshots_response = snapshots
|
81
|
+
return snapshots_response unless snapshots_response.successful?
|
82
|
+
|
83
|
+
unless snapshots_response.data.include? name
|
84
|
+
message = "Unable to find a snapshot named '#{name}'."
|
85
|
+
return Response.new :code => 1, :message => message
|
86
|
+
end
|
87
|
+
|
88
|
+
command = "#{vmrun_cmd} revertToSnapshot "
|
89
|
+
command << "#{conf_file_response.data} \"#{name}\" 2>&1"
|
90
|
+
|
91
|
+
Response.from_command(`#{command}`)
|
31
92
|
end
|
32
93
|
|
94
|
+
# Public: List the snapshots for a VM.
|
95
|
+
#
|
96
|
+
# Examples
|
97
|
+
#
|
98
|
+
# @vm.snapshots.data
|
99
|
+
# # => ['snap 1', 'snap 2']
|
100
|
+
#
|
101
|
+
# Returns a Response with the result.
|
102
|
+
# If successful, the Repsonse's data attribute will be an Array of the
|
103
|
+
# snapshot names (String).
|
104
|
+
# If there is an error, an unsuccessful Response will be returned.
|
33
105
|
def snapshots
|
34
|
-
|
106
|
+
unless exists?
|
107
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
108
|
+
end
|
109
|
+
|
110
|
+
conf_file_response = conf_file
|
111
|
+
return conf_file_response unless conf_file_response.successful?
|
112
|
+
|
113
|
+
command = "#{vmrun_cmd} listSnapshots "
|
114
|
+
command << "#{conf_file_response.data} 2>&1"
|
35
115
|
output = `#{command}`
|
36
116
|
|
37
|
-
|
117
|
+
response = Response.new :code => $?.exitstatus
|
118
|
+
|
119
|
+
if response.successful?
|
38
120
|
snaps = output.split("\n").select { |s| !s.include? 'Total snapshots:' }
|
39
|
-
snaps.map { |s| s.strip }
|
121
|
+
response.data = snaps.map { |s| s.strip }
|
40
122
|
else
|
41
|
-
|
42
|
-
Fission.ui.output_and_exit "The error was:\n#{output}", 1
|
123
|
+
response.message = output
|
43
124
|
end
|
125
|
+
|
126
|
+
response
|
44
127
|
end
|
45
128
|
|
46
|
-
|
47
|
-
|
129
|
+
# Public: Starts a VM. The VM must not be running in order to start it.
|
130
|
+
#
|
131
|
+
# options - Hash of options:
|
132
|
+
# :headless - Boolean which specifies to start the VM without a
|
133
|
+
# GUI console. The Fusion GUI must not be running in
|
134
|
+
# order to start the VM headless.
|
135
|
+
# (default: false)
|
136
|
+
#
|
137
|
+
# Examples
|
138
|
+
#
|
139
|
+
# @vm.start
|
140
|
+
#
|
141
|
+
# @vm.start :headless => true
|
142
|
+
#
|
143
|
+
# Returns a Response with the result.
|
144
|
+
# If successful, the Response's data attribute will be nil.
|
145
|
+
# If there is an error, an unsuccessful Response will be returned.
|
146
|
+
def start(options={})
|
147
|
+
unless exists?
|
148
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
149
|
+
end
|
48
150
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
151
|
+
running_response = running?
|
152
|
+
return running_response unless running_response.successful?
|
153
|
+
|
154
|
+
if running_response.data
|
155
|
+
return Response.new :code => 1, :message => 'VM is already running'
|
53
156
|
end
|
54
157
|
|
55
|
-
|
158
|
+
conf_file_response = conf_file
|
159
|
+
return conf_file_response unless conf_file_response.successful?
|
56
160
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
161
|
+
unless options[:headless].blank?
|
162
|
+
if Fusion.running?
|
163
|
+
message = 'It looks like the Fusion GUI is currently running. '
|
164
|
+
message << 'A VM cannot be started in headless mode when the Fusion GUI is running. '
|
165
|
+
message << 'Exit the Fusion GUI and try again.'
|
166
|
+
return Response.new :code => 1, :message => message
|
167
|
+
end
|
61
168
|
end
|
169
|
+
|
170
|
+
command = "#{vmrun_cmd} start "
|
171
|
+
command << "#{conf_file_response.data} "
|
172
|
+
|
173
|
+
command << (options[:headless].blank? ? 'gui ' : 'nogui ')
|
174
|
+
command << '2>&1'
|
175
|
+
|
176
|
+
Response.from_command(`#{command}`)
|
62
177
|
end
|
63
178
|
|
64
|
-
|
65
|
-
|
66
|
-
|
179
|
+
# Public: Stops a VM. The VM must be running in order to stop it.
|
180
|
+
#
|
181
|
+
# options - Hash of options:
|
182
|
+
# :hard - Boolean which specifies to power off the VM (instead of
|
183
|
+
# attempting to initiate a graceful shutdown). This is
|
184
|
+
# the equivalent of passing 'hard' to the vmrun stop
|
185
|
+
# command.
|
186
|
+
# (default: false)
|
187
|
+
#
|
188
|
+
# Examples
|
189
|
+
#
|
190
|
+
# @vm.stop
|
191
|
+
#
|
192
|
+
# @vm.stop :hard => true
|
193
|
+
#
|
194
|
+
# Returns a Response with the result.
|
195
|
+
# If successful, the Response's data attribute will be nil.
|
196
|
+
# If there is an error, an unsuccessful Response will be returned.
|
197
|
+
def stop(options={})
|
198
|
+
unless exists?
|
199
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
200
|
+
end
|
67
201
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
202
|
+
running_response = running?
|
203
|
+
return running_response unless running_response.successful?
|
204
|
+
|
205
|
+
unless running_response.data
|
206
|
+
return Response.new :code => 1, :message => 'VM is not running'
|
72
207
|
end
|
208
|
+
|
209
|
+
conf_file_response = conf_file
|
210
|
+
return conf_file_response unless conf_file_response.successful?
|
211
|
+
|
212
|
+
command = "#{vmrun_cmd} stop "
|
213
|
+
command << "#{conf_file_response.data} "
|
214
|
+
command << 'hard ' unless options[:hard].blank?
|
215
|
+
command << '2>&1'
|
216
|
+
|
217
|
+
Response.from_command(`#{command}`)
|
73
218
|
end
|
74
219
|
|
220
|
+
# Public: Suspends a VM. The VM must be running in order to suspend it.
|
221
|
+
#
|
222
|
+
# Examples
|
223
|
+
#
|
224
|
+
# @vm.suspend
|
225
|
+
#
|
226
|
+
# Returns a Response with the result.
|
227
|
+
# If successful, the Response's data attribute will be nil.
|
228
|
+
# If there is an error, an unsuccessful Response will be returned.
|
75
229
|
def suspend
|
76
|
-
|
77
|
-
|
230
|
+
unless exists?
|
231
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
232
|
+
end
|
233
|
+
|
234
|
+
running_response = running?
|
235
|
+
return running_response unless running_response.successful?
|
236
|
+
|
237
|
+
unless running_response.data
|
238
|
+
return Response.new :code => 1, :message => 'VM is not running'
|
239
|
+
end
|
240
|
+
|
241
|
+
conf_file_response = conf_file
|
242
|
+
return conf_file_response unless conf_file_response.successful?
|
243
|
+
|
244
|
+
command = "#{vmrun_cmd} suspend "
|
245
|
+
command << "#{conf_file_response.data} 2>&1"
|
246
|
+
|
247
|
+
Response.from_command(`#{command}`)
|
248
|
+
end
|
249
|
+
|
250
|
+
# Public: Provides the MAC addresses for a VM.
|
251
|
+
#
|
252
|
+
# Examples:
|
253
|
+
#
|
254
|
+
# @vm.mac_addresses.data
|
255
|
+
# # => ['00:0c:29:1d:6a:64', '00:0c:29:1d:6a:75']
|
256
|
+
#
|
257
|
+
# Returns a Response with the result.
|
258
|
+
# If successful, the Response's data attribute will be an Array of the MAC
|
259
|
+
# addresses found. If no MAC addresses are found, the Response's data
|
260
|
+
# attribute will be an empty Array.
|
261
|
+
# If there is an error, an unsuccessful Response will be returned.
|
262
|
+
def mac_addresses
|
263
|
+
network_response = network_info
|
264
|
+
return network_response unless network_response.successful?
|
265
|
+
|
266
|
+
response = Response.new :code => 0
|
267
|
+
response.data = network_response.data.values.collect { |n| n['mac_address'] }
|
268
|
+
|
269
|
+
response
|
270
|
+
end
|
271
|
+
|
272
|
+
# Public: Network information for a VM. Includes interface name, associated
|
273
|
+
# MAC address, and IP address (if applicable).
|
274
|
+
#
|
275
|
+
# Examples:
|
276
|
+
#
|
277
|
+
# # if IP addresses are found in the Fusion DHCP lease file
|
278
|
+
# response = @vm.network_info.data
|
279
|
+
# # => { 'ethernet0' => { 'mac_address' => '00:0c:29:1d:6a:64',
|
280
|
+
# 'ip_address' => '127.0.0.1' },
|
281
|
+
# 'ethernet1' => { 'mac_address' => '00:0c:29:1d:6a:75',
|
282
|
+
# 'ip_address' => '127.0.0.2' } }
|
283
|
+
#
|
284
|
+
# # if IP addresses are not found in the Fusion DHCP lease file
|
285
|
+
# response = @vm.network_info.data
|
286
|
+
# # => { 'ethernet0' => { 'mac_address' => '00:0c:29:1d:6a:64',
|
287
|
+
# 'ip_address' => nil },
|
288
|
+
# 'ethernet1' => { 'mac_address' => '00:0c:29:1d:6a:75',
|
289
|
+
# 'ip_address' => nil } }
|
290
|
+
#
|
291
|
+
# Returns a Response with the result.
|
292
|
+
# If successful, the Response's data attribute will be a Hash with the
|
293
|
+
# interface identifiers as the keys and the associated MAC address. If an
|
294
|
+
# IP address was found in the Fusion DHCP lease file, then it will
|
295
|
+
# be included. If an IP address was not found, then the IP address value
|
296
|
+
# will be nil. If there are no network interfaces, the Response's data
|
297
|
+
# attribute will be an empty Hash.
|
298
|
+
# If there is an error, an unsuccessful Response will be returned.
|
299
|
+
def network_info
|
300
|
+
conf_file_response = conf_file
|
301
|
+
return conf_file_response unless conf_file_response.successful?
|
302
|
+
|
303
|
+
response = Response.new :code => 0, :data => {}
|
304
|
+
|
305
|
+
interface_pattern = /^ethernet\d+/
|
306
|
+
mac_pattern = /(\w\w[:-]\w\w[:-]\w\w[:-]\w\w[:-]\w\w[:-]\w\w)/
|
307
|
+
|
308
|
+
File.open conf_file_response.data, 'r' do |f|
|
309
|
+
f.grep(mac_pattern).each do |line|
|
310
|
+
int = line.scan(interface_pattern)[0]
|
311
|
+
mac = line.scan(mac_pattern)[0].first
|
312
|
+
response.data[int] = {}
|
313
|
+
response.data[int]['mac_address'] = mac
|
314
|
+
|
315
|
+
lease_response = Fission::Lease.find_by_mac_address mac
|
316
|
+
return lease_response unless lease_response.successful?
|
317
|
+
|
318
|
+
response.data[int]['ip_address'] = nil
|
319
|
+
|
320
|
+
if lease_response.data
|
321
|
+
response.data[int]['ip_address'] = lease_response.data.ip_address
|
322
|
+
end
|
78
323
|
|
79
|
-
|
80
|
-
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
response
|
328
|
+
end
|
329
|
+
|
330
|
+
# Public: Provides the state of the VM.
|
331
|
+
#
|
332
|
+
# Examples
|
333
|
+
#
|
334
|
+
# @vm.state.data
|
335
|
+
# # => 'running'
|
336
|
+
#
|
337
|
+
# @vm.state.data
|
338
|
+
# # => 'not running'
|
339
|
+
#
|
340
|
+
# @vm.state.data
|
341
|
+
# # => 'suspended'
|
342
|
+
#
|
343
|
+
# Returns a Response with the result.
|
344
|
+
# If the Response is successful, the Response's data attribute will
|
345
|
+
# be a String of the state. If the VM is currently powered on, the state
|
346
|
+
# will be 'running'. If the VM is deemed to be suspended, the state will be
|
347
|
+
# 'suspended'. If the VM is not running and not deemed to be suspended, the
|
348
|
+
# state will be 'not running'.
|
349
|
+
# If there is an error, an unsuccessful Response will be returned.
|
350
|
+
def state
|
351
|
+
running_response = running?
|
352
|
+
return running_response unless running_response.successful?
|
353
|
+
|
354
|
+
response = Response.new :code => 0, :data => 'not running'
|
355
|
+
|
356
|
+
if running_response.data
|
357
|
+
response.data = 'running'
|
81
358
|
else
|
82
|
-
|
359
|
+
suspended_response = suspended?
|
360
|
+
return suspended_response unless suspended_response.successful?
|
361
|
+
|
362
|
+
response.data = 'suspended' if suspended_response.data
|
363
|
+
end
|
364
|
+
|
365
|
+
response
|
366
|
+
end
|
367
|
+
|
368
|
+
# Public: Determines if the VM exists or not. This method looks for the
|
369
|
+
# VM's conf file ('.vmx') to determine if the VM exists or not.
|
370
|
+
#
|
371
|
+
# Examples
|
372
|
+
#
|
373
|
+
# @vm.exists?
|
374
|
+
# # => true
|
375
|
+
#
|
376
|
+
# Returns a Boolean.
|
377
|
+
def exists?
|
378
|
+
conf_file.successful?
|
379
|
+
end
|
380
|
+
|
381
|
+
# Public: Determines if a VM is suspended.
|
382
|
+
#
|
383
|
+
# Examples
|
384
|
+
#
|
385
|
+
# @vm.suspended?.data
|
386
|
+
# # => true
|
387
|
+
#
|
388
|
+
# Returns a Response with the result.
|
389
|
+
# If successful, the Response's data attribute will be a Boolean. If the VM
|
390
|
+
# is not running, then this method will look for a '.vmem' file in the VM's
|
391
|
+
# directory. If a '.vmem' file exists and it matches the name of the VM,
|
392
|
+
# then the VM is considered to be suspended. If the VM is running or if a
|
393
|
+
# matching '.vmem' file is not found, then the VM is not considered to be
|
394
|
+
# suspended.
|
395
|
+
# If there is an error, an unsuccessful Response will be returned.
|
396
|
+
def suspended?
|
397
|
+
running_response = running?
|
398
|
+
return running_response unless running_response.successful?
|
399
|
+
|
400
|
+
response = Response.new :code => 0, :data => false
|
401
|
+
response.data = suspend_file_exists? unless running_response.data
|
402
|
+
|
403
|
+
response
|
404
|
+
end
|
405
|
+
|
406
|
+
# Public: Determines if a VM has a suspend file ('.vmem') in it's directory.
|
407
|
+
# This only looks for a suspend file which matches the name of the VM.
|
408
|
+
#
|
409
|
+
# Examples
|
410
|
+
#
|
411
|
+
# @vm.suspend_file_exists?
|
412
|
+
# # => true
|
413
|
+
#
|
414
|
+
# Returns a Boolean.
|
415
|
+
def suspend_file_exists?
|
416
|
+
File.file? File.join(path, "#{@name}.vmem")
|
417
|
+
end
|
418
|
+
|
419
|
+
# Public: Determines if a VM is running.
|
420
|
+
#
|
421
|
+
# Examples
|
422
|
+
#
|
423
|
+
# @vm.running?.data
|
424
|
+
# # => true
|
425
|
+
#
|
426
|
+
# Returns a Response with the result.
|
427
|
+
# If successful, the Response's data attribute will be a Boolean.
|
428
|
+
# If there is an error, an unsuccessful Response will be returned.
|
429
|
+
def running?
|
430
|
+
all_running_response = self.class.all_running
|
431
|
+
return all_running_response unless all_running_response.successful?
|
432
|
+
|
433
|
+
response = Response.new :code => 0, :data => false
|
434
|
+
|
435
|
+
if all_running_response.data.collect { |v| v.name }.include? @name
|
436
|
+
response.data = true
|
83
437
|
end
|
438
|
+
|
439
|
+
response
|
84
440
|
end
|
85
441
|
|
442
|
+
# Public: Determines the path to the VM's config file ('.vmx').
|
443
|
+
#
|
444
|
+
# Examples
|
445
|
+
#
|
446
|
+
# @vm.conf_file.data
|
447
|
+
# # => '/my_vms/foo/foo.vmx'
|
448
|
+
#
|
449
|
+
# Returns a Response with the result.
|
450
|
+
# If successful, the Response's data attribute will be a String which will
|
451
|
+
# be escaped for spaces (' ').
|
452
|
+
# If there is a single '.vmx' file in the VM's directory, regardless if
|
453
|
+
# the name of '.vmx' file matches the VM name, the Response's data
|
454
|
+
# attribute will the be the path to the '.vmx' file.
|
455
|
+
# If there are multiple '.vmx' files found in the VM's directory, there are
|
456
|
+
# a couple of different possible outcomes.
|
457
|
+
# If one of the file names matches the VM directory name, then the
|
458
|
+
# Response's data attribute will be the path to the matching '.vmx' file.
|
459
|
+
# If none of the file names match the VM directory name, then this is deemed
|
460
|
+
# an error condition and an unsuccessful Response will be returned.
|
461
|
+
# If there is an error, an unsuccessful Response will be returned.
|
86
462
|
def conf_file
|
87
|
-
vmx_path = File.join
|
88
|
-
conf_files = Dir.glob
|
463
|
+
vmx_path = File.join path, "*.vmx"
|
464
|
+
conf_files = Dir.glob vmx_path
|
465
|
+
|
466
|
+
response = Response.new
|
89
467
|
|
90
468
|
case conf_files.count
|
91
469
|
when 0
|
92
|
-
|
470
|
+
response.code = 1
|
471
|
+
response.message = "Unable to find a config file for VM '#{@name}' (in '#{vmx_path}')"
|
93
472
|
when 1
|
94
|
-
|
473
|
+
response.code = 0
|
474
|
+
response.data = conf_files.first
|
95
475
|
else
|
96
476
|
if conf_files.include?(File.join(File.dirname(vmx_path), "#{@name}.vmx"))
|
97
|
-
|
477
|
+
response.code = 0
|
478
|
+
response.data = File.join(File.dirname(vmx_path), "#{@name}.vmx")
|
98
479
|
else
|
480
|
+
response.code = 1
|
99
481
|
output = "Multiple config files found for VM '#{@name}' ("
|
100
482
|
output << conf_files.sort.map { |f| "'#{File.basename(f)}'" }.join(', ')
|
101
483
|
output << " in '#{File.dirname(vmx_path)}')"
|
102
|
-
|
484
|
+
response.message = output
|
103
485
|
end
|
104
486
|
end
|
487
|
+
|
488
|
+
response.data.gsub! ' ', '\ ' if response.successful?
|
489
|
+
|
490
|
+
response
|
105
491
|
end
|
106
492
|
|
493
|
+
# Public: Provides the expected path to a VM's directory. This does not
|
494
|
+
# imply that the VM or path exists.
|
495
|
+
#
|
496
|
+
# name - The name of the VM to provide the path for.
|
497
|
+
#
|
498
|
+
# Examples
|
499
|
+
#
|
500
|
+
# @vm.path
|
501
|
+
# # => '/vm/foo.vmwarevm'
|
502
|
+
#
|
503
|
+
# Returns the path (String) to the VM's directory.
|
504
|
+
def path
|
505
|
+
File.join Fission.config['vm_dir'], "#{@name}.vmwarevm"
|
506
|
+
end
|
507
|
+
|
508
|
+
# Public: Provides all of the VMs which are located in the VM directory.
|
509
|
+
#
|
510
|
+
# Examples
|
511
|
+
#
|
512
|
+
# Fission::VM.all.data
|
513
|
+
# # => [<Fission::VM:0x007fd6fa24c5d8 @name="foo">,
|
514
|
+
# <Fission::VM:0x007fd6fa23c5e8 @name="bar">]
|
515
|
+
#
|
516
|
+
# Returns a Response with the result.
|
517
|
+
# If successful, the Response's data attribute will be an Array of VM
|
518
|
+
# objects. If no VMs are found, the Response's data attribute will be an
|
519
|
+
# empty Array.
|
520
|
+
# If there is an error, an unsuccessful Response will be returned.
|
107
521
|
def self.all
|
108
|
-
vm_dirs = Dir[File.join Fission.config
|
522
|
+
vm_dirs = Dir[File.join Fission.config['vm_dir'], '*.vmwarevm'].select do |d|
|
109
523
|
File.directory? d
|
110
524
|
end
|
111
525
|
|
112
|
-
|
526
|
+
response = Response.new :code => 0
|
527
|
+
response.data = vm_dirs.collect { |d| new(File.basename d, '.vmwarevm') }
|
528
|
+
|
529
|
+
response
|
113
530
|
end
|
114
531
|
|
532
|
+
# Public: Provides all of the VMs which are currently running.
|
533
|
+
#
|
534
|
+
# Examples
|
535
|
+
#
|
536
|
+
# Fission::VM.all_running.data
|
537
|
+
# # => [<Fission::VM:0x007fd6fa24c5d8 @name="foo">,
|
538
|
+
# <Fission::VM:0x007fd6fa23c5e8 @name="bar">]
|
539
|
+
#
|
540
|
+
# Returns a Response with the result.
|
541
|
+
# If successful, the Response's data attribute will be an Array of VM
|
542
|
+
# objects which are running. If no VMs are running, the Response's data
|
543
|
+
# attribute will be an empty Array.
|
544
|
+
# If there is an error, an unsuccessful Response will be returned.
|
115
545
|
def self.all_running
|
116
|
-
command = "#{Fission.config
|
546
|
+
command = "#{Fission.config['vmrun_cmd']} list"
|
117
547
|
|
118
548
|
output = `#{command}`
|
119
549
|
|
120
|
-
|
550
|
+
response = Response.new :code => $?.exitstatus
|
551
|
+
|
552
|
+
if response.successful?
|
121
553
|
vms = output.split("\n").select do |vm|
|
122
554
|
vm.include?('.vmx') && File.exists?(vm) && File.extname(vm) == '.vmx'
|
123
555
|
end
|
124
556
|
|
125
|
-
vms.
|
557
|
+
response.data = vms.collect do |vm|
|
558
|
+
new File.basename(File.dirname(vm), '.vmwarevm')
|
559
|
+
end
|
126
560
|
else
|
127
|
-
|
561
|
+
response.message = output
|
128
562
|
end
|
129
|
-
end
|
130
563
|
|
131
|
-
|
132
|
-
File.directory? path(vm_name)
|
564
|
+
response
|
133
565
|
end
|
134
566
|
|
135
|
-
|
136
|
-
|
137
|
-
|
567
|
+
# Public: Creates a new VM which is a clone of an existing VM. As Fusion
|
568
|
+
# doesn't provide a native cloning mechanism, this is a best effort. This
|
569
|
+
# essentially is a directory copy with updates to relevant files. It's
|
570
|
+
# recommended to clone VMs which are not running.
|
571
|
+
#
|
572
|
+
# source_vm_name - The name of the VM to clone.
|
573
|
+
# target_vm_name - The name of the VM to be created.
|
574
|
+
#
|
575
|
+
# Examples
|
576
|
+
#
|
577
|
+
# Fission::VM.clone 'foo', 'bar'
|
578
|
+
#
|
579
|
+
# Returns a Response with the result.
|
580
|
+
# If successful, the Response's data attribute will be nil.
|
581
|
+
# If there is an error, an unsuccessful Response will be returned.
|
582
|
+
def self.clone(source_vm_name, target_vm_name)
|
583
|
+
source_vm = new source_vm_name
|
584
|
+
target_vm = new target_vm_name
|
585
|
+
|
586
|
+
unless source_vm.exists?
|
587
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
588
|
+
end
|
589
|
+
|
590
|
+
if target_vm.exists?
|
591
|
+
return Response.new :code => 1, :message => 'VM already exists'
|
592
|
+
end
|
138
593
|
|
139
|
-
|
140
|
-
Fission.ui.output "Cloning #{source_vm} to #{target_vm}"
|
141
|
-
FileUtils.cp_r path(source_vm), path(target_vm)
|
594
|
+
FileUtils.cp_r source_vm.path, target_vm.path
|
142
595
|
|
143
|
-
|
144
|
-
|
145
|
-
|
596
|
+
rename_vm_files source_vm.name, target_vm.name
|
597
|
+
update_config source_vm.name, target_vm.name
|
598
|
+
|
599
|
+
Response.new :code => 0
|
146
600
|
end
|
147
601
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
602
|
+
# Public: Deletes a VM. The VM must not be running in order to delete it.
|
603
|
+
# As there are a number issues with the Fusion command line tool for
|
604
|
+
# deleting VMs, this is a best effort. The VM must not be running when this
|
605
|
+
# method is called. This essentially deletes the VM directory and attempts
|
606
|
+
# to remove the relevant entries from the Fusion plist file. It's highly
|
607
|
+
# recommended to delete VMs without the Fusion GUI running. If the Fusion
|
608
|
+
# GUI is running this method should succeed, but it's been observed that
|
609
|
+
# Fusion will recreate the plist data which is deleted. This leads to
|
610
|
+
# 'missing' VMs in the Fusion GUI.
|
611
|
+
#
|
612
|
+
# Examples
|
613
|
+
#
|
614
|
+
# @vm.delete
|
615
|
+
#
|
616
|
+
# Returns a Response with the result.
|
617
|
+
# If successful, the Response's data attribute will be nil.
|
618
|
+
# If there is an error, an unsuccessful Response will be returned.
|
619
|
+
def delete
|
620
|
+
unless exists?
|
621
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
622
|
+
end
|
623
|
+
|
624
|
+
running_response = running?
|
625
|
+
return running_response unless running_response.successful?
|
626
|
+
|
627
|
+
if running_response.data
|
628
|
+
message = 'The VM must not be running in order to delete it.'
|
629
|
+
return Response.new :code => 1, :message => message
|
630
|
+
end
|
631
|
+
|
632
|
+
FileUtils.rm_rf path
|
633
|
+
Metadata.delete_vm_info path
|
634
|
+
|
635
|
+
Response.new :code => 0
|
152
636
|
end
|
153
637
|
|
154
638
|
private
|
639
|
+
# Internal: Renames the files of a newly cloned VM.
|
640
|
+
#
|
641
|
+
# from - The VM name that was used as the source of the clone.
|
642
|
+
# to - The name of the newly cloned VM.
|
643
|
+
#
|
644
|
+
# Examples
|
645
|
+
#
|
646
|
+
# Fission::VM.rename_vm_files 'foo', 'bar'
|
647
|
+
#
|
648
|
+
# Returns nothing.
|
155
649
|
def self.rename_vm_files(from, to)
|
650
|
+
to_vm = new to
|
651
|
+
|
156
652
|
files_to_rename(from, to).each do |file|
|
157
653
|
text_to_replace = File.basename(file, File.extname(file))
|
158
654
|
|
@@ -162,18 +658,34 @@ module Fission
|
|
162
658
|
end
|
163
659
|
end
|
164
660
|
|
165
|
-
unless File.exists?(File.join(path
|
166
|
-
FileUtils.mv File.join(path
|
167
|
-
File.join(path
|
661
|
+
unless File.exists?(File.join(to_vm.path, file.gsub(text_to_replace, to)))
|
662
|
+
FileUtils.mv File.join(to_vm.path, file),
|
663
|
+
File.join(to_vm.path, file.gsub(text_to_replace, to))
|
168
664
|
end
|
169
665
|
end
|
170
666
|
end
|
171
667
|
|
668
|
+
# Internal: Provides the list of files which need to be renamed in a newly
|
669
|
+
# cloned VM directory.
|
670
|
+
#
|
671
|
+
# from - The VM name that was used as the source of the clone.
|
672
|
+
# to - The name of the newly cloned VM.
|
673
|
+
#
|
674
|
+
# Examples
|
675
|
+
#
|
676
|
+
# Fission::VM.files_to_rename 'foo', 'bar'
|
677
|
+
# # => ['/vms/vm1/foo.vmdk', '/vms/vm1/foo.vmx', 'vms/vm1/blah.other']
|
678
|
+
#
|
679
|
+
# Returns an Array containing the paths (String) to the files to rename.
|
680
|
+
# The paths which match the from name will preceed any other files found in
|
681
|
+
# the newly cloned VM directory.
|
172
682
|
def self.files_to_rename(from, to)
|
683
|
+
to_vm = new to
|
684
|
+
|
173
685
|
files_which_match_source_vm = []
|
174
686
|
other_files = []
|
175
687
|
|
176
|
-
Dir.entries(path
|
688
|
+
Dir.entries(to_vm.path).each do |f|
|
177
689
|
unless f == '.' || f == '..'
|
178
690
|
f.include?(from) ? files_which_match_source_vm << f : other_files << f
|
179
691
|
end
|
@@ -182,19 +694,85 @@ module Fission
|
|
182
694
|
files_which_match_source_vm + other_files
|
183
695
|
end
|
184
696
|
|
697
|
+
# Internal: Provides the list of file extensions for VM related files.
|
698
|
+
#
|
699
|
+
# Examples
|
700
|
+
#
|
701
|
+
# Fission::VM.vm_file_extension
|
702
|
+
# # => ['.nvram', '.vmdk', '.vmem']
|
703
|
+
#
|
704
|
+
# Returns an Array containing the file extensions of VM realted files.
|
705
|
+
# The file extensions returned are Strings and include a '.'.
|
185
706
|
def self.vm_file_extensions
|
186
707
|
['.nvram', '.vmdk', '.vmem', '.vmsd', '.vmss', '.vmx', '.vmxf']
|
187
708
|
end
|
188
709
|
|
710
|
+
# Internal: Updates config files for a newly cloned VM. This will update any
|
711
|
+
# files with the extension of '.vmx', '.vmxf', and '.vmdk'. Any binary
|
712
|
+
# '.vmdk' files will be skipped.
|
713
|
+
#
|
714
|
+
# from - The VM name that was used as the source of the clone.
|
715
|
+
# to - The name of the newly cloned VM.
|
716
|
+
#
|
717
|
+
# Examples
|
718
|
+
#
|
719
|
+
# Fission::VM.update_config 'foo', 'bar'
|
720
|
+
#
|
721
|
+
# Returns nothing.
|
189
722
|
def self.update_config(from, to)
|
723
|
+
to_vm = new to
|
724
|
+
|
190
725
|
['.vmx', '.vmxf', '.vmdk'].each do |ext|
|
191
|
-
file = File.join path
|
726
|
+
file = File.join to_vm.path, "#{to}#{ext}"
|
192
727
|
|
193
728
|
unless File.binary?(file)
|
194
729
|
text = (File.read file).gsub from, to
|
195
730
|
File.open(file, 'w'){ |f| f.print text }
|
196
731
|
end
|
732
|
+
|
733
|
+
clean_up_conf_file(file) if ext == '.vmx'
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
# Internal: Cleans up the conf file (*.vmx) for a newly cloned VM. This
|
738
|
+
# includes removing generated MAC addresses, setting up for a new UUID, and
|
739
|
+
# disable VMware tools warning.
|
740
|
+
#
|
741
|
+
# conf_file_path - Aboslute path to the VM's conf file (.vmx).
|
742
|
+
#
|
743
|
+
# Examples
|
744
|
+
#
|
745
|
+
# VM.clean_up_conf_file '/vms/foo/foo.vmx'
|
746
|
+
#
|
747
|
+
# Returns nothing.
|
748
|
+
def self.clean_up_conf_file(conf_file_path)
|
749
|
+
conf_items_patterns = [ /^tools\.remindInstall.*\n/,
|
750
|
+
/^uuid\.action.*\n/,
|
751
|
+
/^ethernet\.+generatedAddress.*\n/ ]
|
752
|
+
|
753
|
+
content = File.read conf_file_path
|
754
|
+
|
755
|
+
conf_items_patterns.each do |pattern|
|
756
|
+
content.gsub(pattern, '').strip
|
197
757
|
end
|
758
|
+
|
759
|
+
content << "\n"
|
760
|
+
content << "tools.remindInstall = \"FALSE\"\n"
|
761
|
+
content << "uuid.action = \"create\"\n"
|
762
|
+
|
763
|
+
File.open(conf_file_path, 'w') { |f| f.print content }
|
764
|
+
end
|
765
|
+
|
766
|
+
# Internal: Helper for getting the configured vmrun_cmd value.
|
767
|
+
#
|
768
|
+
# Examples
|
769
|
+
#
|
770
|
+
# @vm.vmrun_cmd
|
771
|
+
# # => "/foo/bar/vmrun -T fusion"
|
772
|
+
#
|
773
|
+
# Returns a String for the configured value of Fission.config['vmrun_cmd'].
|
774
|
+
def vmrun_cmd
|
775
|
+
Fission.config['vmrun_cmd']
|
198
776
|
end
|
199
777
|
|
200
778
|
end
|