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.
Files changed (50) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +3 -0
  3. data/README.md +1 -1
  4. data/lib/fission.rb +5 -6
  5. data/lib/fission/cli.rb +77 -7
  6. data/lib/fission/command.rb +43 -1
  7. data/lib/fission/command/clone.rb +19 -20
  8. data/lib/fission/command/delete.rb +29 -25
  9. data/lib/fission/command/snapshot_create.rb +11 -26
  10. data/lib/fission/command/snapshot_list.rb +13 -19
  11. data/lib/fission/command/snapshot_revert.rb +11 -26
  12. data/lib/fission/command/start.rb +11 -25
  13. data/lib/fission/command/status.rb +26 -10
  14. data/lib/fission/command/stop.rb +10 -21
  15. data/lib/fission/command/suspend.rb +21 -21
  16. data/lib/fission/command_helpers.rb +21 -0
  17. data/lib/fission/config.rb +35 -0
  18. data/lib/fission/fusion.rb +11 -3
  19. data/lib/fission/lease.rb +148 -0
  20. data/lib/fission/metadata.rb +55 -2
  21. data/lib/fission/response.rb +76 -0
  22. data/lib/fission/ui.rb +49 -0
  23. data/lib/fission/version.rb +1 -1
  24. data/lib/fission/vm.rb +653 -75
  25. data/spec/contexts/command.rb +12 -0
  26. data/spec/fission/cli_spec.rb +4 -11
  27. data/spec/fission/command/clone_spec.rb +45 -45
  28. data/spec/fission/command/delete_spec.rb +56 -43
  29. data/spec/fission/command/snapshot_create_spec.rb +29 -51
  30. data/spec/fission/command/snapshot_list_spec.rb +25 -26
  31. data/spec/fission/command/snapshot_revert_spec.rb +27 -53
  32. data/spec/fission/command/start_spec.rb +25 -69
  33. data/spec/fission/command/status_spec.rb +48 -13
  34. data/spec/fission/command/stop_spec.rb +25 -42
  35. data/spec/fission/command/suspend_spec.rb +54 -49
  36. data/spec/fission/command_helpers_spec.rb +30 -0
  37. data/spec/fission/command_spec.rb +19 -0
  38. data/spec/fission/config_spec.rb +24 -0
  39. data/spec/fission/fusion_spec.rb +6 -6
  40. data/spec/fission/lease_spec.rb +176 -0
  41. data/spec/fission/metadata_spec.rb +8 -8
  42. data/spec/fission/response_spec.rb +81 -0
  43. data/spec/fission/vm_spec.rb +869 -193
  44. data/spec/fission_spec.rb +0 -6
  45. data/spec/helpers/command_helpers.rb +12 -0
  46. data/spec/helpers/response_helpers.rb +21 -0
  47. data/spec/matchers/be_a_successful_response.rb +7 -0
  48. data/spec/matchers/be_an_unsuccessful_response.rb +10 -0
  49. data/spec/spec_helper.rb +7 -0
  50. metadata +24 -5
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  *.gem
2
2
  .bundle
3
3
  Gemfile.lock
4
+ doc/*
4
5
  pkg/*
data/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  ## head
4
4
 
5
+ ## 0.4.0
6
+ * major internal refactoring for usage as a lib
7
+
5
8
  ## 0.3.0 (09/16/2011)
6
9
  * add ability to suspend all running VMs ('--all')
7
10
  * add 'delete' command
data/README.md CHANGED
@@ -127,7 +127,7 @@ regardless of ruby environment when using RVM https://gist.github.com/1203167
127
127
 
128
128
  ## Contribute
129
129
  * Fork the project
130
- * Make your feature addition or bug fix (with tests) in a topic branch
130
+ * Make your feature addition or bug fix (with tests and docs) in a topic branch
131
131
  * Bonus points for not mucking with the gemspec or version
132
132
  * Send a pull request and I'll get it integrated
133
133
 
data/lib/fission.rb CHANGED
@@ -7,7 +7,9 @@ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
7
7
 
8
8
  require 'fission/cli'
9
9
  require 'fission/command'
10
+ require 'fission/command_helpers'
10
11
  require 'fission/command/clone'
12
+ require 'fission/command/delete'
11
13
  require 'fission/command/snapshot_create'
12
14
  require 'fission/command/snapshot_list'
13
15
  require 'fission/command/snapshot_revert'
@@ -15,13 +17,14 @@ require 'fission/command/start'
15
17
  require 'fission/command/status'
16
18
  require 'fission/command/stop'
17
19
  require 'fission/command/suspend'
18
- require 'fission/command/delete'
19
20
  require 'fission/config'
20
21
  require 'fission/core_ext/class'
21
22
  require 'fission/core_ext/file'
22
23
  require 'fission/core_ext/object'
23
24
  require 'fission/fusion'
25
+ require 'fission/lease'
24
26
  require 'fission/metadata'
27
+ require 'fission/response'
25
28
  require 'fission/ui'
26
29
  require 'fission/vm'
27
30
  require 'fission/version'
@@ -30,10 +33,6 @@ module Fission
30
33
  extend self
31
34
 
32
35
  def config
33
- @config ||= Fission::Config.new
34
- end
35
-
36
- def ui
37
- @ui ||= Fission::UI.new
36
+ @config ||= Config.new
38
37
  end
39
38
  end
data/lib/fission/cli.rb CHANGED
@@ -1,11 +1,24 @@
1
1
  module Fission
2
2
  class CLI
3
+
4
+ # Internal: Starts the command line parsing logic and hands off to the
5
+ # requested commands. If there are invalid arguments or errors then the
6
+ # help text will be displayed.
7
+ #
8
+ # args - The list of arguments for the Fission command line app. This
9
+ # should be the raw command line arguments.
10
+ #
11
+ # Examples
12
+ #
13
+ # Fission::CLI.execute
14
+ #
15
+ # Returns nothing.
3
16
  def self.execute(args=ARGV)
4
17
  optparse = OptionParser.new do |opts|
5
18
  opts.banner = "\nUsage: fission [options] COMMAND [arguments]"
6
19
 
7
20
  opts.on_head('-v', '--version', 'Output the version of fission') do
8
- Fission.ui.output Fission::VERSION
21
+ ui.output VERSION
9
22
  exit(0)
10
23
  end
11
24
 
@@ -23,16 +36,16 @@ module Fission
23
36
  begin
24
37
  optparse.order! args
25
38
  rescue OptionParser::InvalidOption => e
26
- Fission.ui.output e
39
+ ui.output e
27
40
  show_all_help(optparse)
28
41
  exit(1)
29
42
  end
30
43
 
31
44
  if commands.include?(args.first)
32
- @cmd = Fission::Command.const_get(args.first.capitalize).new args.drop 1
45
+ @cmd = Command.const_get(args.first.capitalize).new args.drop 1
33
46
  elsif is_snapshot_command?(args)
34
47
  klass = args.take(2).map {|c| c.capitalize}.join('')
35
- @cmd = Fission::Command.const_get(klass).new args.drop 2
48
+ @cmd = Command.const_get(klass).new args.drop 2
36
49
  else
37
50
  show_all_help(optparse)
38
51
  exit(1)
@@ -41,6 +54,16 @@ module Fission
41
54
  @cmd.execute
42
55
  end
43
56
 
57
+ # Internal: Provides the list of Fission commands based on the files in the
58
+ # command directory.
59
+ #
60
+ # Examples
61
+ #
62
+ # Fission::CLI.commands
63
+ # # => ['clone', 'delete', 'snapshot create', 'snapshot list']
64
+ #
65
+ # Returns an Array of the commands (String). Commands with underscores will
66
+ # have them replaced with spaces.
44
67
  def self.commands
45
68
  cmds = Dir.entries(File.join(File.dirname(__FILE__), 'command')).select do |file|
46
69
  !File.directory? file
@@ -50,22 +73,69 @@ module Fission
50
73
  end
51
74
 
52
75
  private
76
+ # Internal: Determines if the provided command is a snapshot related
77
+ # command.
78
+ #
79
+ # args - The arguments (Array) to interrogate. This should be the command
80
+ # line arguments. Only the first two items in the Array will be
81
+ # used.
82
+ #
83
+ # Examples
84
+ #
85
+ # Fission::CLI.is_snapshot_command? ['foo', 'bar']
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.
53
92
  def self.is_snapshot_command?(args)
54
93
  args.first == 'snapshot' && args.count > 1 && commands.include?(args.take(2).join(' '))
55
94
  end
56
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.
57
104
  def self.commands_banner
58
105
  text = "\nCommands:\n"
59
- Fission::Command.descendants.each do |command_klass|
106
+ Command.descendants.each do |command_klass|
60
107
  text << (command_klass.send :help)
61
108
  end
62
109
 
63
110
  text
64
111
  end
65
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)
123
+ #
124
+ # Returns nothing.
66
125
  def self.show_all_help(options)
67
- Fission.ui.output options
68
- Fission.ui.output commands_banner
126
+ ui.output options
127
+ ui.output commands_banner
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
69
139
  end
70
140
 
71
141
  end
@@ -1,12 +1,54 @@
1
+ require 'forwardable'
2
+
1
3
  module Fission
2
4
  class Command
3
- attr_reader :options, :args
5
+ extend Forwardable
6
+
7
+ def_delegators :@ui, :output, :output_and_exit, :output_printf
8
+
9
+ # Internal: Returns the OpenStruct options of the command.
10
+ attr_reader :options
4
11
 
12
+ # Internal: Returns the Array arguments of the command.
13
+ attr_reader :args
14
+
15
+ # Internal: Initializes a new Command with some basic setup. This is
16
+ # intended to be used as a base class for other command classes to inherit
17
+ # from.
18
+ #
19
+ # args - Array of arguments which will be assigned to the args instance
20
+ # variable.
21
+ #
22
+ # Examples
23
+ #
24
+ # Fission::Command.new ['foo', 'bar']
5
25
  def initialize(args=[])
26
+ ui
6
27
  @options = OpenStruct.new
7
28
  @args = args
8
29
  end
9
30
 
31
+ # Internal: Helper method used to delegate UI related methods through.
32
+ #
33
+ # Examples
34
+ #
35
+ # command.ui.output 'foo'
36
+ #
37
+ # Returns a UI instance.
38
+ def ui
39
+ @ui ||= UI.new
40
+ end
41
+
42
+ # Internal: Helper method to return the help text of a command. This is
43
+ # intended to be used by a command class which inherits from this class.
44
+ # This method will call the 'option_parser' method which must be defined in
45
+ # any class which inherits from this class.
46
+ #
47
+ # Examples
48
+ #
49
+ # Fission::Command::Suspend.help
50
+ #
51
+ # Returns a String of the output parser text.
10
52
  def self.help
11
53
  self.new.option_parser.to_s
12
54
  end
@@ -1,6 +1,7 @@
1
1
  module Fission
2
2
  class Command
3
3
  class Clone < Command
4
+ include Fission::CommandHelpers
4
5
 
5
6
  def initialize(args=[])
6
7
  super
@@ -10,32 +11,30 @@ module Fission
10
11
  def execute
11
12
  option_parser.parse! @args
12
13
 
13
- unless @args.count > 1
14
- Fission.ui.output self.class.help
15
- Fission.ui.output ""
16
- Fission.ui.output_and_exit "Incorrect arguments for clone command", 1
17
- end
14
+ incorrect_arguments 'clone' unless @args.count > 1
18
15
 
19
- source_vm = @args.first
20
- target_vm = @args[1]
16
+ source_vm = Fission::VM.new @args.first
17
+ target_vm = Fission::VM.new @args[1]
21
18
 
22
- unless Fission::VM.exists? source_vm
23
- Fission.ui.output_and_exit "Unable to find the source vm #{source_vm} (#{Fission::VM.path(source_vm)})", 1
24
- end
19
+ clone_response = VM.clone source_vm.name, target_vm.name
25
20
 
26
- if Fission::VM.exists? target_vm
27
- Fission::ui.output_and_exit "The target vm #{target_vm} already exists", 1
28
- end
21
+ if clone_response.successful?
22
+ output ''
23
+ output 'Clone complete!'
29
24
 
30
- Fission::VM.clone source_vm, target_vm
25
+ if @options.start
26
+ output "Starting '#{target_vm.name}'"
31
27
 
32
- Fission.ui.output ''
33
- Fission.ui.output 'Clone complete!'
28
+ start_response = target_vm.start
34
29
 
35
- if @options.start
36
- Fission.ui.output "Starting '#{target_vm}'"
37
- @vm = Fission::VM.new target_vm
38
- @vm.start
30
+ if start_response.successful?
31
+ output "VM '#{target_vm.name}' started"
32
+ else
33
+ output_and_exit "There was an error starting the VM. The error was:\n#{start_response.message}", start_response.code
34
+ end
35
+ end
36
+ else
37
+ output_and_exit "There was an error cloning the VM. The error was:\n#{clone_response.message}", clone_response.code
39
38
  end
40
39
  end
41
40
 
@@ -1,6 +1,7 @@
1
1
  module Fission
2
2
  class Command
3
3
  class Delete < Command
4
+ include Fission::CommandHelpers
4
5
 
5
6
  def initialize(args=[])
6
7
  super
@@ -10,47 +11,50 @@ module Fission
10
11
  def execute
11
12
  option_parser.parse! @args
12
13
 
13
- if @args.count < 1
14
- Fission.ui.output self.class.help
15
- Fission.ui.output ""
16
- Fission.ui.output_and_exit "Incorrect arguments for delete command", 1
17
- end
14
+ incorrect_arguments 'delete' if @args.count < 1
18
15
 
19
- target_vm = @args.first
16
+ vm = VM.new @args.first
20
17
 
21
- unless Fission::VM.exists? target_vm
22
- Fission.ui.output_and_exit "Unable to find target vm #{target_vm} (#{Fission::VM.path(target_vm)})", 1
23
- end
18
+ running_response = vm.running?
24
19
 
25
- if Fission::VM.all_running.include? target_vm
26
- Fission.ui.output 'VM is currently running'
27
- if @options.force
28
- Fission.ui.output 'Going to stop it'
29
- Fission::Command::Stop.new([target_vm]).execute
30
- else
31
- Fission.ui.output_and_exit "Either stop/suspend the VM or use '--force' and try again.", 1
20
+ if running_response.successful?
21
+ if running_response.data
22
+ output 'VM is currently running'
23
+ if @options.force
24
+ output 'Going to stop it'
25
+ Command::Stop.new([vm.name]).execute
26
+ else
27
+ output_and_exit "Either stop/suspend the VM or use '--force' and try again.", 1
28
+ end
32
29
  end
30
+ else
31
+ output_and_exit "There was an error determining if the VM is running. The error was:\n#{running_response.message}", running_response.code
33
32
  end
34
33
 
35
- if Fission::Fusion.is_running?
36
- Fission.ui.output 'It looks like the Fusion GUI is currently running'
34
+ if Fusion.running?
35
+ output 'It looks like the Fusion GUI is currently running'
36
+
37
37
  if @options.force
38
- Fission.ui.output 'The Fusion metadata for the VM may not be removed completely'
38
+ output 'The Fusion metadata for the VM may not be removed completely'
39
39
  else
40
- Fission.ui.output "Either exit the Fusion GUI or use '--force' and try again"
41
- Fission.ui.output_and_exit "NOTE: Forcing a VM deletion with the Fusion GUI running may not clean up all of the VM metadata", 1
40
+ output "Either exit the Fusion GUI or use '--force' and try again"
41
+ output_and_exit "NOTE: Forcing a VM deletion with the Fusion GUI running may not clean up all of the VM metadata", 1
42
42
  end
43
43
  end
44
44
 
45
- Fission::VM.delete target_vm
45
+ delete_response = vm.delete
46
46
 
47
- Fission.ui.output ''
48
- Fission.ui.output "Deletion complete!"
47
+ if delete_response.successful?
48
+ output ''
49
+ output "Deletion complete!"
50
+ else
51
+ output_and_exit "There was an error deleting the VM. The error was:\n#{delete_response.message}", delete_response.code
52
+ end
49
53
  end
50
54
 
51
55
  def option_parser
52
56
  optparse = OptionParser.new do |opts|
53
- opts.banner = "\ndelete usage: fission delete target_vm [--force]"
57
+ opts.banner = "\ndelete usage: fission delete vm_name [--force]"
54
58
 
55
59
  opts.on '--force', "Stop the VM if it's running and then delete it" do
56
60
  @options.force = true
@@ -1,42 +1,27 @@
1
1
  module Fission
2
2
  class Command
3
3
  class SnapshotCreate < Command
4
-
5
- def initialize(args=[])
6
- super
7
- end
4
+ include Fission::CommandHelpers
8
5
 
9
6
  def execute
10
- unless @args.count == 2
11
- Fission.ui.output self.class.help
12
- Fission.ui.output ""
13
- Fission.ui.output_and_exit "Incorrect arguments for snapshot create command", 1
14
- end
15
-
16
- vm_name, snap_name = @args.take 2
7
+ incorrect_arguments 'snapshot create' unless @args.count == 2
17
8
 
18
- unless Fission::VM.exists? vm_name
19
- Fission.ui.output_and_exit "Unable to find the VM #{vm_name} (#{Fission::VM.path(vm_name)})", 1
20
- end
21
-
22
- unless Fission::VM.all_running.include? vm_name
23
- Fission.ui.output "VM '#{vm_name}' is not running"
24
- Fission.ui.output_and_exit 'A snapshot cannot be created unless the VM is running', 1
25
- end
9
+ vm = VM.new @args[0]
10
+ snap_name = @args[1]
26
11
 
27
- @vm = Fission::VM.new vm_name
12
+ output "Creating snapshot"
13
+ response = vm.create_snapshot snap_name
28
14
 
29
- if @vm.snapshots.include? snap_name
30
- Fission.ui.output_and_exit "VM '#{vm_name}' already has a snapshot named '#{snap_name}'", 1
15
+ if response.successful?
16
+ output "Snapshot '#{snap_name}' created"
17
+ else
18
+ output_and_exit "There was an error creating the snapshot. The error was:\n#{response.message}", response.code
31
19
  end
32
-
33
- Fission.ui.output "Creating snapshot"
34
- @vm.create_snapshot(snap_name)
35
20
  end
36
21
 
37
22
  def option_parser
38
23
  optparse = OptionParser.new do |opts|
39
- opts.banner = "\nsnapshot create: fission snapshot create my_vm snapshot_1"
24
+ opts.banner = "\nsnapshot create: fission snapshot create vm_name snapshot_1"
40
25
  end
41
26
 
42
27
  optparse