simple_stack 0.0.28 → 0.1.0
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.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.markdown +72 -0
- data/Rakefile +1 -0
- data/lib/simple_stack/cacheable.rb +24 -0
- data/lib/simple_stack/collection.rb +45 -0
- data/lib/simple_stack/connection.rb +21 -0
- data/lib/simple_stack/disk.rb +4 -0
- data/lib/simple_stack/entity.rb +44 -0
- data/lib/simple_stack/exception.rb +87 -0
- data/lib/simple_stack/guest.rb +86 -0
- data/lib/simple_stack/host.rb +4 -0
- data/lib/simple_stack/hypervisor.rb +130 -0
- data/lib/simple_stack/network_interface.rb +4 -0
- data/lib/simple_stack/snapshot.rb +11 -0
- data/lib/simple_stack/storage.rb +14 -0
- data/lib/simple_stack/version.rb +3 -0
- data/lib/simple_stack.rb +22 -0
- data/simple_stack.gemspec +23 -0
- metadata +21 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec7852762d8fb5388f29dbcb6d0c889958c4409e
|
|
4
|
+
data.tar.gz: 9b6c5482c4d1ff94cf126a6656292b8bf92f5f69
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4cf1159e2b0ba0c68cd11bd2f587e314959a37e5999b69683af636fb790efe93e76c25e6ca5acafdc2cb694e2bb8073ffaadee48128f5c70cd3db142838f0d15
|
|
7
|
+
data.tar.gz: 0572cb6541a74fa415a9c836b18e54dd5581465fb07ef5e9eedf5b95ed24342b285688046cb5b44d39ab67ac8490c72db775b45e77e8e8fadd870efd148fc508
|
data/Gemfile
ADDED
data/README.markdown
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Simplestack ruby client
|
|
2
|
+
=======================
|
|
3
|
+
|
|
4
|
+
A simple gem to deal with Simple Stack project.
|
|
5
|
+
|
|
6
|
+
Get a simplestack class:
|
|
7
|
+
|
|
8
|
+
stack = SimpleStack::Connection.new :url => url, :username => username, :password => password
|
|
9
|
+
|
|
10
|
+
Connecting to hypervisor:
|
|
11
|
+
|
|
12
|
+
vmware = stack.connect_to("vmware", :host => host, :username => username, :password => password)
|
|
13
|
+
|
|
14
|
+
Pool informations:
|
|
15
|
+
|
|
16
|
+
vmware.info
|
|
17
|
+
vmware.guests
|
|
18
|
+
|
|
19
|
+
# TODO:
|
|
20
|
+
# vmware.used_memory
|
|
21
|
+
# vmware.total_memory
|
|
22
|
+
# vmware.import vm_file
|
|
23
|
+
|
|
24
|
+
Working with Guests
|
|
25
|
+
-------------------
|
|
26
|
+
|
|
27
|
+
guest = vmware.guests.find(vm.uuid)
|
|
28
|
+
guest.info
|
|
29
|
+
guest.update(:name => "Guest name", :memory => 512)
|
|
30
|
+
guest.delete
|
|
31
|
+
|
|
32
|
+
Shutdown and power on and reboot
|
|
33
|
+
|
|
34
|
+
guest.stop
|
|
35
|
+
guest.start
|
|
36
|
+
guest.reboot
|
|
37
|
+
|
|
38
|
+
Force the guest shutdown
|
|
39
|
+
|
|
40
|
+
guest.force_stop
|
|
41
|
+
|
|
42
|
+
Resume and suspend guests
|
|
43
|
+
|
|
44
|
+
guest.resume
|
|
45
|
+
guest.pause
|
|
46
|
+
|
|
47
|
+
TODO:
|
|
48
|
+
|
|
49
|
+
file = guest.export :to => file_path
|
|
50
|
+
|
|
51
|
+
Snapshots
|
|
52
|
+
---------
|
|
53
|
+
|
|
54
|
+
List snapshots
|
|
55
|
+
|
|
56
|
+
guest.snapshots
|
|
57
|
+
|
|
58
|
+
Find a snapshot
|
|
59
|
+
|
|
60
|
+
guest.snapshots.find(snap.uuid)
|
|
61
|
+
|
|
62
|
+
Create a new snapshot
|
|
63
|
+
|
|
64
|
+
snap = guest.snapshots.create :name => :snapshot_name
|
|
65
|
+
|
|
66
|
+
Delete a snapshot
|
|
67
|
+
|
|
68
|
+
snap.delete
|
|
69
|
+
|
|
70
|
+
Revert a snapshot
|
|
71
|
+
|
|
72
|
+
snap.use
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
module Cacheable
|
|
3
|
+
def reload
|
|
4
|
+
@cached_attributes = {}
|
|
5
|
+
self
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def cacheable?
|
|
9
|
+
if respond_to? :connection
|
|
10
|
+
connection.cache_enabled
|
|
11
|
+
else
|
|
12
|
+
false
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def cached_attributes
|
|
17
|
+
if cacheable?
|
|
18
|
+
@cached_attributes ||= {}
|
|
19
|
+
else
|
|
20
|
+
{}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Collection
|
|
3
|
+
include SimpleStack::Cacheable
|
|
4
|
+
|
|
5
|
+
attr_accessor :hypervisor, :parent, :url, :clazz
|
|
6
|
+
|
|
7
|
+
def initialize(hypervisor, parent, url, clazz)
|
|
8
|
+
self.hypervisor = hypervisor
|
|
9
|
+
self.parent = parent
|
|
10
|
+
self.url = url.to_s
|
|
11
|
+
self.clazz = clazz
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_a
|
|
15
|
+
cached_attributes[:items] ||= hypervisor.get(url).map do |item|
|
|
16
|
+
clazz.new hypervisor, self, "#{url}/#{item["id"]}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def find(id)
|
|
21
|
+
clazz.new hypervisor, self, "#{url}/#{id}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def create(options={})
|
|
25
|
+
response = hypervisor.post(url, options)
|
|
26
|
+
entity_path = response.headers["location"].sub(/^\//, "").sub(/\/$/, "")
|
|
27
|
+
entity_url = "#{connection.url}/#{entity_path}"
|
|
28
|
+
new_item = clazz.new hypervisor, self, entity_url
|
|
29
|
+
reload if cacheable?
|
|
30
|
+
new_item
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def method_missing(method, *args, &block)
|
|
34
|
+
to_a.send(method, *args, &block)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def inspect
|
|
38
|
+
to_a.inspect
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def connection
|
|
42
|
+
hypervisor.connection
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Connection
|
|
3
|
+
attr_accessor :url, :graceful_degradation, :cache_enabled, :timeout, :read_timeout
|
|
4
|
+
|
|
5
|
+
def initialize(options = {})
|
|
6
|
+
self.url = options[:url].to_s.sub(/\/$/, "")
|
|
7
|
+
self.graceful_degradation = options[:graceful_degradation]
|
|
8
|
+
self.cache_enabled = options[:cache_enabled]
|
|
9
|
+
self.timeout = options[:timeout] || 60
|
|
10
|
+
self.read_timeout = options[:read_timeout] || timeout
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def connect_to(type, options)
|
|
14
|
+
SimpleStack::Hypervisor.new self, type, options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def token
|
|
18
|
+
"TODO"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Entity
|
|
3
|
+
include SimpleStack::Cacheable
|
|
4
|
+
|
|
5
|
+
attr_accessor :hypervisor, :parent, :url
|
|
6
|
+
|
|
7
|
+
def initialize(hypervisor, parent, url)
|
|
8
|
+
self.hypervisor = hypervisor
|
|
9
|
+
self.parent = parent
|
|
10
|
+
self.url = url.to_s
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def info
|
|
14
|
+
cached_attributes[:info] ||= hypervisor.get(url).parsed_response
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def update(attributes = {})
|
|
18
|
+
hypervisor.put url, attributes
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def delete
|
|
22
|
+
response = hypervisor.delete url
|
|
23
|
+
parent.reload if cacheable?
|
|
24
|
+
response
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inspect
|
|
28
|
+
"#<#{self.class} info=#{info.to_json}>"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def connection
|
|
32
|
+
hypervisor.connection
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def method_missing(method, *args, &block)
|
|
36
|
+
entity_info = info
|
|
37
|
+
if entity_info.keys.include?(method.to_s)
|
|
38
|
+
entity_info[method.to_s]
|
|
39
|
+
else
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Exception < ::Exception
|
|
3
|
+
def self.factory(error)
|
|
4
|
+
return Exception.new(error.inspect) if !error.is_a?(Hash)
|
|
5
|
+
case error["error"]
|
|
6
|
+
when "EntityNotFound"
|
|
7
|
+
EntityNotFound.new(error["message"])
|
|
8
|
+
when "FeatureNotImplemented"
|
|
9
|
+
NotImplemented.new(error["message"])
|
|
10
|
+
when "FeatureNotAvailable"
|
|
11
|
+
NotImplemented.new(error["message"])
|
|
12
|
+
when "HypervisorError"
|
|
13
|
+
HypervisorError.new(error["message"])
|
|
14
|
+
else
|
|
15
|
+
Exception.new(error.inspect)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class EntityNotFound < Exception
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class HypervisorError < Exception
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class NotImplemented < Exception
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class GracefulObject
|
|
30
|
+
def [](key)
|
|
31
|
+
GracefulObject.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def []=(key, value)
|
|
35
|
+
GracefulObject.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def +(other)
|
|
39
|
+
other + self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def -(other)
|
|
43
|
+
-(other - self)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def *(other)
|
|
47
|
+
other * self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def to_i
|
|
51
|
+
0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def to_f
|
|
55
|
+
0.0
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def to_str
|
|
59
|
+
"GracefulObject"
|
|
60
|
+
end
|
|
61
|
+
alias :to_s :to_str
|
|
62
|
+
|
|
63
|
+
def to_ary
|
|
64
|
+
[]
|
|
65
|
+
end
|
|
66
|
+
alias :to_a :to_ary
|
|
67
|
+
|
|
68
|
+
def to_hash
|
|
69
|
+
{}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def coerce(other)
|
|
73
|
+
coerced = if other.is_a? Fixnum
|
|
74
|
+
self.to_i
|
|
75
|
+
elsif other.is_a? String
|
|
76
|
+
self.to_s
|
|
77
|
+
elsif other.is_a? Array
|
|
78
|
+
self.to_a
|
|
79
|
+
elsif other.is_a? Hash
|
|
80
|
+
self.to_hash
|
|
81
|
+
else
|
|
82
|
+
nil
|
|
83
|
+
end
|
|
84
|
+
[coerced, other]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Guest < Entity
|
|
3
|
+
def disks
|
|
4
|
+
cached_attributes[:disks] ||= SimpleStack::Collection.new hypervisor, self, "#{url}/disks", SimpleStack::Disk
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def network_interfaces
|
|
8
|
+
cached_attributes[:network_interfaces] ||= SimpleStack::Collection.new hypervisor, self, "#{url}/network_interfaces", SimpleStack::NetworkInterface
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def snapshots
|
|
12
|
+
cached_attributes[:snapshots] ||= SimpleStack::Collection.new hypervisor, self, "#{url}/snapshots", SimpleStack::Snapshot
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def tags
|
|
16
|
+
cached_attributes[:tags] ||= hypervisor.get("#{url}/tags").parsed_response
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add_tag(tag)
|
|
20
|
+
hypervisor.post "#{url}/tags", :name => tag
|
|
21
|
+
reload if cacheable?
|
|
22
|
+
tag
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def remove_tag(tag)
|
|
26
|
+
hypervisor.delete "#{url}/tags/#{tag}"
|
|
27
|
+
reload if cacheable?
|
|
28
|
+
tag
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def reboot(opts={:force => false})
|
|
32
|
+
hypervisor.put "#{url}/reboot", :force => opts[:force]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def export(opts={})
|
|
36
|
+
opts = {:to => "/tmp/export_file"}.merge(opts)
|
|
37
|
+
file = File.open(opts[:to], "wb")
|
|
38
|
+
|
|
39
|
+
hypervisor.get_stream("#{url}/export", file)
|
|
40
|
+
|
|
41
|
+
opts[:to]
|
|
42
|
+
ensure
|
|
43
|
+
file.close rescue nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def revert_to(snapshot)
|
|
47
|
+
snapshot.revert
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def clone(opts={})
|
|
51
|
+
response = hypervisor.post("#{url}/clone", opts)
|
|
52
|
+
entity_path = response.headers["location"].sub(/^\//, "").sub(/\/$/, "")
|
|
53
|
+
entity_url = "#{connection.url}/#{entity_path}"
|
|
54
|
+
new_item = SimpleStack::Guest.new hypervisor, self, entity_url
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def insert_media(media_name, opts={})
|
|
58
|
+
media_options = opts.merge(:name => media_name)
|
|
59
|
+
hypervisor.put("#{url}/media_device", media_options)
|
|
60
|
+
reload if cacheable?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def eject_media
|
|
64
|
+
hypervisor.put("#{url}/media_device", :name => nil)
|
|
65
|
+
reload if cacheable?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def inserted_media
|
|
69
|
+
if cached_attributes.key? :inserted_media
|
|
70
|
+
cached_attributes[:inserted_media]
|
|
71
|
+
else
|
|
72
|
+
cached_attributes[:inserted_media] = hypervisor.get("#{url}/media_device").parsed_response["name"]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def power_state=(state)
|
|
77
|
+
hypervisor.put "#{url}/power", :state => state
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
["start", "stop", "force_stop", "pause", "resume"].each do |state|
|
|
81
|
+
define_method(state) do
|
|
82
|
+
self.power_state = state
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Hypervisor
|
|
3
|
+
include SimpleStack::Cacheable
|
|
4
|
+
|
|
5
|
+
attr_accessor :connection, :type, :host, :username, :password
|
|
6
|
+
|
|
7
|
+
def initialize(connection, type, options)
|
|
8
|
+
self.connection = connection
|
|
9
|
+
self.type = type
|
|
10
|
+
self.host = options[:host]
|
|
11
|
+
self.username = options[:username]
|
|
12
|
+
self.password = options[:password]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def url
|
|
16
|
+
"#{connection.url}/#{type}/#{host}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def headers
|
|
20
|
+
{
|
|
21
|
+
"x-simplestack-version" => "1.0",
|
|
22
|
+
"x-simplestack-token" => connection.token,
|
|
23
|
+
"x-simplestack-hypervisor-token" => token,
|
|
24
|
+
"Content-Type" => "application/json"
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def http_options
|
|
29
|
+
{
|
|
30
|
+
:timeout => connection.timeout,
|
|
31
|
+
:read_timeout => connection.read_timeout,
|
|
32
|
+
:no_follow => true,
|
|
33
|
+
:headers => headers
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def token
|
|
38
|
+
Base64.encode64("#{username}:#{password}").split("\n").join("")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def info
|
|
42
|
+
cached_attributes[:info] ||= self.get url
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def hosts
|
|
46
|
+
cached_attributes[:hosts] ||= SimpleStack::Collection.new self, self, "#{url}/hosts", SimpleStack::Host
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def storages
|
|
50
|
+
cached_attributes[:storages] ||= SimpleStack::Collection.new self, self, "#{url}/storages", SimpleStack::Storage
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def guests
|
|
54
|
+
cached_attributes[:guests] ||= SimpleStack::Collection.new self, self, "#{url}/guests", SimpleStack::Guest
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def import(opts={})
|
|
58
|
+
file = File.open(opts[:from], "rb")
|
|
59
|
+
|
|
60
|
+
response = post_stream("#{url}/guests", file)
|
|
61
|
+
entity_path = response["location"].sub(/^\//, "").sub(/\/$/, "")
|
|
62
|
+
entity_url = "#{connection.url}/#{entity_path}"
|
|
63
|
+
SimpleStack::Guest.new self, guests.reload, entity_url
|
|
64
|
+
ensure
|
|
65
|
+
file.close rescue nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def get(url)
|
|
69
|
+
http_call { HTTParty.get(url, http_options) }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def get_stream(url, io)
|
|
73
|
+
uri = URI.parse url
|
|
74
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
75
|
+
request = Net::HTTP::Get.new(uri.path)
|
|
76
|
+
|
|
77
|
+
headers.each_pair do |k, v|
|
|
78
|
+
request.add_field(k, v)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
http.request(request) do |res|
|
|
82
|
+
res.read_body {|chunk| io.write chunk }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def post(url, body)
|
|
87
|
+
http_call { HTTParty.post(url, http_options.merge(:body => JSON.dump(body))) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def put(url, body)
|
|
91
|
+
http_call { HTTParty.put(url, http_options.merge(:body => JSON.dump(body))) }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def post_stream(url, io)
|
|
95
|
+
uri = URI.parse url
|
|
96
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
97
|
+
request = Net::HTTP::Post.new(uri.path, {})
|
|
98
|
+
|
|
99
|
+
headers.each_pair do |k, v|
|
|
100
|
+
request.add_field(k, v)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
request.body_stream = io
|
|
104
|
+
request.content_length = io.size
|
|
105
|
+
response = http.request(request)
|
|
106
|
+
|
|
107
|
+
if response.code.to_i >= 400
|
|
108
|
+
parsed_response = JSON.load(response.body) rescue response.body
|
|
109
|
+
raise SimpleStack::Exception.factory(parsed_response)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
response
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def delete(url)
|
|
116
|
+
http_call { HTTParty.delete(url, http_options) }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def http_call
|
|
120
|
+
response = yield
|
|
121
|
+
return SimpleStack::GracefulObject.new if response.code == 501 && connection.graceful_degradation
|
|
122
|
+
raise SimpleStack::Exception.factory(response.parsed_response) if response.code >= 400
|
|
123
|
+
response
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def inspect
|
|
127
|
+
"#<#{self.class} url=#{url}>"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module SimpleStack
|
|
2
|
+
class Storage < Entity
|
|
3
|
+
def import(opts={})
|
|
4
|
+
file = File.open(opts[:from], "rb")
|
|
5
|
+
|
|
6
|
+
response = hypervisor.post_stream("#{url}/guests", file)
|
|
7
|
+
entity_path = response["location"].sub(/^\//, "").sub(/\/$/, "")
|
|
8
|
+
entity_url = "#{connection.url}/#{entity_path}"
|
|
9
|
+
SimpleStack::Guest.new hypervisor, hypervisor.guests.reload, entity_url
|
|
10
|
+
ensure
|
|
11
|
+
file.close rescue nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/simple_stack.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "base64"
|
|
3
|
+
require "httparty"
|
|
4
|
+
require "simple_stack/version"
|
|
5
|
+
require "simple_stack/exception"
|
|
6
|
+
require "simple_stack/connection"
|
|
7
|
+
require "simple_stack/cacheable"
|
|
8
|
+
require "simple_stack/collection"
|
|
9
|
+
require "simple_stack/hypervisor"
|
|
10
|
+
require "simple_stack/entity"
|
|
11
|
+
require "simple_stack/host"
|
|
12
|
+
require "simple_stack/storage"
|
|
13
|
+
require "simple_stack/guest"
|
|
14
|
+
require "simple_stack/snapshot"
|
|
15
|
+
require "simple_stack/network_interface"
|
|
16
|
+
require "simple_stack/disk"
|
|
17
|
+
|
|
18
|
+
module SimpleStack
|
|
19
|
+
def self.client
|
|
20
|
+
HTTParty
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "simple_stack/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "simple_stack"
|
|
7
|
+
s.version = SimpleStack::VERSION
|
|
8
|
+
s.authors = ["Thiago Morello", "Willian Molinari"]
|
|
9
|
+
s.email = ["thiago.morello@locaweb.com.br", "willian.molinari@locaweb.com.br"]
|
|
10
|
+
s.homepage = "https://github.com/locaweb/ruby-simplestack-client"
|
|
11
|
+
s.summary = %q{A simple gem to work with simplestack project}
|
|
12
|
+
s.description = s.summary
|
|
13
|
+
|
|
14
|
+
s.rubyforge_project = "simple_stack"
|
|
15
|
+
|
|
16
|
+
s.files = Dir["{lib}/**/*"] + ["Rakefile", "README.markdown", "Gemfile", "simple_stack.gemspec"]
|
|
17
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
18
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
s.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency "rspec"
|
|
22
|
+
s.add_runtime_dependency "httparty"
|
|
23
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: simple_stack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thiago Morello
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-09-
|
|
12
|
+
date: 2013-09-06 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rspec
|
|
@@ -46,7 +46,25 @@ email:
|
|
|
46
46
|
executables: []
|
|
47
47
|
extensions: []
|
|
48
48
|
extra_rdoc_files: []
|
|
49
|
-
files:
|
|
49
|
+
files:
|
|
50
|
+
- lib/simple_stack/snapshot.rb
|
|
51
|
+
- lib/simple_stack/exception.rb
|
|
52
|
+
- lib/simple_stack/network_interface.rb
|
|
53
|
+
- lib/simple_stack/version.rb
|
|
54
|
+
- lib/simple_stack/disk.rb
|
|
55
|
+
- lib/simple_stack/collection.rb
|
|
56
|
+
- lib/simple_stack/connection.rb
|
|
57
|
+
- lib/simple_stack/hypervisor.rb
|
|
58
|
+
- lib/simple_stack/entity.rb
|
|
59
|
+
- lib/simple_stack/storage.rb
|
|
60
|
+
- lib/simple_stack/host.rb
|
|
61
|
+
- lib/simple_stack/cacheable.rb
|
|
62
|
+
- lib/simple_stack/guest.rb
|
|
63
|
+
- lib/simple_stack.rb
|
|
64
|
+
- Rakefile
|
|
65
|
+
- README.markdown
|
|
66
|
+
- Gemfile
|
|
67
|
+
- simple_stack.gemspec
|
|
50
68
|
homepage: https://github.com/locaweb/ruby-simplestack-client
|
|
51
69
|
licenses: []
|
|
52
70
|
metadata: {}
|