fission 0.4.0 → 0.5.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +12 -3
- data/README.md +45 -19
- data/bin/fission +1 -1
- data/fission.gemspec +3 -2
- data/lib/fission.rb +15 -0
- data/lib/fission/action/shell_executor.rb +37 -0
- data/lib/fission/action/snapshot/creator.rb +81 -0
- data/lib/fission/action/snapshot/deleter.rb +85 -0
- data/lib/fission/action/snapshot/lister.rb +90 -0
- data/lib/fission/action/snapshot/reverter.rb +81 -0
- data/lib/fission/action/vm/cloner.rb +191 -0
- data/lib/fission/action/vm/deleter.rb +73 -0
- data/lib/fission/action/vm/lister.rb +138 -0
- data/lib/fission/action/vm/starter.rb +88 -0
- data/lib/fission/action/vm/stopper.rb +79 -0
- data/lib/fission/action/vm/suspender.rb +68 -0
- data/lib/fission/cli.rb +21 -117
- data/lib/fission/command.rb +39 -0
- data/lib/fission/command/clone.rb +11 -6
- data/lib/fission/command/delete.rb +11 -6
- data/lib/fission/command/info.rb +62 -0
- data/lib/fission/command/snapshot_create.rb +9 -3
- data/lib/fission/command/snapshot_delete.rb +38 -0
- data/lib/fission/command/snapshot_list.rb +9 -3
- data/lib/fission/command/snapshot_revert.rb +9 -3
- data/lib/fission/command/start.rb +11 -6
- data/lib/fission/command/status.rb +9 -1
- data/lib/fission/command/stop.rb +9 -3
- data/lib/fission/command/suspend.rb +11 -6
- data/lib/fission/command_helpers.rb +18 -4
- data/lib/fission/command_line_parser.rb +189 -0
- data/lib/fission/config.rb +1 -1
- data/lib/fission/fusion.rb +3 -4
- data/lib/fission/lease.rb +2 -1
- data/lib/fission/metadata.rb +6 -1
- data/lib/fission/response.rb +17 -9
- data/lib/fission/version.rb +1 -1
- data/lib/fission/vm.rb +142 -382
- data/lib/fission/vm_configuration.rb +79 -0
- data/spec/fission/action/execute_shell_command_spec.rb +25 -0
- data/spec/fission/action/snapshot/creator_spec.rb +77 -0
- data/spec/fission/action/snapshot/deleter_spec.rb +84 -0
- data/spec/fission/action/snapshot/lister_spec.rb +67 -0
- data/spec/fission/action/snapshot/reverter_spec.rb +76 -0
- data/spec/fission/action/vm/cloner_spec.rb +198 -0
- data/spec/fission/action/vm/deleter_spec.rb +79 -0
- data/spec/fission/action/vm/lister_spec.rb +164 -0
- data/spec/fission/action/vm/starter_spec.rb +88 -0
- data/spec/fission/action/vm/stopper_spec.rb +71 -0
- data/spec/fission/action/vm/suspender_spec.rb +59 -0
- data/spec/fission/cli_spec.rb +32 -157
- data/spec/fission/command/clone_spec.rb +9 -3
- data/spec/fission/command/delete_spec.rb +11 -3
- data/spec/fission/command/info_spec.rb +130 -0
- data/spec/fission/command/snapshot_create_spec.rb +11 -3
- data/spec/fission/command/snapshot_delete_spec.rb +74 -0
- data/spec/fission/command/snapshot_list_spec.rb +11 -3
- data/spec/fission/command/snapshot_revert_spec.rb +11 -3
- data/spec/fission/command/start_spec.rb +11 -3
- data/spec/fission/command/status_spec.rb +16 -5
- data/spec/fission/command/stop_spec.rb +11 -3
- data/spec/fission/command/suspend_spec.rb +11 -3
- data/spec/fission/command_helpers_spec.rb +27 -5
- data/spec/fission/command_line_parser_spec.rb +267 -0
- data/spec/fission/command_spec.rb +16 -1
- data/spec/fission/config_spec.rb +3 -3
- data/spec/fission/fusion_spec.rb +11 -6
- data/spec/fission/lease_spec.rb +81 -45
- data/spec/fission/metadata_spec.rb +29 -6
- data/spec/fission/response_spec.rb +20 -9
- data/spec/fission/ui_spec.rb +1 -1
- data/spec/fission/vm_configuration_spec.rb +132 -0
- data/spec/fission/vm_spec.rb +393 -750
- data/spec/helpers/command_helpers.rb +1 -1
- metadata +93 -15
- data/.rvmrc +0 -1
@@ -0,0 +1,88 @@
|
|
1
|
+
module Fission
|
2
|
+
module Action
|
3
|
+
module VM
|
4
|
+
|
5
|
+
class Starter
|
6
|
+
|
7
|
+
# Internal: Creates a new VMStarter object. This accepts a VM object.
|
8
|
+
#
|
9
|
+
# vm - An instance of VM
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
#
|
13
|
+
# Fission::Action::VMStarter.new @my_vm
|
14
|
+
#
|
15
|
+
# Returns a new VMStarter object
|
16
|
+
def initialize(vm)
|
17
|
+
@vm = vm
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Starts a VM. The VM must not be running in order to start it.
|
21
|
+
#
|
22
|
+
# options - Hash of options:
|
23
|
+
# :headless - Boolean which specifies to start the VM without
|
24
|
+
# a GUI console. The Fusion GUI must not be
|
25
|
+
# running in order to start the VM headless.
|
26
|
+
# (default: false)
|
27
|
+
#
|
28
|
+
# Examples
|
29
|
+
#
|
30
|
+
# @vm_starter.start
|
31
|
+
#
|
32
|
+
# @vm_starter.start :headless => true
|
33
|
+
#
|
34
|
+
# Returns a Response with the result.
|
35
|
+
# If successful, the Response's data attribute will be nil.
|
36
|
+
# If there is an error, an unsuccessful Response will be returned.
|
37
|
+
def start(options={})
|
38
|
+
unless @vm.exists?
|
39
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
40
|
+
end
|
41
|
+
|
42
|
+
running_response = @vm.running?
|
43
|
+
return running_response unless running_response.successful?
|
44
|
+
|
45
|
+
if running_response.data
|
46
|
+
return Response.new :code => 1, :message => 'VM is already running'
|
47
|
+
end
|
48
|
+
|
49
|
+
conf_file_response = @vm.conf_file
|
50
|
+
return conf_file_response unless conf_file_response.successful?
|
51
|
+
|
52
|
+
unless options[:headless].blank?
|
53
|
+
if Fusion.running?
|
54
|
+
message = 'It looks like the Fusion GUI is currently running. '
|
55
|
+
message << 'A VM cannot be started in headless mode when the Fusion GUI is running. '
|
56
|
+
message << 'Exit the Fusion GUI and try again.'
|
57
|
+
return Response.new :code => 1, :message => message
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
command = "#{vmrun_cmd} start "
|
62
|
+
command << "'#{conf_file_response.data}' "
|
63
|
+
|
64
|
+
command << (options[:headless].blank? ? 'gui ' : 'nogui ')
|
65
|
+
command << '2>&1'
|
66
|
+
|
67
|
+
command_exec = Fission::Action::ShellExecutor.new command
|
68
|
+
Response.from_shell_executor command_exec.execute
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
# Internal: Helper for getting the configured vmrun_cmd value.
|
73
|
+
#
|
74
|
+
# Examples
|
75
|
+
#
|
76
|
+
# @vm_starter.vmrun_cmd
|
77
|
+
# # => "/foo/bar/vmrun -T fusion"
|
78
|
+
#
|
79
|
+
# Returns a String for the configured value of
|
80
|
+
# Fission.config['vmrun_cmd'].
|
81
|
+
def vmrun_cmd
|
82
|
+
Fission.config['vmrun_cmd']
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Fission
|
2
|
+
module Action
|
3
|
+
module VM
|
4
|
+
|
5
|
+
class Stopper
|
6
|
+
|
7
|
+
# Internal: Creates a new VMStopper object. This accepts a VM object.
|
8
|
+
#
|
9
|
+
# vm - An instance of VM
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
#
|
13
|
+
# Fission::Action::VMStopper.new @my_vm
|
14
|
+
#
|
15
|
+
# Returns a new VMStopper object
|
16
|
+
def initialize(vm)
|
17
|
+
@vm = vm
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Stops a VM. The VM must be running in order to stop it.
|
21
|
+
#
|
22
|
+
# options - Hash of options:
|
23
|
+
# :hard - Boolean which specifies to power off the VM (instead
|
24
|
+
# of attempting to initiate a graceful shutdown). This
|
25
|
+
# is the equivalent of passing 'hard' to the vmrun
|
26
|
+
# stop command.
|
27
|
+
# (default: false)
|
28
|
+
#
|
29
|
+
# Examples
|
30
|
+
#
|
31
|
+
# @stopper.stop
|
32
|
+
#
|
33
|
+
# @stopper.stop :hard => true
|
34
|
+
#
|
35
|
+
# Returns a Response with the result.
|
36
|
+
# If successful, the Response's data attribute will be nil.
|
37
|
+
# If there is an error, an unsuccessful Response will be returned.
|
38
|
+
def stop(options={})
|
39
|
+
unless @vm.exists?
|
40
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
41
|
+
end
|
42
|
+
|
43
|
+
running_response = @vm.running?
|
44
|
+
return running_response unless running_response.successful?
|
45
|
+
|
46
|
+
unless running_response.data
|
47
|
+
return Response.new :code => 1, :message => 'VM is not running'
|
48
|
+
end
|
49
|
+
|
50
|
+
conf_file_response = @vm.conf_file
|
51
|
+
return conf_file_response unless conf_file_response.successful?
|
52
|
+
|
53
|
+
command = "#{vmrun_cmd} stop "
|
54
|
+
command << "'#{conf_file_response.data}' "
|
55
|
+
command << 'hard ' unless options[:hard].blank?
|
56
|
+
command << '2>&1'
|
57
|
+
|
58
|
+
command_exec = Fission::Action::ShellExecutor.new command
|
59
|
+
Response.from_shell_executor command_exec.execute
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
# Internal: Helper for getting the configured vmrun_cmd value.
|
64
|
+
#
|
65
|
+
# Examples
|
66
|
+
#
|
67
|
+
# @vm_stopper.vmrun_cmd
|
68
|
+
# # => "/foo/bar/vmrun -T fusion"
|
69
|
+
#
|
70
|
+
# Returns a String for the configured value of
|
71
|
+
# Fission.config['vmrun_cmd'].
|
72
|
+
def vmrun_cmd
|
73
|
+
Fission.config['vmrun_cmd']
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Fission
|
2
|
+
module Action
|
3
|
+
module VM
|
4
|
+
|
5
|
+
class Suspender
|
6
|
+
|
7
|
+
# Internal: Creates a new VMSuspender object. This accepts a VM object.
|
8
|
+
#
|
9
|
+
# vm - An instance of VM
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
#
|
13
|
+
# Fission::Action::VMSuspender.new @my_vm
|
14
|
+
#
|
15
|
+
# Returns a new VMSuspender object
|
16
|
+
def initialize(vm)
|
17
|
+
@vm = vm
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Suspends a VM. The VM must be running in order to suspend it.
|
21
|
+
#
|
22
|
+
# Examples
|
23
|
+
#
|
24
|
+
# @suspender.suspend
|
25
|
+
#
|
26
|
+
# Returns a Response with the result.
|
27
|
+
# If successful, the Response's data attribute will be nil.
|
28
|
+
# If there is an error, an unsuccessful Response will be returned.
|
29
|
+
def suspend
|
30
|
+
unless @vm.exists?
|
31
|
+
return Response.new :code => 1, :message => 'VM does not exist'
|
32
|
+
end
|
33
|
+
|
34
|
+
running_response = @vm.running?
|
35
|
+
return running_response unless running_response.successful?
|
36
|
+
|
37
|
+
unless running_response.data
|
38
|
+
return Response.new :code => 1, :message => 'VM is not running'
|
39
|
+
end
|
40
|
+
|
41
|
+
conf_file_response = @vm.conf_file
|
42
|
+
return conf_file_response unless conf_file_response.successful?
|
43
|
+
|
44
|
+
command = "#{vmrun_cmd} suspend "
|
45
|
+
command << "'#{conf_file_response.data}' 2>&1"
|
46
|
+
|
47
|
+
command_exec = Fission::Action::ShellExecutor.new command
|
48
|
+
Response.from_shell_executor command_exec.execute
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
# Internal: Helper for getting the configured vmrun_cmd value.
|
53
|
+
#
|
54
|
+
# Examples
|
55
|
+
#
|
56
|
+
# @suspender.vmrun_cmd
|
57
|
+
# # => "/foo/bar/vmrun -T fusion"
|
58
|
+
#
|
59
|
+
# Returns a String for the configured value of
|
60
|
+
# Fission.config['vmrun_cmd'].
|
61
|
+
def vmrun_cmd
|
62
|
+
Fission.config['vmrun_cmd']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/fission/cli.rb
CHANGED
@@ -1,141 +1,45 @@
|
|
1
1
|
module Fission
|
2
2
|
class CLI
|
3
3
|
|
4
|
-
# Internal:
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# args - The list of arguments for the Fission command line app. This
|
9
|
-
# should be the raw command line arguments.
|
4
|
+
# Internal: Creates a new Fission::CLI object. This automatically parses
|
5
|
+
# the arguments in ARGV. This will also automatically display the usage
|
6
|
+
# and exit if applicable.
|
10
7
|
#
|
11
8
|
# Examples
|
12
9
|
#
|
13
|
-
# Fission::CLI.
|
10
|
+
# Fission::CLI.new
|
14
11
|
#
|
15
|
-
# Returns
|
16
|
-
def
|
17
|
-
|
18
|
-
opts.banner = "\nUsage: fission [options] COMMAND [arguments]"
|
19
|
-
|
20
|
-
opts.on_head('-v', '--version', 'Output the version of fission') do
|
21
|
-
ui.output VERSION
|
22
|
-
exit(0)
|
23
|
-
end
|
24
|
-
|
25
|
-
opts.on_head('-h', '--help', 'Displays this message') do
|
26
|
-
show_all_help(optparse)
|
27
|
-
exit(0)
|
28
|
-
end
|
29
|
-
|
30
|
-
opts.define_tail do
|
31
|
-
commands_banner
|
32
|
-
end
|
12
|
+
# Returns a Fission::CLI object.
|
13
|
+
def initialize(args=ARGV, parser=CommandLineParser)
|
14
|
+
@args = args ||= ARGV
|
33
15
|
|
34
|
-
|
16
|
+
@parser = parser.new @args
|
35
17
|
|
36
|
-
|
37
|
-
optparse.order! args
|
38
|
-
rescue OptionParser::InvalidOption => e
|
39
|
-
ui.output e
|
40
|
-
show_all_help(optparse)
|
41
|
-
exit(1)
|
42
|
-
end
|
43
|
-
|
44
|
-
if commands.include?(args.first)
|
45
|
-
@cmd = Command.const_get(args.first.capitalize).new args.drop 1
|
46
|
-
elsif is_snapshot_command?(args)
|
47
|
-
klass = args.take(2).map {|c| c.capitalize}.join('')
|
48
|
-
@cmd = Command.const_get(klass).new args.drop 2
|
49
|
-
else
|
50
|
-
show_all_help(optparse)
|
51
|
-
exit(1)
|
52
|
-
end
|
53
|
-
|
54
|
-
@cmd.execute
|
18
|
+
parse_arguments
|
55
19
|
end
|
56
20
|
|
57
|
-
# Internal:
|
58
|
-
# command directory.
|
21
|
+
# Internal: Execute the determined command.
|
59
22
|
#
|
60
|
-
# Examples
|
23
|
+
# Examples:
|
61
24
|
#
|
62
|
-
# Fission::CLI.
|
63
|
-
# # => ['clone', 'delete', 'snapshot create', 'snapshot list']
|
25
|
+
# Fission::CLI.new(ARGV).execute
|
64
26
|
#
|
65
|
-
# Returns
|
66
|
-
|
67
|
-
|
68
|
-
cmds = Dir.entries(File.join(File.dirname(__FILE__), 'command')).select do |file|
|
69
|
-
!File.directory? file
|
70
|
-
end
|
71
|
-
|
72
|
-
cmds.map { |cmd| File.basename(cmd, '.rb').gsub '_', ' ' }
|
27
|
+
# Returns nothing.
|
28
|
+
def execute
|
29
|
+
@cmd.execute
|
73
30
|
end
|
74
31
|
|
75
32
|
private
|
76
|
-
# Internal:
|
77
|
-
# command.
|
33
|
+
# Internal: Parses the arguments using the parser.
|
78
34
|
#
|
79
|
-
#
|
80
|
-
# line arguments. Only the first two items in the Array will be
|
81
|
-
# used.
|
82
|
-
#
|
83
|
-
# Examples
|
35
|
+
# Examples:
|
84
36
|
#
|
85
|
-
#
|
86
|
-
# # => false
|
87
|
-
#
|
88
|
-
# Fission::CLI.is_snapshot_command? ['snapshot', 'list']
|
89
|
-
# # => true
|
90
|
-
#
|
91
|
-
# Returns a Boolean of whether a snapshot command was given or not.
|
92
|
-
def self.is_snapshot_command?(args)
|
93
|
-
args.first == 'snapshot' && args.count > 1 && commands.include?(args.take(2).join(' '))
|
94
|
-
end
|
95
|
-
|
96
|
-
# Internal: Provides the help of all of the known commands.
|
97
|
-
#
|
98
|
-
# Examples
|
99
|
-
#
|
100
|
-
# Fission::CLI.commands_banner
|
101
|
-
#
|
102
|
-
# Returns a String which is a concatenation of the help text for all known
|
103
|
-
# commands.
|
104
|
-
def self.commands_banner
|
105
|
-
text = "\nCommands:\n"
|
106
|
-
Command.descendants.each do |command_klass|
|
107
|
-
text << (command_klass.send :help)
|
108
|
-
end
|
109
|
-
|
110
|
-
text
|
111
|
-
end
|
112
|
-
|
113
|
-
# Internal: Helper method to output the command line options and the help
|
114
|
-
# for all known commands to the terminal.
|
115
|
-
#
|
116
|
-
# options - The options to display as a part of the output. This can (and
|
117
|
-
# in almost all cases) should be the optparse object.
|
118
|
-
#
|
119
|
-
# Examples
|
120
|
-
#
|
121
|
-
# Fission::CLI.show_all_help my_opt_parse
|
122
|
-
# # => 'fission options command arguments ....' (concatenated)
|
37
|
+
# @cli.parse_arguments
|
123
38
|
#
|
124
39
|
# Returns nothing.
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
# Internal: Helper method for outputting text to the ui
|
131
|
-
#
|
132
|
-
# Examples
|
133
|
-
#
|
134
|
-
# CLI.ui.output 'foo'
|
135
|
-
#
|
136
|
-
# Returns a UI instance.
|
137
|
-
def self.ui
|
138
|
-
@ui ||= UI.new
|
40
|
+
def parse_arguments
|
41
|
+
@parser.parse
|
42
|
+
@cmd = @parser.command
|
139
43
|
end
|
140
44
|
|
141
45
|
end
|
data/lib/fission/command.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'forwardable'
|
2
|
+
require 'fission/command_helpers'
|
2
3
|
|
3
4
|
module Fission
|
4
5
|
class Command
|
6
|
+
include Fission::CommandHelpers
|
5
7
|
extend Forwardable
|
6
8
|
|
7
9
|
def_delegators :@ui, :output, :output_and_exit, :output_printf
|
@@ -28,6 +30,17 @@ module Fission
|
|
28
30
|
@args = args
|
29
31
|
end
|
30
32
|
|
33
|
+
# Internal: Primary method for performing an action within a command.
|
34
|
+
#
|
35
|
+
# Examples
|
36
|
+
#
|
37
|
+
# command.execute
|
38
|
+
#
|
39
|
+
# Returns nothing
|
40
|
+
def execute
|
41
|
+
parse_arguments
|
42
|
+
end
|
43
|
+
|
31
44
|
# Internal: Helper method used to delegate UI related methods through.
|
32
45
|
#
|
33
46
|
# Examples
|
@@ -39,6 +52,32 @@ module Fission
|
|
39
52
|
@ui ||= UI.new
|
40
53
|
end
|
41
54
|
|
55
|
+
# Internal: Helper method to determine the command name of command class.
|
56
|
+
# This should only be called against descendants of this class.
|
57
|
+
#
|
58
|
+
# #xamples:
|
59
|
+
# Fission::Command::SnapshotList.new.command_name
|
60
|
+
# # => 'snapshot list'
|
61
|
+
#
|
62
|
+
# Returns the command name as a String.
|
63
|
+
def command_name(klass=self)
|
64
|
+
klass.class.name.split('::')[2].
|
65
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
66
|
+
gsub('_', ' ').downcase
|
67
|
+
end
|
68
|
+
|
69
|
+
# Internal: Summmary of the command. This is to be implemented by any
|
70
|
+
# class which inherits from this class.
|
71
|
+
#
|
72
|
+
# Examples
|
73
|
+
# command.summary
|
74
|
+
# # => 'This command does x and y'
|
75
|
+
#
|
76
|
+
# Returns a String summary of the command.
|
77
|
+
def summary
|
78
|
+
raise NotImplementedError
|
79
|
+
end
|
80
|
+
|
42
81
|
# Internal: Helper method to return the help text of a command. This is
|
43
82
|
# intended to be used by a command class which inherits from this class.
|
44
83
|
# This method will call the 'option_parser' method which must be defined in
|