fission 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@fission --create
@@ -0,0 +1,6 @@
1
+ # changes
2
+
3
+ ## head
4
+
5
+ ## 0.1.0 (05/17/2011)
6
+ Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fission.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Thomas Bishop, bishop.thomas@gmail.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # Fission
2
+
3
+ ## Intro
4
+ Fission is a simple command line tool for cloning of VMware Fusion VMs.
5
+
6
+
7
+ ## Config
8
+ By default, fission will use the default VMware Fusion VM directory
9
+ (~/Documents/Virtual Machines.localized/) when cloning. If you want to use a
10
+ different directory, you can set this in a config file.
11
+
12
+ The config file needs to be in yaml format and live at '~/.fissionrc'
13
+
14
+ $cat ~/.fissionrc
15
+ ---
16
+ vm_dir: "/vm"
17
+
18
+
19
+ ## Install
20
+ gem install fission
21
+
22
+
23
+ ## Usage
24
+ ### Clone
25
+ fission clone existing_vm new_vm
26
+
27
+ ### Help
28
+ fission -h
29
+
30
+ or just
31
+
32
+ fission
33
+
34
+
35
+ ## Other Notable Info
36
+ As of now, VMware Fusion doesn't provide an easy, out of
37
+ the box, way to modify the personality (hostname, ip, etc.) of a VM. Because of
38
+ this, a clone created by fission is an _exact_ copy of the original (including
39
+ hostname, ip address, etc.). Most likely, this isn't what you want.
40
+
41
+ One approach is to create a VM which will act as a template. Create the VM with
42
+ the desired install method (ideally with easy install) and settings, but do not
43
+ power on the VM. You can create clones from this VM and when you power it on,
44
+ it will start the OS install process (and assign a new ip, etc.)
45
+
46
+
47
+ ## Contribute
48
+ * Fork the project
49
+ * Make your feature addition or bug fix (with tests) in a topic branch
50
+ * Bonus points for not mucking with the gemspec or version
51
+ * Send a pull request and I'll get it integrated
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ task :default => [:spec]
7
+
8
+ desc 'Run specs'
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.rspec_opts = %w(-fs --color)
11
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'fission'
6
+
7
+ Fission::CLI.execute
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fission/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fission"
7
+ s.version = Fission::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Tommy Bishop']
10
+ s.email = ['bishop.thomas@gmail.com']
11
+ s.homepage = "https://github.com/thbishop/fission"
12
+ s.summary = %q{Tool to clone VMware fusion VMs}
13
+ s.description = %q{A simple utility to create VMware Fusion VM clones}
14
+
15
+ s.rubyforge_project = "fission"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ s.add_development_dependency 'rspec', '~> 2.6.0'
22
+ s.add_development_dependency 'fakefs', '~> 0.3.2'
23
+ end
@@ -0,0 +1,28 @@
1
+ require 'fileutils'
2
+ require 'optparse'
3
+ require 'ostruct'
4
+ require 'yaml'
5
+
6
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
7
+
8
+ require 'fission/cli'
9
+ require 'fission/command'
10
+ require 'fission/command/clone'
11
+ require 'fission/config'
12
+ require 'fission/core_ext/class'
13
+ require 'fission/core_ext/object'
14
+ require 'fission/ui'
15
+ require 'fission/vm'
16
+ require 'fission/version'
17
+
18
+ module Fission
19
+ extend self
20
+
21
+ def config
22
+ @config ||= Fission::Config.new
23
+ end
24
+
25
+ def ui
26
+ @ui ||= Fission::UI.new
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ module Fission
2
+ class CLI
3
+ def self.execute(args=ARGV)
4
+ optparse = OptionParser.new do |opts|
5
+ opts.banner = "\nUsage: fission [options] COMMAND [arguments]"
6
+
7
+ opts.on_head('-v', '--version', 'Output the version of fission') do
8
+ Fission.ui.output Fission::VERSION
9
+ exit(0)
10
+ end
11
+
12
+ opts.on_head('-h', '--help', 'Displays this message') do
13
+ show_all_help(optparse)
14
+ exit(0)
15
+ end
16
+
17
+ opts.define_tail do
18
+ commands_banner
19
+ end
20
+
21
+ end
22
+
23
+ begin
24
+ optparse.order! args
25
+ rescue OptionParser::InvalidOption => e
26
+ Fission.ui.output e
27
+ show_all_help(optparse)
28
+ exit(1)
29
+ end
30
+
31
+ case args.first
32
+ when 'clone'
33
+ @command = Fission::Command::Clone.new args.drop 1
34
+ @command.execute
35
+ else
36
+ show_all_help(optparse)
37
+ exit(0)
38
+ end
39
+
40
+ end
41
+
42
+ private
43
+ def self.commands_banner
44
+ text = "\nCommands:\n"
45
+ Fission::Command.descendants.each do |command_klass|
46
+ text << (command_klass.send :help)
47
+ text << "\n\n"
48
+ end
49
+
50
+ text
51
+ end
52
+
53
+ def self.show_all_help(options)
54
+ Fission.ui.output options
55
+ Fission.ui.output commands_banner
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ module Fission
2
+ class Command
3
+ attr_reader :options, :args
4
+
5
+ def initialize(args=[])
6
+ @options = OpenStruct.new
7
+ @args = args
8
+ end
9
+
10
+ def self.help
11
+ self.new.option_parser.to_s
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,57 @@
1
+ module Fission
2
+ class Command
3
+ class Clone < Command
4
+
5
+ def initialize(args=[])
6
+ super
7
+ @options.start = false
8
+ end
9
+
10
+ def execute
11
+ unless args.count > 1
12
+ Fission.ui.output self.class.help
13
+ Fission.ui.output ""
14
+ Fission.ui.output_and_exit "Incorrect arguments for clone command", 1
15
+ end
16
+
17
+ source_vm = @args.first
18
+ target_vm = @args[1]
19
+
20
+ unless Fission::VM.exists? source_vm
21
+ Fission.ui.output_and_exit "Unable to find the source vm #{source_vm} (#{Fission::VM.path(source_vm)})", 1
22
+ end
23
+
24
+ if Fission::VM.exists? target_vm
25
+ Fission::ui.output_and_exit "The target vm #{target_vm} already exists", 1
26
+ end
27
+
28
+ clone_options = option_parser
29
+ clone_options.parse! @args
30
+
31
+ Fission::VM.clone source_vm, target_vm
32
+
33
+ Fission.ui.output ''
34
+ Fission.ui.output 'Clone complete!'
35
+
36
+ if @options.start
37
+ Fission.ui.output "Starting '#{target_vm}'"
38
+ @vm = Fission::VM.new target_vm
39
+ @vm.start
40
+ end
41
+ end
42
+
43
+ def option_parser
44
+ optparse = OptionParser.new do |opts|
45
+ opts.banner = "\nclone usage: fission clone source_vm target_vm [options]"
46
+
47
+ opts.on '--start', 'Start the VM after cloning' do
48
+ @options.start = true
49
+ end
50
+ end
51
+
52
+ optparse
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ module Fission
2
+ class Config
3
+ attr_accessor :attributes
4
+
5
+ CONF_FILE = File.expand_path '~/.fissionrc'
6
+
7
+ def initialize
8
+ @attributes = {}
9
+ load_from_file
10
+
11
+ if @attributes['vm_dir'].blank?
12
+ @attributes['vm_dir'] = File.expand_path('~/Documents/Virtual Machines.localized/')
13
+ end
14
+
15
+ @attributes['vmrun_bin'] = '/Library/Application Support/VMware Fusion/vmrun'
16
+ end
17
+
18
+ private
19
+ def load_from_file
20
+ if File.file?(CONF_FILE)
21
+ @attributes.merge!(YAML.load_file(CONF_FILE))
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ class Class
2
+ def descendants
3
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
4
+ end
5
+ end
@@ -0,0 +1,112 @@
1
+ # this is from active_support
2
+ # github.com/rails/rails/activesupport
3
+ #
4
+ class Object
5
+ # An object is blank if it's false, empty, or a whitespace string.
6
+ # For example, "", " ", +nil+, [], and {} are blank.
7
+ #
8
+ # This simplifies:
9
+ #
10
+ # if !address.nil? && !address.empty?
11
+ #
12
+ # ...to:
13
+ #
14
+ # if !address.blank?
15
+ def blank?
16
+ respond_to?(:empty?) ? empty? : !self
17
+ end
18
+
19
+ # An object is present if it's not <tt>blank?</tt>.
20
+ def present?
21
+ !blank?
22
+ end
23
+
24
+ # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
25
+ # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
26
+ #
27
+ # This is handy for any representation of objects where blank is the same
28
+ # as not present at all. For example, this simplifies a common check for
29
+ # HTTP POST/query parameters:
30
+ #
31
+ # state = params[:state] if params[:state].present?
32
+ # country = params[:country] if params[:country].present?
33
+ # region = state || country || 'US'
34
+ #
35
+ # ...becomes:
36
+ #
37
+ # region = params[:state].presence || params[:country].presence || 'US'
38
+ def presence
39
+ self if present?
40
+ end
41
+ end
42
+
43
+ class NilClass
44
+ # +nil+ is blank:
45
+ #
46
+ # nil.blank? # => true
47
+ #
48
+ def blank?
49
+ true
50
+ end
51
+ end
52
+
53
+ class FalseClass
54
+ # +false+ is blank:
55
+ #
56
+ # false.blank? # => true
57
+ #
58
+ def blank?
59
+ true
60
+ end
61
+ end
62
+
63
+ class TrueClass
64
+ # +true+ is not blank:
65
+ #
66
+ # true.blank? # => false
67
+ #
68
+ def blank?
69
+ false
70
+ end
71
+ end
72
+
73
+ class Array
74
+ # An array is blank if it's empty:
75
+ #
76
+ # [].blank? # => true
77
+ # [1,2,3].blank? # => false
78
+ #
79
+ alias_method :blank?, :empty?
80
+ end
81
+
82
+ class Hash
83
+ # A hash is blank if it's empty:
84
+ #
85
+ # {}.blank? # => true
86
+ # {:key => 'value'}.blank? # => false
87
+ #
88
+ alias_method :blank?, :empty?
89
+ end
90
+
91
+ class String
92
+ # A string is blank if it's empty or contains whitespaces only:
93
+ #
94
+ # "".blank? # => true
95
+ # " ".blank? # => true
96
+ # " something here ".blank? # => false
97
+ #
98
+ def blank?
99
+ self !~ /\S/
100
+ end
101
+ end
102
+
103
+ class Numeric #:nodoc:
104
+ # No number is blank:
105
+ #
106
+ # 1.blank? # => false
107
+ # 0.blank? # => false
108
+ #
109
+ def blank?
110
+ false
111
+ end
112
+ end
@@ -0,0 +1,18 @@
1
+ module Fission
2
+ class UI
3
+ attr_reader :stdout
4
+
5
+ def initialize(stdout=$stdout)
6
+ @stdout = stdout
7
+ end
8
+
9
+ def output(s)
10
+ @stdout.puts s
11
+ end
12
+
13
+ def output_and_exit(s, exit_code)
14
+ output s
15
+ exit exit_code
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Fission
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,62 @@
1
+ module Fission
2
+ class VM
3
+ attr_reader :name
4
+
5
+ def initialize(name)
6
+ @name = name
7
+ end
8
+
9
+ def start
10
+ command = "#{Fission.config.attributes['vmrun_bin'].gsub(' ', '\ ' )} -T fusion start #{conf_file.gsub ' ', '\ '} gui 2>&1"
11
+ output = `#{command}`
12
+
13
+ if $?.exitstatus == 0
14
+ Fission.ui.output "VM started"
15
+ else
16
+ Fission.ui.output "There was a problem starting the VM. The error was:\n#{output}"
17
+ end
18
+ end
19
+
20
+ def conf_file
21
+ File.join self.class.path(@name), "#{@name}.vmx"
22
+ end
23
+
24
+ def self.exists?(vm_name)
25
+ File.directory? path(vm_name)
26
+ end
27
+
28
+ def self.path(vm_name)
29
+ File.join Fission.config.attributes['vm_dir'], "#{vm_name}.vmwarevm"
30
+ end
31
+
32
+ def self.clone(source_vm, target_vm)
33
+ Fission.ui.output "Cloning #{source_vm} to #{target_vm}"
34
+ FileUtils.cp_r path(source_vm), path(target_vm)
35
+
36
+ Fission.ui.output "Configuring #{target_vm}"
37
+ rename_vm_files source_vm, target_vm
38
+ update_config source_vm, target_vm
39
+ end
40
+
41
+ private
42
+ def self.rename_vm_files(from, to)
43
+ files_to_rename(from, to).each do |file|
44
+ FileUtils.mv File.join(path(to), file), File.join(path(to), file.gsub(from, to))
45
+ end
46
+ end
47
+
48
+ def self.files_to_rename(from, to)
49
+ Dir.entries(path(to)).select { |f| f.include?(from) }
50
+ end
51
+
52
+ def self.update_config(from, to)
53
+ ['.vmdk', '.vmx', '.vmxf'].each do |ext|
54
+ file = File.join path(to), "#{to}#{ext}"
55
+ text = File.read file
56
+ text.gsub! from, to
57
+ File.open(file, 'w'){ |f| f.print text }
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::CLI do
4
+ before :each do
5
+ @string_io = StringIO.new
6
+ Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
7
+ end
8
+
9
+ describe 'execute' do
10
+
11
+ describe 'with no arguments' do
12
+ it 'should output the usage info' do
13
+ lambda {
14
+ Fission::CLI.execute []
15
+ }.should raise_error SystemExit
16
+
17
+ @string_io.string.should match /Usage/
18
+ end
19
+ end
20
+
21
+ describe '-v or --version' do
22
+ ['-v', '--version'].each do |arg|
23
+ it "should output the version with #{arg}" do
24
+ lambda {
25
+ Fission::CLI.execute [arg]
26
+ }.should raise_error SystemExit
27
+
28
+ @string_io.string.should match /#{Fission::VERSION}/
29
+
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ describe '-h or --help' do
36
+ ['-h', '--help'].each do |arg|
37
+ it "should output the usage info with #{arg}" do
38
+ lambda {
39
+ Fission::CLI.execute [arg]
40
+ }.should raise_error SystemExit
41
+
42
+ @string_io.string.should match /Usage/
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ describe 'clone' do
49
+ before :each do
50
+ @clone_mock = mock('clone_mock')
51
+ Fission::Command::Clone.stub!(:help).and_return('')
52
+ end
53
+
54
+ it "should try to clone the vm" do
55
+ @clone_mock.should_receive(:execute)
56
+ Fission::Command::Clone.should_receive(:new).with(['foo', 'bar']).and_return(@clone_mock)
57
+
58
+ Fission::CLI.execute ['clone', 'foo', 'bar']
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,90 @@
1
+ require File.expand_path('../../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::Command::Clone do
4
+ before :all do
5
+ @vm_info = ['foo', 'bar']
6
+ end
7
+
8
+ before :each do
9
+ @string_io = StringIO.new
10
+ Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
11
+ end
12
+
13
+ describe 'execute' do
14
+ [ [], ['foo'] ].each do |args|
15
+ it "should output an error and the help when #{args.count} arguments are passed in" do
16
+ Fission::Command::Clone.should_receive(:help)
17
+
18
+ lambda {
19
+ command = Fission::Command::Clone.new args
20
+ command.execute
21
+ }.should raise_error SystemExit
22
+
23
+ @string_io.string.should match /Incorrect arguments for clone command/
24
+ end
25
+ end
26
+
27
+ it "should output an error and exit if it can't find the source vm" do
28
+ Fission::VM.should_receive(:exists?).with(@vm_info.first).and_return(false)
29
+ Fission::VM.should_not_receive(:exists?).with(@vm_info[1])
30
+
31
+ lambda {
32
+ command = Fission::Command::Clone.new @vm_info
33
+ command.execute
34
+ }.should raise_error SystemExit
35
+
36
+ @string_io.string.should match /Unable to find the source vm #{@vm_info.first}/
37
+ end
38
+
39
+
40
+ it "should output an error and exit if the target vm already exists" do
41
+ @vm_info.each do |vm|
42
+ Fission::VM.should_receive(:exists?).with(vm).and_return(true)
43
+ end
44
+
45
+ lambda {
46
+ command = Fission::Command::Clone.new @vm_info
47
+ command.execute
48
+ }.should raise_error SystemExit
49
+
50
+ @string_io.string.should match /The target vm #{@vm_info[1]} already exists/
51
+ end
52
+
53
+ it 'should try to clone the vm if the source vm exists and the target vm does not' do
54
+ Fission::VM.should_receive(:exists?).with(@vm_info.first).and_return(true)
55
+ Fission::VM.should_receive(:exists?).with(@vm_info[1]).and_return(false)
56
+ Fission::VM.should_receive(:clone).with(@vm_info.first, @vm_info[1])
57
+ command = Fission::Command::Clone.new @vm_info
58
+ command.execute
59
+
60
+ @string_io.string.should match /Clone complete/
61
+ end
62
+
63
+ describe 'with --start' do
64
+ it 'should try to clone the vm and start it' do
65
+ @vm_mock = mock('vm_mock')
66
+ Fission::VM.should_receive(:exists?).with(@vm_info.first).and_return(true)
67
+ Fission::VM.should_receive(:exists?).with(@vm_info[1]).and_return(false)
68
+ Fission::VM.should_receive(:clone).with(@vm_info.first, @vm_info[1])
69
+
70
+ @vm_mock.should_receive(:start)
71
+ Fission::VM.should_receive(:new).with(@vm_info[1]).and_return(@vm_mock)
72
+
73
+ command = Fission::Command::Clone.new @vm_info << '--start'
74
+ command.execute
75
+
76
+ @string_io.string.should match /Clone complete/
77
+ @string_io.string.should match /Starting '#{@vm_info[1]}'/
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ describe 'help' do
84
+ it 'should output info for this command' do
85
+ output = Fission::Command::Clone.help
86
+
87
+ output.should match /clone source_vm target_vm/
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::Command do
4
+
5
+ describe 'new' do
6
+ it 'should set options variable as an open struct' do
7
+ @command = Fission::Command.new
8
+ @command.options.should be_kind_of OpenStruct
9
+ end
10
+
11
+ it 'should set the args variable' do
12
+ @command = Fission::Command.new ['foo', 'bar']
13
+ @command.args.should == ['foo', 'bar']
14
+ end
15
+ end
16
+
17
+ describe 'help' do
18
+ it 'should call option_parser on a new instance' do
19
+ @new_instance_mock = mock('new_instance')
20
+ @new_instance_mock.should_receive(:option_parser).and_return('foo')
21
+ Fission::Command.should_receive(:new).and_return(@new_instance_mock)
22
+ Fission::Command.help.should == 'foo'
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::Config do
4
+ describe "init" do
5
+ it "should use the fusion default dir for vm_dir" do
6
+ FakeFS do
7
+ @config = Fission::Config.new
8
+ @config.attributes['vm_dir'].should == File.expand_path('~/Documents/Virtual Machines.localized/')
9
+ end
10
+ end
11
+
12
+ it 'should use the fusion default for vmrun_bin' do
13
+ FakeFS do
14
+ @config = Fission::Config.new
15
+ @config.attributes['vmrun_bin'].should == '/Library/Application Support/VMware Fusion/vmrun'
16
+ end
17
+ end
18
+
19
+ it "should use the user specified dir in ~/.fissionrc" do
20
+ FakeFS do
21
+ File.open('~/.fissionrc', 'w') { |f| f.puts YAML.dump({ 'vm_dir' => '/var/tmp/foo' })}
22
+
23
+ @config = Fission::Config.new
24
+ @config.attributes['vm_dir'].should == '/var/tmp/foo'
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::UI do
4
+ describe 'output' do
5
+ it 'should show the desired text' do
6
+ output = capturing_output do
7
+ Fission::UI.new.output "foo bar\nbaz blah"
8
+ end
9
+
10
+ output.should == "foo bar\nbaz blah\n"
11
+ end
12
+ end
13
+
14
+ describe 'output_and_exit' do
15
+ it 'should show the desired text and exit with the desired exit code' do
16
+ Fission::UI.any_instance.should_receive(:exit).and_return(1)
17
+
18
+ output = capturing_output do
19
+ Fission::UI.new.output_and_exit "foo bar\nbaz blah", 1
20
+ end
21
+
22
+ output.should == "foo bar\nbaz blah\n"
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,107 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::VM do
4
+ before :each do
5
+ @string_io = StringIO.new
6
+ end
7
+
8
+ describe 'new' do
9
+ it 'should set the vm name' do
10
+ Fission::VM.new('foo').name.should == 'foo'
11
+ end
12
+ end
13
+
14
+ describe 'start' do
15
+ it 'should output that it was successful' do
16
+ Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
17
+ @vm = Fission::VM.new('foo')
18
+ @vm.should_receive(:`).with("#{Fission.config.attributes['vmrun_bin'].gsub ' ', '\ '} -T fusion start #{(File.join(Fission::VM.path('foo'), 'foo.vmx')).gsub ' ', '\ '} gui 2>&1").and_return("it's all good")
19
+ @vm.start
20
+
21
+ @string_io.string.should match /VM started/
22
+ end
23
+
24
+ it 'it should output that it was unsuccessful' do
25
+ $?.should_receive(:exitstatus).and_return(1)
26
+ Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
27
+ @vm = Fission::VM.new('foo')
28
+ @vm.should_receive(:`).with("#{Fission.config.attributes['vmrun_bin'].gsub ' ', '\ '} -T fusion start #{(File.join(Fission::VM.path('foo'), 'foo.vmx')).gsub ' ', '\ '} gui 2>&1").and_return("it blew up")
29
+ @vm.start
30
+
31
+ @string_io.string.should match /There was a problem starting the VM.+it blew up.+/m
32
+ end
33
+ end
34
+
35
+ describe 'conf_file' do
36
+ it 'should return the path to the conf file' do
37
+ Fission::VM.new('foo').conf_file.should == File.join(Fission.config.attributes['vm_dir'], 'foo.vmwarevm', 'foo.vmx')
38
+ end
39
+ end
40
+
41
+ describe "self.path" do
42
+ it "should return the path of the vm" do
43
+ vm_path = File.join(Fission.config.attributes['vm_dir'], 'foo.vmwarevm').gsub '\\', ''
44
+ Fission::VM.path('foo').should == vm_path
45
+ end
46
+ end
47
+
48
+ describe "self.exists?" do
49
+ it "should return true if the vm exists" do
50
+ FakeFS do
51
+ FileUtils.mkdir_p(Fission::VM.path('foo'))
52
+ Fission::VM.exists?('foo').should == true
53
+ end
54
+ end
55
+
56
+ it 'should return false if the vm does not exist' do
57
+ FakeFS do
58
+ FileUtils.rm_r(Fission::VM.path('foo'))
59
+ Fission::VM.exists?('foo').should == false
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+ describe "self.clone" do
66
+ before :each do
67
+ Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
68
+ end
69
+
70
+ it 'should clone the vm to the target' do
71
+ source_vm = 'foo'
72
+ target_vm = 'bar'
73
+ vm_files = [ '.vmx',
74
+ '.vmxf',
75
+ '.vmdk',
76
+ '-s001.vmdk',
77
+ '-s002.vmdk',
78
+ '.vmsd' ]
79
+
80
+ FakeFS do
81
+ FileUtils.mkdir_p Fission::VM.path('foo')
82
+
83
+ vm_files.each do |file|
84
+ FileUtils.touch File.join(Fission::VM.path('foo'), "#{source_vm}#{file}")
85
+ end
86
+
87
+ File.open(File.join(Fission::VM.path('foo'), 'foo.vmx'), 'w') { |f| f.write 'foo.vmdk'}
88
+
89
+ Fission::VM.clone source_vm, target_vm
90
+
91
+ File.directory?(Fission::VM.path('bar')).should == true
92
+
93
+ vm_files.each do |file|
94
+ File.file?(File.join(Fission::VM.path('bar'), "#{target_vm}#{file}")).should == true
95
+ end
96
+
97
+ conf_file = File.read File.join(Fission::VM.path('bar'), 'bar.vmx')
98
+ conf_file.should == 'bar.vmdk'
99
+ end
100
+
101
+ @string_io.string.should match /Cloning #{source_vm} to #{target_vm}/
102
+ @string_io.string.should match /Configuring #{target_vm}/
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission do
4
+ describe "config" do
5
+ it "should load a config object" do
6
+ Fission.config.should be_a Fission::Config
7
+ end
8
+ end
9
+
10
+ describe "ui" do
11
+ it "should load a ui object" do
12
+ Fission.ui.should be_a Fission::UI
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec'
2
+ require 'fission'
3
+ require 'fakefs/safe'
4
+
5
+ # Helper to capture our stdout
6
+ # Example
7
+ # output = capturing_output do
8
+ # lambda {
9
+ # Erector.new(["--version"])
10
+ # }.should raise_error(SystemExit)
11
+ # end
12
+ # output.should == Erector::VERSION + "\n"
13
+ def capturing_output
14
+ output = StringIO.new
15
+ $stdout = output
16
+ yield
17
+ output.string
18
+ ensure
19
+ $stdout = STDOUT
20
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fission
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Tommy Bishop
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-18 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.6.0
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: fakefs
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 0.3.2
35
+ type: :development
36
+ version_requirements: *id002
37
+ description: A simple utility to create VMware Fusion VM clones
38
+ email:
39
+ - bishop.thomas@gmail.com
40
+ executables:
41
+ - fission
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - .gitignore
48
+ - .rspec
49
+ - .rvmrc
50
+ - CHANGELOG.md
51
+ - Gemfile
52
+ - LICENSE
53
+ - README.md
54
+ - Rakefile
55
+ - bin/fission
56
+ - fission.gemspec
57
+ - lib/fission.rb
58
+ - lib/fission/cli.rb
59
+ - lib/fission/command.rb
60
+ - lib/fission/command/clone.rb
61
+ - lib/fission/config.rb
62
+ - lib/fission/core_ext/class.rb
63
+ - lib/fission/core_ext/object.rb
64
+ - lib/fission/ui.rb
65
+ - lib/fission/version.rb
66
+ - lib/fission/vm.rb
67
+ - spec/fission/cli_spec.rb
68
+ - spec/fission/command/clone_spec.rb
69
+ - spec/fission/command_spec.rb
70
+ - spec/fission/config_spec.rb
71
+ - spec/fission/ui_spec.rb
72
+ - spec/fission/vm_spec.rb
73
+ - spec/fission_spec.rb
74
+ - spec/spec_helper.rb
75
+ homepage: https://github.com/thbishop/fission
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options: []
80
+
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project: fission
98
+ rubygems_version: 1.8.2
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Tool to clone VMware fusion VMs
102
+ test_files:
103
+ - spec/fission/cli_spec.rb
104
+ - spec/fission/command/clone_spec.rb
105
+ - spec/fission/command_spec.rb
106
+ - spec/fission/config_spec.rb
107
+ - spec/fission/ui_spec.rb
108
+ - spec/fission/vm_spec.rb
109
+ - spec/fission_spec.rb
110
+ - spec/spec_helper.rb