fission 0.4.0 → 0.5.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|