fission 0.3.0 → 0.4.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.
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