virtuoso 0.0.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/.gitignore +6 -0
- data/.yardopts +1 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +37 -0
- data/README.md +68 -0
- data/Rakefile +20 -0
- data/lib/virtuoso.rb +22 -0
- data/lib/virtuoso/api/hypervisor.rb +30 -0
- data/lib/virtuoso/api/vm.rb +90 -0
- data/lib/virtuoso/error.rb +9 -0
- data/lib/virtuoso/version.rb +3 -0
- data/lib/virtuoso/virtualbox.rb +6 -0
- data/lib/virtuoso/virtualbox/hypervisor.rb +21 -0
- data/lib/virtuoso/virtualbox/vm.rb +85 -0
- data/test/test_helper.rb +30 -0
- data/test/virtuoso/api/vm_test.rb +70 -0
- data/test/virtuoso/virtuoso_test.rb +18 -0
- data/virtuoso.gemspec +26 -0
- metadata +129 -0
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-m markdown
|
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in virtuoso.gemspec
|
4
|
+
gem "virtuoso", :path => "."
|
5
|
+
|
6
|
+
# Use libvirt-rb straight from git, since Virtuoso dev requires
|
7
|
+
# the latest and greatest
|
8
|
+
gem "libvirt", :git => "git://github.com/mitchellh/libvirt-rb.git"
|
9
|
+
|
10
|
+
# Gems required for testing only.
|
11
|
+
group :development do
|
12
|
+
gem "protest", "~> 0.4.0"
|
13
|
+
gem "mocha", "~> 0.9.8"
|
14
|
+
|
15
|
+
# Not JRuby, which doesn't like bluecloth
|
16
|
+
platforms :ruby, :mri do
|
17
|
+
gem "yard", "~> 0.6.1"
|
18
|
+
gem "bluecloth", "~> 2.0.9"
|
19
|
+
end
|
20
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/mitchellh/libvirt-rb.git
|
3
|
+
revision: d06c4aef6e52723816b76b4e46b5f8cc985d5d8a
|
4
|
+
specs:
|
5
|
+
libvirt (0.2.1.dev)
|
6
|
+
ffi (~> 0.6.3)
|
7
|
+
nokogiri (~> 1.4.3)
|
8
|
+
|
9
|
+
PATH
|
10
|
+
remote: .
|
11
|
+
specs:
|
12
|
+
virtuoso (0.0.1)
|
13
|
+
libvirt (~> 0.2)
|
14
|
+
|
15
|
+
GEM
|
16
|
+
remote: http://rubygems.org/
|
17
|
+
specs:
|
18
|
+
bluecloth (2.0.9)
|
19
|
+
ffi (0.6.3)
|
20
|
+
rake (>= 0.8.7)
|
21
|
+
mocha (0.9.10)
|
22
|
+
rake
|
23
|
+
nokogiri (1.4.4)
|
24
|
+
protest (0.4.2)
|
25
|
+
rake (0.8.7)
|
26
|
+
yard (0.6.3)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bluecloth (~> 2.0.9)
|
33
|
+
libvirt!
|
34
|
+
mocha (~> 0.9.8)
|
35
|
+
protest (~> 0.4.0)
|
36
|
+
virtuoso!
|
37
|
+
yard (~> 0.6.1)
|
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Virtuoso
|
2
|
+
|
3
|
+
Virtuoso is a Ruby library that provides dead simple virtual machine
|
4
|
+
management across many hypervisors, using the powerful [libvirt](http://libvirt.org)
|
5
|
+
library underneath. Libvirt is an extremely powerful library, and the
|
6
|
+
focus of Virtuoso is to provide an extremely simple, common API for
|
7
|
+
managing virtual machines at the cost of sacrificing some of libvirt's
|
8
|
+
power.
|
9
|
+
|
10
|
+
Currently supported hypervisors:
|
11
|
+
|
12
|
+
- VirtualBox
|
13
|
+
|
14
|
+
Since Virtuoso is built on top of [libvirt](http://libvirt.org), it isn't
|
15
|
+
too difficult to add support for another hypervisor. The reason a libvirt-supported
|
16
|
+
hypervisor may not be supportd by Virtuoso at this time is most likely
|
17
|
+
because I don't have experience using that hypervisor. Open an issue if
|
18
|
+
you'd like to see support for another hypervisor.
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
The library is packaged as a gem:
|
23
|
+
|
24
|
+
gem install virtuoso
|
25
|
+
|
26
|
+
Additionally, you may need to install libvirt, the C-library used to
|
27
|
+
interface with the various hypervisors. On OS X the recommended way is
|
28
|
+
using [homebrew](http://github.com/mxcl/homebrew):
|
29
|
+
|
30
|
+
brew install libvirt
|
31
|
+
|
32
|
+
If you're on linux, your package manager should contain a compatible
|
33
|
+
version of libvirt.
|
34
|
+
|
35
|
+
## Project Status and Warning
|
36
|
+
|
37
|
+
**Warning:** This project is extremely _alpha_. The API will most definitely
|
38
|
+
change multiple times in the near future and the project itself will be
|
39
|
+
a fast moving target. This status will be updated in time as the project
|
40
|
+
matures.
|
41
|
+
|
42
|
+
## Usage
|
43
|
+
|
44
|
+
Below is an example of starting a VM with VirtualBox. All drivers (for
|
45
|
+
different hypervisors) are required to conform to the same API, so the
|
46
|
+
usage is the same for all other hypervisors.
|
47
|
+
|
48
|
+
require 'virtuoso'
|
49
|
+
|
50
|
+
# Connect to a libvirt instance. Virtuoso instantiates the proper
|
51
|
+
# hypervisor.
|
52
|
+
hypervisor = Virtuoso.connect("vbox:///session")
|
53
|
+
|
54
|
+
# Create a new VM within the hypervisor and start it
|
55
|
+
vm = hypervisor.new_vm
|
56
|
+
vm.name = "My Virtuoso VM"
|
57
|
+
vm.disk_image = "/home/mitchellh/lucid.vmdk"
|
58
|
+
vm.save
|
59
|
+
vm.start
|
60
|
+
|
61
|
+
# Watch it booting...
|
62
|
+
sleep 5
|
63
|
+
|
64
|
+
# Stop and destroy it
|
65
|
+
vm.stop
|
66
|
+
sleep 3
|
67
|
+
vm.destroy
|
68
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'bundler/setup'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc "Run the test suite."
|
9
|
+
task :test do
|
10
|
+
$:.unshift File.expand_path("../test", __FILE__)
|
11
|
+
files = ENV["TEST"] ? [ENV["TEST"]] : Dir["test/**/*_test.rb"]
|
12
|
+
files.each { |f| load f }
|
13
|
+
end
|
14
|
+
|
15
|
+
begin
|
16
|
+
# Documentation task
|
17
|
+
require 'yard'
|
18
|
+
YARD::Rake::YardocTask.new
|
19
|
+
rescue LoadError
|
20
|
+
end
|
data/lib/virtuoso.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'libvirt'
|
2
|
+
|
3
|
+
module Virtuoso
|
4
|
+
autoload :Error, "virtuoso/error"
|
5
|
+
autoload :VirtualBox, "virtuoso/virtualbox"
|
6
|
+
|
7
|
+
# Holds all the "abstract" classes for specifying and documenting
|
8
|
+
# the Virtuoso API.
|
9
|
+
module API
|
10
|
+
autoload :Hypervisor, "virtuoso/api/hypervisor"
|
11
|
+
autoload :VM, "virtuoso/api/vm"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Connects to a hypervisor given by the URL to a libvirt instance,
|
15
|
+
# and returns the proper hypervisor class based on the connection.
|
16
|
+
def self.connect(url=nil)
|
17
|
+
mapping = { "VBOX" => :VirtualBox }
|
18
|
+
conn = Libvirt.connect(url)
|
19
|
+
raise Error::UnsupportedHypervisorError, "Unsupported hypervisor: #{conn.hypervisor}" if !mapping[conn.hypervisor]
|
20
|
+
const_get(mapping[conn.hypervisor]).const_get(:Hypervisor).new(conn)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Virtuoso
|
2
|
+
module API
|
3
|
+
# Base class specifying the API for all hypervisors. Every feature in
|
4
|
+
# this base class must be overloaded by any hypervisors.
|
5
|
+
class Hypervisor
|
6
|
+
# The libvirt connection instance.
|
7
|
+
attr_reader :connection
|
8
|
+
|
9
|
+
# Initializes a hypervisor with the given libvirt connection. The
|
10
|
+
# connection should be established through {Virtuoso.connect}, which
|
11
|
+
# also chooses the correct hypervisor.
|
12
|
+
def initialize(connection)
|
13
|
+
@connection = connection
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns a new {VM} instance that can be used to create a new virtual
|
17
|
+
# machine.
|
18
|
+
#
|
19
|
+
# @return [VM]
|
20
|
+
def new_vm; end
|
21
|
+
|
22
|
+
# Searches for a VM with the given ID and returns it if it finds it,
|
23
|
+
# and otherwise returns nil. The exact semantics of the find are up to
|
24
|
+
# the hypervisor but typically it searches by both name and UUID.
|
25
|
+
#
|
26
|
+
# @return [VM]
|
27
|
+
def find(id); end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Virtuoso
|
2
|
+
module API
|
3
|
+
# Base class specifying the API that all VMs within a hypervisor must
|
4
|
+
# conform to.
|
5
|
+
class VM
|
6
|
+
# The libvirt connection instance.
|
7
|
+
attr_reader :connection
|
8
|
+
|
9
|
+
# The libvirt domain object.
|
10
|
+
attr_reader :domain
|
11
|
+
|
12
|
+
# The name of the VM.
|
13
|
+
attr_accessor :name
|
14
|
+
|
15
|
+
# The memory for the VM.
|
16
|
+
attr_accessor :memory
|
17
|
+
|
18
|
+
# The disk image to use as the main boot drive.
|
19
|
+
attr_accessor :disk_image
|
20
|
+
|
21
|
+
# Initializes a VM with the given libvirt connection.
|
22
|
+
def initialize(connection, domain=nil)
|
23
|
+
@connection = connection
|
24
|
+
@domain = domain
|
25
|
+
|
26
|
+
# Set reasonable defaults for fields if we can
|
27
|
+
@name = "My Virtuoso VM"
|
28
|
+
@memory = 524288 # 512 MB
|
29
|
+
|
30
|
+
# Load in the proper data
|
31
|
+
reload if domain
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the current state of the VM. This is expected to always
|
35
|
+
# return the current, up-to-date state (therefore it is _not_ cached
|
36
|
+
# and updated only on {#reload}). The state is meant to be returned
|
37
|
+
# as a symbol.
|
38
|
+
#
|
39
|
+
# @return [Symbol]
|
40
|
+
def state; end
|
41
|
+
|
42
|
+
# Saves the VM. If the VM is new, this is expected to create it
|
43
|
+
# initially, otherwise this is expected to update the existing
|
44
|
+
# VM.
|
45
|
+
def save; end
|
46
|
+
|
47
|
+
# Destroys the VM, deleting any information about it. This will not
|
48
|
+
# destroy any disk images, nor will it stop the VM if it is running.
|
49
|
+
def destroy; end
|
50
|
+
|
51
|
+
# Starts the VM.
|
52
|
+
def start; end
|
53
|
+
|
54
|
+
# Stops the VM.
|
55
|
+
def stop; end
|
56
|
+
|
57
|
+
# Reloads information from about a VM which exists. Since Virtuoso
|
58
|
+
# can't enforce any sort of VM locking, it is possible a VM changes
|
59
|
+
# in the background by some other process while it is being modified.
|
60
|
+
# In that case, when you attempt to save, your changes will either
|
61
|
+
# overwrite the previous settings, or fail altogether (if someone else
|
62
|
+
# destroyed the VM, for example). It is up to the developer to be
|
63
|
+
# knowledgeable about his or her environment and account for this
|
64
|
+
# accordingly. If you know that a VM changed, or you're just being
|
65
|
+
# careful, {#reload} may be called to reload the data associated
|
66
|
+
# with this VM and bring it up to date.
|
67
|
+
def reload; end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
# A helper method for subclasses to mark methods which require an
|
72
|
+
# existing VM to function (these are methods like `start` and `stop`).
|
73
|
+
# This method will raise an {Error::NewVMError} if an existing VM
|
74
|
+
# is not set.
|
75
|
+
def requires_existing_vm
|
76
|
+
raise Error::NewVMError if !domain
|
77
|
+
end
|
78
|
+
|
79
|
+
# A helper method for subclasses to set a domain object to represent
|
80
|
+
# this VM. This properly sets up the object and reloads it for the
|
81
|
+
# most up to date information.
|
82
|
+
def set_domain(domain)
|
83
|
+
@domain = domain
|
84
|
+
@domain_spec = nil
|
85
|
+
|
86
|
+
reload if domain
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Virtuoso
|
2
|
+
# Any exceptions which are thrown by Virtuoso (not lower-level libraries)
|
3
|
+
# exist in this module.
|
4
|
+
module Error
|
5
|
+
class VirtuosoError < StandardError; end
|
6
|
+
class UnsupportedHypervisorError < StandardError; end
|
7
|
+
class NewVMError < VirtuosoError; end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Virtuoso
|
2
|
+
module VirtualBox
|
3
|
+
# VirtualBox driver, allowing the control and management of
|
4
|
+
# VirtualBox virtual machines.
|
5
|
+
class Hypervisor < API::Hypervisor
|
6
|
+
def new_vm
|
7
|
+
VM.new(connection)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Searches for a VM by name or UUID.
|
11
|
+
#
|
12
|
+
# @param [String] id Name or UUID
|
13
|
+
# @return [VM]
|
14
|
+
def find(id)
|
15
|
+
result = connection.domains.find(id)
|
16
|
+
return nil if !result
|
17
|
+
VM.new(connection, result)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Virtuoso
|
2
|
+
module VirtualBox
|
3
|
+
# VirtualBox VM.
|
4
|
+
class VM < API::VM
|
5
|
+
def state
|
6
|
+
domain ? domain.state : :new
|
7
|
+
end
|
8
|
+
|
9
|
+
def save
|
10
|
+
# Setup the basic settings for the VM
|
11
|
+
d = Libvirt::Spec::Domain.new
|
12
|
+
d.hypervisor = :vbox
|
13
|
+
d.name = name
|
14
|
+
d.memory = memory
|
15
|
+
d.vcpu = 1
|
16
|
+
d.features = [:acpi, :pae]
|
17
|
+
d.clock.offset = :localtime
|
18
|
+
d.os.type = :hvm
|
19
|
+
d.os.arch = :i386
|
20
|
+
d.os.boot = [:cdrom, :hd]
|
21
|
+
|
22
|
+
# Attach the main hard disk
|
23
|
+
disk = Libvirt::Spec::Device.get(:disk).new
|
24
|
+
disk.type = :file
|
25
|
+
disk.device = :disk
|
26
|
+
disk.source = disk_image
|
27
|
+
disk.target_dev = :hda
|
28
|
+
disk.target_bus = :ide
|
29
|
+
d.devices << disk
|
30
|
+
|
31
|
+
# Attach a basic NAT network interface
|
32
|
+
nat = Libvirt::Spec::Device.get(:interface).new
|
33
|
+
nat.type = :user
|
34
|
+
nat.mac_address = "08:00:27:8f:7a:9f"
|
35
|
+
nat.model_type = "82540EM"
|
36
|
+
d.devices << nat
|
37
|
+
|
38
|
+
# Attach video information
|
39
|
+
video = Libvirt::Spec::Device.get(:video).new
|
40
|
+
model = Libvirt::Spec::Device::VideoModel.new
|
41
|
+
model.type = :vbox
|
42
|
+
model.vram = 12
|
43
|
+
model.heads = 1
|
44
|
+
model.accel3d = false
|
45
|
+
model.accel2d = false
|
46
|
+
video.models << model
|
47
|
+
d.devices << video
|
48
|
+
|
49
|
+
# At this point, assuming the virtuoso settings are correct, we
|
50
|
+
# should have a bootable VM spec, so define it and reload the VM
|
51
|
+
# information.
|
52
|
+
@domain = connection.domains.define(d)
|
53
|
+
reload
|
54
|
+
end
|
55
|
+
|
56
|
+
def destroy
|
57
|
+
requires_existing_vm
|
58
|
+
@domain.undefine
|
59
|
+
@domain = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def start
|
63
|
+
requires_existing_vm
|
64
|
+
domain.start
|
65
|
+
end
|
66
|
+
|
67
|
+
def stop
|
68
|
+
requires_existing_vm
|
69
|
+
domain.stop
|
70
|
+
end
|
71
|
+
|
72
|
+
def reload
|
73
|
+
# Load the main disk image path. We assume this is the first "disk"
|
74
|
+
# device, though this assumption is probably pretty weak.
|
75
|
+
spec = domain.spec
|
76
|
+
disk = spec.devices.find { |d| d.is_a?(Libvirt::Spec::Device::Disk) }
|
77
|
+
self.disk_image = disk.source
|
78
|
+
|
79
|
+
# Load the basic attributes
|
80
|
+
self.name = spec.name
|
81
|
+
self.memory = spec.memory
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "test/unit/assertions"
|
2
|
+
require "protest"
|
3
|
+
require "mocha"
|
4
|
+
require "virtuoso"
|
5
|
+
|
6
|
+
class Protest::TestCase
|
7
|
+
include Test::Unit::Assertions
|
8
|
+
include Mocha::API
|
9
|
+
|
10
|
+
# Get Mocha integrated properly into the tests
|
11
|
+
alias :original_run :run
|
12
|
+
def run(report)
|
13
|
+
original_run(report)
|
14
|
+
mocha_verify
|
15
|
+
ensure
|
16
|
+
mocha_teardown
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a connection to a libvirt test hypervisor.
|
20
|
+
def test_connection
|
21
|
+
Libvirt.connect("test:///default")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a domain object from the libvirt test hypervisor.
|
25
|
+
def test_domain
|
26
|
+
test_connection.domains.first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Protest.report_with(:progress)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
Protest.describe("API::VM") do
|
4
|
+
setup do
|
5
|
+
@klass = Virtuoso::API::VM
|
6
|
+
end
|
7
|
+
|
8
|
+
context "requiring an existing VM" do
|
9
|
+
setup do
|
10
|
+
@impl = Class.new(@klass) do
|
11
|
+
def save
|
12
|
+
@domain = true
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
requires_existing_vm
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@instance = @impl.new(test_connection)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "raise an exception if an existing VM is not set" do
|
24
|
+
assert_raises(Virtuoso::Error::NewVMError) { @instance.start }
|
25
|
+
end
|
26
|
+
|
27
|
+
should "not raise an exception if an existing VM is set" do
|
28
|
+
assert_nothing_raised {
|
29
|
+
@instance.save
|
30
|
+
@instance.start
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "initializing a VM" do
|
36
|
+
context "reloading" do
|
37
|
+
setup do
|
38
|
+
@impl = Class.new(@klass) do
|
39
|
+
def reload
|
40
|
+
throw :reloaded, :reload
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
should "reload if a domain is given" do
|
46
|
+
result = catch :reloaded do
|
47
|
+
@impl.new(test_connection, test_domain)
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal :reload, result
|
52
|
+
end
|
53
|
+
|
54
|
+
should "not load if a domain is not given" do
|
55
|
+
result = catch :reloaded do
|
56
|
+
@impl.new(test_connection)
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
assert !result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with a VM object" do
|
66
|
+
setup do
|
67
|
+
@instance = @klass.new(test_connection)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
Protest.describe("Virtuoso") do
|
4
|
+
setup do
|
5
|
+
@klass = Virtuoso
|
6
|
+
end
|
7
|
+
|
8
|
+
context "connecting" do
|
9
|
+
should "raise an exception if an unsupported hypervisor is connected to" do
|
10
|
+
assert_raises(Virtuoso::Error::UnsupportedHypervisorError) {
|
11
|
+
@klass.connect("test:///default")
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: To test other connections, hypervisor must be present... so we
|
16
|
+
# can't guarantee and test that yet.
|
17
|
+
end
|
18
|
+
end
|
data/virtuoso.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "virtuoso/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "virtuoso"
|
7
|
+
s.version = Virtuoso::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Mitchell Hashimoto"]
|
10
|
+
s.email = ["mitchell.hashimoto@gmail.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/virtuoso"
|
12
|
+
s.summary = "Dead simple virtual machine management for many hypervisors."
|
13
|
+
s.description = "Dead simple virtual machine management for many hypervisors."
|
14
|
+
|
15
|
+
s.rubyforge_project = "virtuoso"
|
16
|
+
|
17
|
+
s.add_dependency "libvirt", "~> 0.2"
|
18
|
+
|
19
|
+
s.add_development_dependency "protest", "~> 0.4.0"
|
20
|
+
s.add_development_dependency "mocha", "~> 0.9.8"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: virtuoso
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mitchell Hashimoto
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-07 00:00:00 -08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: libvirt
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 2
|
30
|
+
version: "0.2"
|
31
|
+
type: :runtime
|
32
|
+
prerelease: false
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: protest
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 4
|
44
|
+
- 0
|
45
|
+
version: 0.4.0
|
46
|
+
type: :development
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: mocha
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ~>
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
- 9
|
59
|
+
- 8
|
60
|
+
version: 0.9.8
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: *id003
|
64
|
+
description: Dead simple virtual machine management for many hypervisors.
|
65
|
+
email:
|
66
|
+
- mitchell.hashimoto@gmail.com
|
67
|
+
executables: []
|
68
|
+
|
69
|
+
extensions: []
|
70
|
+
|
71
|
+
extra_rdoc_files: []
|
72
|
+
|
73
|
+
files:
|
74
|
+
- .gitignore
|
75
|
+
- .yardopts
|
76
|
+
- Gemfile
|
77
|
+
- Gemfile.lock
|
78
|
+
- README.md
|
79
|
+
- Rakefile
|
80
|
+
- lib/virtuoso.rb
|
81
|
+
- lib/virtuoso/api/hypervisor.rb
|
82
|
+
- lib/virtuoso/api/vm.rb
|
83
|
+
- lib/virtuoso/error.rb
|
84
|
+
- lib/virtuoso/version.rb
|
85
|
+
- lib/virtuoso/virtualbox.rb
|
86
|
+
- lib/virtuoso/virtualbox/hypervisor.rb
|
87
|
+
- lib/virtuoso/virtualbox/vm.rb
|
88
|
+
- test/test_helper.rb
|
89
|
+
- test/virtuoso/api/vm_test.rb
|
90
|
+
- test/virtuoso/virtuoso_test.rb
|
91
|
+
- virtuoso.gemspec
|
92
|
+
has_rdoc: true
|
93
|
+
homepage: http://rubygems.org/gems/virtuoso
|
94
|
+
licenses: []
|
95
|
+
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: -4389485739309843364
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
version: "0"
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: -4389485739309843364
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
version: "0"
|
119
|
+
requirements: []
|
120
|
+
|
121
|
+
rubyforge_project: virtuoso
|
122
|
+
rubygems_version: 1.3.7
|
123
|
+
signing_key:
|
124
|
+
specification_version: 3
|
125
|
+
summary: Dead simple virtual machine management for many hypervisors.
|
126
|
+
test_files:
|
127
|
+
- test/test_helper.rb
|
128
|
+
- test/virtuoso/api/vm_test.rb
|
129
|
+
- test/virtuoso/virtuoso_test.rb
|