fission 0.2.0 → 0.3.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +9 -0
- data/README.md +44 -3
- data/fission.gemspec +3 -2
- data/lib/fission.rb +6 -0
- data/lib/fission/cli.rb +12 -6
- data/lib/fission/command/clone.rb +3 -4
- data/lib/fission/command/delete.rb +65 -0
- data/lib/fission/command/snapshot_create.rb +47 -0
- data/lib/fission/command/snapshot_list.rb +42 -0
- data/lib/fission/command/snapshot_revert.rb +47 -0
- data/lib/fission/command/start.rb +22 -4
- data/lib/fission/command/stop.rb +2 -2
- data/lib/fission/command/suspend.rb +29 -13
- data/lib/fission/config.rb +2 -0
- data/lib/fission/fusion.rb +13 -0
- data/lib/fission/metadata.rb +39 -0
- data/lib/fission/version.rb +1 -1
- data/lib/fission/vm.rb +100 -15
- data/spec/fission/cli_spec.rb +91 -11
- data/spec/fission/command/clone_spec.rb +2 -6
- data/spec/fission/command/delete_spec.rb +109 -0
- data/spec/fission/command/snapshot_create_spec.rb +88 -0
- data/spec/fission/command/snapshot_list_spec.rb +61 -0
- data/spec/fission/command/snapshot_revert_spec.rb +90 -0
- data/spec/fission/command/start_spec.rb +35 -6
- data/spec/fission/command/status_spec.rb +2 -2
- data/spec/fission/command/stop_spec.rb +1 -4
- data/spec/fission/command/suspend_spec.rb +27 -6
- data/spec/fission/command_spec.rb +0 -1
- data/spec/fission/config_spec.rb +10 -0
- data/spec/fission/fusion_spec.rb +22 -0
- data/spec/fission/metadata_spec.rb +100 -0
- data/spec/fission/ui_spec.rb +8 -12
- data/spec/fission/vm_spec.rb +268 -44
- data/spec/spec_helper.rb +0 -17
- metadata +40 -11
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## head
|
4
4
|
|
5
|
+
## 0.3.0 (09/08/2011)
|
6
|
+
* add ability to suspend all running VMs ('--all')
|
7
|
+
* add 'delete' command
|
8
|
+
* add 'snapshot create' command
|
9
|
+
* add 'snapshot list' command
|
10
|
+
* add 'snapshot revert' command
|
11
|
+
* add '--headless' option to start
|
12
|
+
* fix issue #2
|
13
|
+
|
5
14
|
## 0.2.0 (07/13/2011)
|
6
15
|
* add 'status' command
|
7
16
|
* add 'start' command
|
data/README.md
CHANGED
@@ -14,11 +14,36 @@ Fission is a simple command line tool for managing VMware Fusion VMs.
|
|
14
14
|
|
15
15
|
If you provide '--start', then the new VM will be powered on after cloning
|
16
16
|
|
17
|
+
### Snapshot Create
|
18
|
+
fission snapshot create my_vm snapshot_name
|
19
|
+
|
20
|
+
Creates a snapshot for the VM
|
21
|
+
|
22
|
+
In order to create the snapshot:
|
23
|
+
* The VM must be running
|
24
|
+
* The snapshot name must be unique
|
25
|
+
|
26
|
+
### Snapshot List
|
27
|
+
fission snapshot list my_vm
|
28
|
+
|
29
|
+
Lists the snapshots for the VM
|
30
|
+
|
31
|
+
### Snapshot Revert
|
32
|
+
fission snapshot revert my_vm existing_snapshot
|
33
|
+
|
34
|
+
Reverts a VM to an existing snapshot
|
35
|
+
|
36
|
+
In order to revert to the snapshot:
|
37
|
+
* The Fusion GUI cannot be running
|
38
|
+
|
17
39
|
### Start
|
18
|
-
fission start my_vm
|
40
|
+
fission start my_vm [--headless]
|
19
41
|
|
20
42
|
Starts the VM
|
21
43
|
|
44
|
+
Providng '--headless' will start the VM without a Fusion GUI console
|
45
|
+
Note that the Fusion GUI cannot be running to start a VM with '--headless'
|
46
|
+
|
22
47
|
### Status
|
23
48
|
fission status
|
24
49
|
|
@@ -30,9 +55,22 @@ Displays the status (running or not) of all of the VMs found
|
|
30
55
|
Stops the VM
|
31
56
|
|
32
57
|
### Suspend
|
33
|
-
fission suspend my_vm
|
58
|
+
fission suspend [my_vm | --all]
|
59
|
+
|
60
|
+
Suspends the VM or all running VMs
|
61
|
+
|
62
|
+
### Delete
|
63
|
+
fission delete my_vm [--force]
|
64
|
+
|
65
|
+
Deletes the VM. This will delete the files from disk and remove the related metadata in Fusion.
|
66
|
+
|
67
|
+
By default, the VM will not be deleted if:
|
68
|
+
* The VM is running
|
69
|
+
* The Fusion GUI is running (as the metadata cannot be cleanly removed)
|
34
70
|
|
35
|
-
|
71
|
+
Providing '--force' will:
|
72
|
+
* Stop the VM if it's running
|
73
|
+
* Delete the VM even if the Fusion GUI is running
|
36
74
|
|
37
75
|
### Help
|
38
76
|
fission -h
|
@@ -69,6 +107,9 @@ the desired install method (ideally with easy install) and settings, but do not
|
|
69
107
|
power on the VM. You can then create clones from this VM 'template'. When you
|
70
108
|
power on the clone, it will start the OS install process (and assign a new ip, etc.).
|
71
109
|
|
110
|
+
## Fission with RVM
|
111
|
+
Please see the following gist for a walkthrough of making fission available
|
112
|
+
regardless of ruby environment when using RVM https://gist.github.com/1203167
|
72
113
|
|
73
114
|
## Contribute
|
74
115
|
* Fork the project
|
data/fission.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ['Tommy Bishop']
|
10
10
|
s.email = ['bishop.thomas@gmail.com']
|
11
11
|
s.homepage = "https://github.com/thbishop/fission"
|
12
|
-
s.summary = %q{
|
13
|
-
s.description = %q{A simple utility to
|
12
|
+
s.summary = %q{Command line tool to manage VMware Fusion VMs}
|
13
|
+
s.description = %q{A simple utility to manage VMware Fusion VMs from the command line}
|
14
14
|
|
15
15
|
s.rubyforge_project = "fission"
|
16
16
|
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
s.add_dependency 'CFPropertyList', '~> 2.0.17'
|
21
22
|
s.add_development_dependency 'rspec', '~> 2.6.0'
|
22
23
|
s.add_development_dependency 'fakefs', '~> 0.3.2'
|
23
24
|
end
|
data/lib/fission.rb
CHANGED
@@ -8,14 +8,20 @@ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
|
8
8
|
require 'fission/cli'
|
9
9
|
require 'fission/command'
|
10
10
|
require 'fission/command/clone'
|
11
|
+
require 'fission/command/snapshot_create'
|
12
|
+
require 'fission/command/snapshot_list'
|
13
|
+
require 'fission/command/snapshot_revert'
|
11
14
|
require 'fission/command/start'
|
12
15
|
require 'fission/command/status'
|
13
16
|
require 'fission/command/stop'
|
14
17
|
require 'fission/command/suspend'
|
18
|
+
require 'fission/command/delete'
|
15
19
|
require 'fission/config'
|
16
20
|
require 'fission/core_ext/class'
|
17
21
|
require 'fission/core_ext/file'
|
18
22
|
require 'fission/core_ext/object'
|
23
|
+
require 'fission/fusion'
|
24
|
+
require 'fission/metadata'
|
19
25
|
require 'fission/ui'
|
20
26
|
require 'fission/vm'
|
21
27
|
require 'fission/version'
|
data/lib/fission/cli.rb
CHANGED
@@ -30,28 +30,34 @@ module Fission
|
|
30
30
|
|
31
31
|
if commands.include?(args.first)
|
32
32
|
@cmd = Fission::Command.const_get(args.first.capitalize).new args.drop 1
|
33
|
-
|
33
|
+
elsif is_snapshot_command?(args)
|
34
|
+
klass = args.take(2).map {|c| c.capitalize}.join('')
|
35
|
+
@cmd = Fission::Command.const_get(klass).new args.drop 2
|
34
36
|
else
|
35
37
|
show_all_help(optparse)
|
36
38
|
exit(1)
|
37
39
|
end
|
40
|
+
|
41
|
+
@cmd.execute
|
38
42
|
end
|
39
43
|
|
40
44
|
def self.commands
|
41
|
-
cmds =
|
42
|
-
|
43
|
-
cmds << File.basename(file, '.rb') unless File.directory? file
|
45
|
+
cmds = Dir.entries(File.join(File.dirname(__FILE__), 'command')).select do |file|
|
46
|
+
!File.directory? file
|
44
47
|
end
|
45
48
|
|
46
|
-
cmds
|
49
|
+
cmds.map { |cmd| File.basename(cmd, '.rb').gsub '_', ' ' }
|
47
50
|
end
|
48
51
|
|
49
52
|
private
|
53
|
+
def self.is_snapshot_command?(args)
|
54
|
+
args.first == 'snapshot' && args.count > 1 && commands.include?(args.take(2).join(' '))
|
55
|
+
end
|
56
|
+
|
50
57
|
def self.commands_banner
|
51
58
|
text = "\nCommands:\n"
|
52
59
|
Fission::Command.descendants.each do |command_klass|
|
53
60
|
text << (command_klass.send :help)
|
54
|
-
text << "\n\n"
|
55
61
|
end
|
56
62
|
|
57
63
|
text
|
@@ -8,7 +8,9 @@ module Fission
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def execute
|
11
|
-
|
11
|
+
option_parser.parse! @args
|
12
|
+
|
13
|
+
unless @args.count > 1
|
12
14
|
Fission.ui.output self.class.help
|
13
15
|
Fission.ui.output ""
|
14
16
|
Fission.ui.output_and_exit "Incorrect arguments for clone command", 1
|
@@ -25,9 +27,6 @@ module Fission
|
|
25
27
|
Fission::ui.output_and_exit "The target vm #{target_vm} already exists", 1
|
26
28
|
end
|
27
29
|
|
28
|
-
clone_options = option_parser
|
29
|
-
clone_options.parse! @args
|
30
|
-
|
31
30
|
Fission::VM.clone source_vm, target_vm
|
32
31
|
|
33
32
|
Fission.ui.output ''
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Fission
|
2
|
+
class Command
|
3
|
+
class Delete < Command
|
4
|
+
|
5
|
+
def initialize(args=[])
|
6
|
+
super
|
7
|
+
@options.force = false
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
option_parser.parse! @args
|
12
|
+
|
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
|
18
|
+
|
19
|
+
target_vm = @args.first
|
20
|
+
|
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
|
24
|
+
|
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
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if Fission::Fusion.is_running?
|
36
|
+
Fission.ui.output 'It looks like the Fusion GUI is currently running'
|
37
|
+
if @options.force
|
38
|
+
Fission.ui.output 'The Fusion metadata for the VM may not be removed completely'
|
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
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
Fission::VM.delete target_vm
|
46
|
+
|
47
|
+
Fission.ui.output ''
|
48
|
+
Fission.ui.output "Deletion complete!"
|
49
|
+
end
|
50
|
+
|
51
|
+
def option_parser
|
52
|
+
optparse = OptionParser.new do |opts|
|
53
|
+
opts.banner = "\ndelete usage: fission delete target_vm [--force]"
|
54
|
+
|
55
|
+
opts.on '--force', "Stop the VM if it's running and then delete it" do
|
56
|
+
@options.force = true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
optparse
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Fission
|
2
|
+
class Command
|
3
|
+
class SnapshotCreate < Command
|
4
|
+
|
5
|
+
def initialize(args=[])
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
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
|
17
|
+
|
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
|
26
|
+
|
27
|
+
@vm = Fission::VM.new vm_name
|
28
|
+
|
29
|
+
if @vm.snapshots.include? snap_name
|
30
|
+
Fission.ui.output_and_exit "VM '#{vm_name}' already has a snapshot named '#{snap_name}'", 1
|
31
|
+
end
|
32
|
+
|
33
|
+
Fission.ui.output "Creating snapshot"
|
34
|
+
@vm.create_snapshot(snap_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def option_parser
|
38
|
+
optparse = OptionParser.new do |opts|
|
39
|
+
opts.banner = "\nsnapshot create: fission snapshot create my_vm snapshot_1"
|
40
|
+
end
|
41
|
+
|
42
|
+
optparse
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Fission
|
2
|
+
class Command
|
3
|
+
class SnapshotList < Command
|
4
|
+
|
5
|
+
def initialize(args=[])
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
unless @args.count == 1
|
11
|
+
Fission.ui.output self.class.help
|
12
|
+
Fission.ui.output ""
|
13
|
+
Fission.ui.output_and_exit "Incorrect arguments for snapshot list command", 1
|
14
|
+
end
|
15
|
+
|
16
|
+
vm_name = @args.first
|
17
|
+
|
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
|
+
@vm = Fission::VM.new vm_name
|
23
|
+
snaps = @vm.snapshots
|
24
|
+
|
25
|
+
if snaps.any?
|
26
|
+
Fission.ui.output snaps.join("\n")
|
27
|
+
else
|
28
|
+
Fission.ui.output "No snapshots found for VM '#{vm_name}'"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def option_parser
|
33
|
+
optparse = OptionParser.new do |opts|
|
34
|
+
opts.banner = "\nsnapshot list: fission snapshot list my_vm"
|
35
|
+
end
|
36
|
+
|
37
|
+
optparse
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Fission
|
2
|
+
class Command
|
3
|
+
class SnapshotRevert < Command
|
4
|
+
|
5
|
+
def initialize(args=[])
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
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 revert command', 1
|
14
|
+
end
|
15
|
+
|
16
|
+
vm_name, snap_name = @args.take 2
|
17
|
+
|
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
|
+
if Fission::Fusion.is_running?
|
23
|
+
Fission.ui.output 'It looks like the Fusion GUI is currently running'
|
24
|
+
Fission.ui.output_and_exit 'Please exit the Fusion GUI and try again', 1
|
25
|
+
end
|
26
|
+
|
27
|
+
@vm = Fission::VM.new vm_name
|
28
|
+
|
29
|
+
unless @vm.snapshots.include? snap_name
|
30
|
+
Fission.ui.output_and_exit "Unable to find the snapshot '#{snap_name}'", 1
|
31
|
+
end
|
32
|
+
|
33
|
+
Fission.ui.output "Reverting to snapshot '#{snap_name}'"
|
34
|
+
@vm.revert_to_snapshot(snap_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def option_parser
|
38
|
+
optparse = OptionParser.new do |opts|
|
39
|
+
opts.banner = "\nsnapshot revert: fission snapshot revert my_vm snapshot_1"
|
40
|
+
end
|
41
|
+
|
42
|
+
optparse
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -4,16 +4,19 @@ module Fission
|
|
4
4
|
|
5
5
|
def initialize(args=[])
|
6
6
|
super
|
7
|
+
@options.headless = false
|
7
8
|
end
|
8
9
|
|
9
10
|
def execute
|
10
|
-
|
11
|
+
option_parser.parse! @args
|
12
|
+
|
13
|
+
if @args.empty?
|
11
14
|
Fission.ui.output self.class.help
|
12
15
|
Fission.ui.output ""
|
13
16
|
Fission.ui.output_and_exit "Incorrect arguments for start command", 1
|
14
17
|
end
|
15
18
|
|
16
|
-
vm_name = args.first
|
19
|
+
vm_name = @args.first
|
17
20
|
|
18
21
|
unless Fission::VM.exists? vm_name
|
19
22
|
Fission.ui.output_and_exit "Unable to find the VM #{vm_name} (#{Fission::VM.path(vm_name)})", 1
|
@@ -26,12 +29,27 @@ module Fission
|
|
26
29
|
|
27
30
|
Fission.ui.output "Starting '#{vm_name}'"
|
28
31
|
@vm = Fission::VM.new vm_name
|
29
|
-
|
32
|
+
|
33
|
+
if @options.headless
|
34
|
+
if Fission::Fusion.is_running?
|
35
|
+
Fission.ui.output 'It looks like the Fusion GUI is currently running'
|
36
|
+
Fission.ui.output 'A VM cannot be started in headless mode when the Fusion GUI is running'
|
37
|
+
Fission.ui.output_and_exit "Exit the Fusion GUI and try again", 1
|
38
|
+
else
|
39
|
+
@vm.start :headless => true
|
40
|
+
end
|
41
|
+
else
|
42
|
+
@vm.start
|
43
|
+
end
|
30
44
|
end
|
31
45
|
|
32
46
|
def option_parser
|
33
47
|
optparse = OptionParser.new do |opts|
|
34
|
-
opts.banner = "\nstart usage: fission start vm"
|
48
|
+
opts.banner = "\nstart usage: fission start vm [options]"
|
49
|
+
|
50
|
+
opts.on '--headless', 'Start the VM in headless mode (i.e. no Fusion GUI console)' do
|
51
|
+
@options.headless = true
|
52
|
+
end
|
35
53
|
end
|
36
54
|
|
37
55
|
optparse
|