lxc-ruby 0.2.3 → 0.3.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9b048cb271bb43ee64cf3759aa1916899b9c85e5
4
+ data.tar.gz: c91c3b7c6e0998b64eccf7e81f033781d997ff51
5
+ SHA512:
6
+ metadata.gz: fc5eddbca427353c4f33dbcab6f559949dddd2472239488badebc54eae7d8ed831462832ba7e7b67ec8230fc8e7841094d549d418a55814448d05fd08ed16217
7
+ data.tar.gz: de0f0ad1dea5a915b1ceddc781aaf488e1b19194ef4143e6604bb7d5c901cf67231c8355415a791e91245f4d12ad945a833ba34a019fe9cf07f9e286a696fca1
data/.gitignore CHANGED
@@ -8,6 +8,7 @@
8
8
  .bundle
9
9
  .config
10
10
  .yardoc
11
+ .vagrant
11
12
  Gemfile.lock
12
13
  InstalledFiles
13
14
  \#*
@@ -23,3 +24,4 @@ test/version_tmp
23
24
  tmp
24
25
  tmtags
25
26
  lib/test.rb
27
+ shared/
data/.travis.yml CHANGED
@@ -3,5 +3,6 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
+ - 2.0.0
6
7
  - rbx-18mode
7
8
  - rbx-19mode
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
  gemspec
data/README.md CHANGED
@@ -1,23 +1,17 @@
1
- # LXC Ruby Wrapper
1
+ # LXC Ruby Wrapper [![Build Status](https://secure.travis-ci.org/sosedoff/lxc-ruby.png?branch=master)](http://travis-ci.org/sosedoff/lxc-ruby)
2
2
 
3
- Ruby wrapper to [Linux Containers](http://lxc.sourceforge.net/) CLI tools
4
-
5
- ## Build status
6
-
7
- This library uses Travis-CI service for automated tests.
8
-
9
- [![Build Status](https://secure.travis-ci.org/sosedoff/lxc-ruby.png?branch=master)](http://travis-ci.org/sosedoff/lxc-ruby)
3
+ Ruby library to integrate with [Linux Containers](http://lxc.sourceforge.net/) CLI tools
10
4
 
11
5
  ## Requirements
12
6
 
13
7
  Supported LXC versions:
14
8
 
15
9
  - 0.7.5
16
- - 0.8.0-rc1
17
- - 0.8.0-rc2 - in works
10
+ - 0.8.0
18
11
 
19
- For testing purposes you can use [Vagrant](http://vagrantup.com/) or [VirtualBox](https://www.virtualbox.org/). Most of functionality
20
- was tested on Ubuntu 11.x / 12.04. Additional boxes could be found [here](http://www.vagrantbox.es/)
12
+ For testing purposes you can use [Vagrant](http://vagrantup.com/) with [VirtualBox](https://www.virtualbox.org/).
13
+ Most of the functionality was tested on 64-bit Ubuntu 11.10 and 12.04. Recommended version is 12.04.
14
+ Additional boxes could be found [here](http://www.vagrantbox.es/).
21
15
 
22
16
  ## Installation
23
17
 
@@ -64,10 +58,13 @@ Container instance is a simple abstaction for lxc's container tools:
64
58
  c = LXC.container('foo')
65
59
 
66
60
  # Get current status of container
67
- c.status # => {:state => 'RUNNING', :pid => 1234}
61
+ c.state # => 'running'
62
+ c.pid # => 1234
63
+ c.status # => <LXC::Status @state='running' @pid=123456>
68
64
 
69
65
  # Check if container exists?
70
- # this is needed since lxc does not raise any errors if container is
66
+ #
67
+ # This is needed since lxc does not raise any errors if container is
71
68
  # not present in the system, and returns the same result as if container
72
69
  # is actually stopped
73
70
  c.exists? # => true
@@ -78,8 +75,8 @@ c.stopped? # => false
78
75
  c.frozen? # => false
79
76
 
80
77
  # Start and stop containers
81
- c.start # => {:state => 'RUNNING', :pid => 1234}
82
- c.stop # => {:state => 'STOPPED', :pid => -1}
78
+ c.start # will be started in daemonized mode
79
+ c.stop
83
80
 
84
81
  # Free and unfreeze (also returns current status)
85
82
  c.freeze
data/Vagrantfile ADDED
@@ -0,0 +1,111 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "precise64"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
15
+
16
+ # Create a forwarded port mapping which allows access to a specific port
17
+ # within the machine from a port on the host machine. In the example below,
18
+ # accessing "localhost:8080" will access port 80 on the guest machine.
19
+ # config.vm.network :forwarded_port, guest: 80, host: 8080
20
+
21
+ # Create a private network, which allows host-only access to the machine
22
+ # using a specific IP.
23
+ config.vm.network :private_network, ip: "192.168.33.10"
24
+
25
+ # Create a public network, which generally matched to bridged network.
26
+ # Bridged networks make the machine appear as another physical device on
27
+ # your network.
28
+ # config.vm.network :public_network
29
+
30
+ # Share an additional folder to the guest VM. The first argument is
31
+ # the path on the host to the actual folder. The second argument is
32
+ # the path on the guest to mount the folder. And the optional third
33
+ # argument is a set of non-required options.
34
+ config.vm.synced_folder "./shared", "/shared"
35
+
36
+ # Provider-specific configuration so you can fine-tune various
37
+ # backing providers for Vagrant. These expose provider-specific options.
38
+ # Example for VirtualBox:
39
+ #
40
+ # config.vm.provider :virtualbox do |vb|
41
+ # # Don't boot with headless mode
42
+ # vb.gui = true
43
+ #
44
+ # # Use VBoxManage to customize the VM. For example to change memory:
45
+ # vb.customize ["modifyvm", :id, "--memory", "1024"]
46
+ # end
47
+ #
48
+ # View the documentation for the provider you're using for more
49
+ # information on available options.
50
+
51
+ # Enable provisioning with Puppet stand alone. Puppet manifests
52
+ # are contained in a directory path relative to this Vagrantfile.
53
+ # You will need to create the manifests directory and a manifest in
54
+ # the file base.pp in the manifests_path directory.
55
+ #
56
+ # An example Puppet manifest to provision the message of the day:
57
+ #
58
+ # # group { "puppet":
59
+ # # ensure => "present",
60
+ # # }
61
+ # #
62
+ # # File { owner => 0, group => 0, mode => 0644 }
63
+ # #
64
+ # # file { '/etc/motd':
65
+ # # content => "Welcome to your Vagrant-built virtual machine!
66
+ # # Managed by Puppet.\n"
67
+ # # }
68
+ #
69
+ # config.vm.provision :puppet do |puppet|
70
+ # puppet.manifests_path = "manifests"
71
+ # puppet.manifest_file = "base.pp"
72
+ # end
73
+
74
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
75
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
76
+ # some recipes and/or roles.
77
+ #
78
+ # config.vm.provision :chef_solo do |chef|
79
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
80
+ # chef.roles_path = "../my-recipes/roles"
81
+ # chef.data_bags_path = "../my-recipes/data_bags"
82
+ # chef.add_recipe "mysql"
83
+ # chef.add_role "web"
84
+ #
85
+ # # You may also specify custom JSON attributes:
86
+ # chef.json = { :mysql_password => "foo" }
87
+ # end
88
+
89
+ # Enable provisioning with chef server, specifying the chef server URL,
90
+ # and the path to the validation key (relative to this Vagrantfile).
91
+ #
92
+ # The Opscode Platform uses HTTPS. Substitute your organization for
93
+ # ORGNAME in the URL and validation key.
94
+ #
95
+ # If you have your own Chef Server, use the appropriate URL, which may be
96
+ # HTTP instead of HTTPS depending on your configuration. Also change the
97
+ # validation key to validation.pem.
98
+ #
99
+ # config.vm.provision :chef_client do |chef|
100
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
101
+ # chef.validation_key_path = "ORGNAME-validator.pem"
102
+ # end
103
+ #
104
+ # If you're using the Opscode platform, your validator client is
105
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
106
+ #
107
+ # If you have your own Chef Server, the default validation client name is
108
+ # chef-validator, unless you changed the configuration.
109
+ #
110
+ # chef.validation_client_name = "ORGNAME-validator"
111
+ end
@@ -17,9 +17,11 @@ module LXC
17
17
  # @return [LXC::Configuration]
18
18
  def self.load_file(path)
19
19
  fullpath = File.expand_path(path)
20
+
20
21
  if !File.exists?(fullpath)
21
22
  raise ArgumentError, "File '#{path}' does not exist."
22
23
  end
24
+
23
25
  LXC::Configuration.new(File.read(fullpath))
24
26
  end
25
27
 
@@ -45,15 +47,20 @@ module LXC
45
47
  def save_to_file(path)
46
48
  fullpath = File.expand_path(path)
47
49
  lines = []
50
+
48
51
  @content.each_pair do |key,value|
49
52
  k = "lxc.#{key.gsub('_', '.')}"
53
+
50
54
  if value.kind_of?(Array)
51
55
  lines << value.map { |v| "#{k} = #{v}" }
52
56
  else
53
57
  lines << "#{k} = #{value}"
54
58
  end
55
59
  end
56
- File.open(path, 'w') { |f| f.write(lines.flatten.join("\n")) }
60
+
61
+ File.open(path, 'w') do |f|
62
+ f.write(lines.flatten.join("\n"))
63
+ end
57
64
  end
58
65
 
59
66
  private
@@ -61,16 +68,24 @@ module LXC
61
68
  def parse(data)
62
69
  hash = {}
63
70
  lines = data.split("\n").map(&:strip).select { |l| !l.empty? && l[0,1] != '#' }
71
+
64
72
  lines.each do |l|
65
73
  key,value = l.split('=').map(&:strip)
74
+
66
75
  if !valid_option?(key)
67
76
  raise ConfigurationError, "Invalid config attribute: #{key}."
68
77
  end
78
+
69
79
  key.gsub!(/^lxc\./, '').gsub!('.', '_')
80
+
70
81
  hash[key] = [] if !hash.key?(key)
71
82
  hash[key] << value
72
83
  end
73
- hash.each_pair { |k,v| hash[k] = v.first if v.size == 1 }
84
+
85
+ hash.each_pair do |k, v|
86
+ hash[k] = v.first if v.size == 1
87
+ end
88
+
74
89
  hash
75
90
  end
76
91
  end
data/lib/lxc/container.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  module LXC
2
2
  class Container
3
3
  attr_accessor :name
4
- attr_reader :state
5
- attr_reader :pid
6
4
 
7
5
  # Initialize a new LXC::Container instance
8
6
  # @param [String] name container name
@@ -14,17 +12,28 @@ module LXC
14
12
  # Get container attributes hash
15
13
  # @return [Hash]
16
14
  def to_hash
17
- status
18
- {'name' => name, 'state' => state, 'pid' => pid}
15
+ status.to_hash.merge('name' => name)
19
16
  end
20
17
 
21
18
  # Get current status of container
22
19
  # @return [Hash] hash with :state and :pid attributes
23
20
  def status
24
- str = LXC.run('info', '-n', name)
25
- @state = str.scan(/^state:\s+([\w]+)$/).flatten.first
26
- @pid = str.scan(/^pid:\s+(-?[\d]+)$/).flatten.first
27
- {:state => @state, :pid => @pid}
21
+ output = run('info')
22
+ result = output.scan(/^state:\s+([\w]+)|pid:\s+(-?[\d]+)$/).flatten
23
+
24
+ LXC::Status.new(result.first, result.last)
25
+ end
26
+
27
+ # Get state of the container
28
+ # @return [String]
29
+ def state
30
+ status.state
31
+ end
32
+
33
+ # Get PID of the container
34
+ # @return [Integer]
35
+ def pid
36
+ status.pid
28
37
  end
29
38
 
30
39
  # Check if container exists
@@ -36,19 +45,19 @@ module LXC
36
45
  # Check if container is running
37
46
  # @return [Boolean]
38
47
  def running?
39
- status[:state] == 'RUNNING'
48
+ status.state == 'running'
40
49
  end
41
50
 
42
51
  # Check if container is frozen
43
52
  # @return [Boolean]
44
53
  def frozen?
45
- status[:state] == 'FROZEN'
54
+ status.state == 'frozen'
46
55
  end
47
56
 
48
- # Check if container is stopped?
57
+ # Check if container is stopped
49
58
  # @return [Boolean]
50
59
  def stopped?
51
- exists? && status[:state] == 'STOPPED'
60
+ exists? && status.state == 'stopped'
52
61
  end
53
62
 
54
63
  # Start container
@@ -68,8 +77,8 @@ module LXC
68
77
  # Restart container
69
78
  # @return [Hash] container status hash
70
79
  def restart
71
- stop
72
- start
80
+ stop ; start
81
+ status
73
82
  end
74
83
 
75
84
  # Freeze container
@@ -87,9 +96,9 @@ module LXC
87
96
  end
88
97
 
89
98
  # Wait for container to change status
90
- # @param [String] state state name
99
+ # @param [String] state name
91
100
  def wait(state)
92
- if !LXC::Shell.valid_state?(state)
101
+ if !LXC::Shell.valid_state?(status.state)
93
102
  raise ArgumentError, "Invalid container state: #{state}"
94
103
  end
95
104
 
@@ -111,14 +120,14 @@ module LXC
111
120
  # Get container cpu shares
112
121
  # @return [Integer]
113
122
  def cpu_shares
114
- result = run('cgroup', "cpu.shares").strip
123
+ result = run('cgroup', "cpu.shares").to_s.strip
115
124
  result.empty? ? nil : result.to_i
116
125
  end
117
126
 
118
127
  # Get container cpu usage in seconds
119
128
  # @return [Float]
120
129
  def cpu_usage
121
- result = run('cgroup', "cpuacct.usage").strip
130
+ result = run('cgroup', "cpuacct.usage").to_s.strip
122
131
  result.empty? ? nil : Float('%.4f' % (result.to_i / 1E9))
123
132
  end
124
133
 
@@ -149,7 +158,8 @@ module LXC
149
158
  end
150
159
 
151
160
  if !!path[:template]
152
- template_path = "/usr/lib/lxc/templates/lxc-#{path[:template]}"
161
+ template_dir = path[:template_dir] || '/usr/lib/lxc/templates'
162
+ template_path = File.join(template_dir,"lxc-#{path[:template]}")
153
163
  unless File.exists?(template_path)
154
164
  raise ArgumentError, "Template #{path[:template]} does not exist."
155
165
  end
@@ -163,7 +173,7 @@ module LXC
163
173
  exists?
164
174
  else
165
175
  raise ArgumentError, "File #{path} does not exist." unless File.exists?(path)
166
- LXC.run('create', '-n', name, '-f', path)
176
+ LXC.run('create', '-f', path)
167
177
  exists?
168
178
  end
169
179
  end
@@ -173,12 +183,13 @@ module LXC
173
183
  # @return [LXC::Container] new container instance
174
184
  def clone_to(target)
175
185
  raise ContainerError, "Container does not exist." unless exists?
176
- if self.class.new(target).exists?
186
+
187
+ if LXC.container(target).exists?
177
188
  raise ContainerError, "New container already exists."
178
189
  end
179
190
 
180
191
  LXC.run('clone', '-o', name, '-n', target)
181
- self.class.new target
192
+ LXC.container(target)
182
193
  end
183
194
 
184
195
  # Create a new container from an existing container
@@ -186,11 +197,12 @@ module LXC
186
197
  # @return [Boolean]
187
198
  def clone_from(source)
188
199
  raise ContainerError, "Container already exists." if exists?
189
- unless self.class.new(source).exists?
200
+
201
+ unless LXC.container(source).exists?
190
202
  raise ContainerError, "Source container does not exist."
191
203
  end
192
204
 
193
- LXC.run('clone', '-o', source, '-n', name)
205
+ run('clone', '-o', source)
194
206
  exists?
195
207
  end
196
208
 
@@ -202,18 +214,19 @@ module LXC
202
214
  # it will be stopped first. Otherwise it will raise exception.
203
215
  #
204
216
  def destroy(force=false)
205
- raise ContainerError, "Container does not exist." unless exists?
217
+ unless exists?
218
+ raise ContainerError, "Container does not exist."
219
+ end
206
220
 
207
221
  if running?
208
- if force
209
- # This will force stop and destroy container automatically
210
- run('destroy', '-f')
222
+ if force == true
223
+ stop
211
224
  else
212
225
  raise ContainerError, "Container is running. Stop it first or use force=true"
213
- end
214
- else
215
- run('destroy')
216
- end
226
+ end
227
+ end
228
+
229
+ run('destroy')
217
230
 
218
231
  !exists?
219
232
  end
@@ -228,20 +241,13 @@ module LXC
228
241
  chunks = line.split(' ')
229
242
  chunks.delete_at(0)
230
243
 
231
- pid = chunks.shift
232
- user = chunks.shift
233
- cpu = chunks.shift
234
- mem = chunks.shift
235
- command = chunks.shift
236
- args = chunks.join(' ')
237
-
238
244
  {
239
- 'pid' => pid,
240
- 'user' => user,
241
- 'cpu' => cpu,
242
- 'memory' => mem,
243
- 'command' => command,
244
- 'args' => args
245
+ 'pid' => chunks.shift,
246
+ 'user' => chunks.shift,
247
+ 'cpu' => chunks.shift,
248
+ 'memory' => chunks.shift,
249
+ 'command' => chunks.shift,
250
+ 'args' => chunks.join(' ')
245
251
  }
246
252
  end
247
253
  end
data/lib/lxc/shell.rb CHANGED
@@ -78,15 +78,18 @@ module LXC
78
78
  # provide a block that returns string
79
79
  def run(command, *args)
80
80
  command_name = "lxc-#{command}"
81
+
81
82
  unless BIN_FILES.include?(command_name)
82
83
  raise ArgumentError, "Invalid command: #{command_name}."
83
84
  end
84
85
 
85
86
  cmd = ""
86
- cmd += "sudo " if use_sudo == true
87
- cmd += "#{command_name} #{args.join(' ')}".strip
88
- cmd += " | #{yield}" if block_given?
89
- `#{cmd.strip}`
87
+ cmd << "sudo " if use_sudo == true
88
+ cmd << "#{command_name} #{args.join(' ')}".strip
89
+ cmd << " | #{yield}" if block_given?
90
+
91
+ child = POSIX::Spawn::Child.new(cmd.strip)
92
+ child.out
90
93
  end
91
94
  end
92
95
  end
data/lib/lxc/status.rb ADDED
@@ -0,0 +1,22 @@
1
+ module LXC
2
+ class Status
3
+ attr_reader :state, :pid
4
+
5
+ def initialize(state, pid)
6
+ @state = state.to_s.downcase
7
+ @pid = Integer(pid)
8
+ end
9
+
10
+ def == (instance)
11
+ instance.pid == pid && instance.state == state
12
+ end
13
+
14
+ def to_hash
15
+ {'state' => state, 'pid' => pid}
16
+ end
17
+
18
+ def to_s
19
+ "state=#{state} pid=#{pid}"
20
+ end
21
+ end
22
+ end
data/lib/lxc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LXC
2
- VERSION = '0.2.3'
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/lxc.rb CHANGED
@@ -1,58 +1,67 @@
1
+ require 'posix/spawn'
1
2
  require 'lxc/version'
2
- require 'lxc/errors'
3
- require 'lxc/shell'
4
- require 'lxc/configuration_options'
5
- require 'lxc/configuration'
6
- require 'lxc/container'
7
3
 
8
4
  module LXC
5
+ class Error < StandardError ; end
6
+ class ContainerError < Error ; end
7
+ class ConfigurationError < Error ; end
8
+
9
+ autoload :Shell, 'lxc/shell'
10
+ autoload :Configuration, 'lxc/configuration'
11
+ autoload :ConfigurationOptions, 'lxc/configuration_options'
12
+ autoload :Container, 'lxc/container'
13
+ autoload :Status, 'lxc/status'
14
+
9
15
  class << self
10
16
  include LXC::Shell
17
+ end
18
+
19
+ # Check if binary file is installed
20
+ # @param [String] binary filename
21
+ # @return [Boolean] true if installed
22
+ def self.binary_installed?(name)
23
+ path = File.join(LXC::Shell::BIN_PREFIX, name)
24
+ File.exists?(path)
25
+ end
26
+
27
+ # Check if all binaries are present in the system
28
+ # @return [Boolean] true if binary files are found
29
+ def self.installed?
30
+ LXC::Shell::BIN_FILES.all?{ |f| binary_installed?(f) }
31
+ end
32
+
33
+ # Get LXC configuration info
34
+ # @return [Hash] hash containing config groups
35
+ def self.config
36
+ str = LXC.run('checkconfig') { LXC::Shell::REMOVE_COLORS }
37
+
38
+ data = str.scan(/^([\w\s]+): (enabled|disabled)$/).map { |r|
39
+ [r.first.downcase.gsub(' ', '_'), r.last == 'enabled']
40
+ }
41
+
42
+ Hash[data]
43
+ end
44
+
45
+ # Get a single container instance
46
+ # @param [String] name of the container
47
+ # @return [LXC::Container] container instance
48
+ def self.container(name)
49
+ LXC::Container.new(name)
50
+ end
51
+
52
+ # Get a list of all available containers
53
+ # @param [String] select containers that match string
54
+ # @return [Array] array of LXC::Containers
55
+ def self.containers(filter=nil)
56
+ names = LXC.run('ls').split("\n").uniq
57
+
58
+ names.delete_if { |v| !v.include?(filter) } if filter.kind_of?(String)
59
+ names.map { |name| LXC::Container.new(name) }
60
+ end
11
61
 
12
- # Check if binary file is installed
13
- # @param [String] binary filename
14
- # @return [Boolean] true if installed
15
- def binary_installed?(name)
16
- path = File.join(LXC::Shell::BIN_PREFIX, name)
17
- File.exists?(path)
18
- end
19
-
20
- # Check if all binaries are present in the system
21
- # @return [Boolean] true if binary files are found
22
- def installed?
23
- !BIN_FILES.map { |f| binary_installed?(f) }.uniq.include?(false)
24
- end
25
-
26
- # Get LXC configuration info
27
- # @return [Hash] hash containing config groups
28
- def config
29
- str = LXC.run('checkconfig') { LXC::Shell::REMOVE_COLORS }
30
- data = str.scan(/^([\w\s]+): (enabled|disabled)$/).map { |r|
31
- [r.first.downcase.gsub(' ', '_'), r.last == 'enabled']
32
- }
33
- Hash[data]
34
- end
35
-
36
- # Get container information record
37
- # @param [name] container name
38
- # @return [LXC::Container] container instance
39
- def container(name)
40
- LXC::Container.new(name)
41
- end
42
-
43
- # Get a list of all available containers
44
- # @param [String] select containers that match string
45
- # @return [Array] array of LXC::Containers
46
- def containers(filter=nil)
47
- names = LXC.run('ls').split("\n").uniq
48
- names.delete_if { |v| !v.include?(filter) } if filter.kind_of?(String)
49
- names.map { |name| Container.new(name) }
50
- end
51
-
52
- # Get current LXC version
53
- # @return [String] current LXC version
54
- def version
55
- LXC.run('version').strip.split(' ').last
56
- end
62
+ # Get currently installeded LXC version
63
+ # @return [String] current LXC version
64
+ def self.version
65
+ LXC.run('version').strip.split(' ').last
57
66
  end
58
- end
67
+ end
@@ -8,10 +8,12 @@ Gem::Specification.new do |s|
8
8
  s.homepage = "http://github.com/sosedoff/lxc-ruby"
9
9
  s.authors = ["Dan Sosedoff"]
10
10
  s.email = ["dan.sosedoff@gmail.com"]
11
+
12
+ s.add_dependency 'posix-spawn', '~> 0.3.6'
11
13
 
12
14
  s.add_development_dependency 'rake'
13
- s.add_development_dependency 'rspec', '~> 2.6'
14
- s.add_development_dependency 'simplecov', '~> 0.4'
15
+ s.add_development_dependency 'rspec', '~> 2.13'
16
+ s.add_development_dependency 'simplecov', '~> 0.7'
15
17
 
16
18
  s.files = `git ls-files`.split("\n")
17
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -3,13 +3,13 @@ require 'spec_helper'
3
3
  describe LXC::Configuration do
4
4
  it 'parses config data' do
5
5
  conf = LXC::Configuration.new(fixture('configuration.txt'))
6
- conf.content.should be_a Hash
7
- conf.attributes.should be_an Array
8
- conf.attributes.should_not be_empty
9
- conf.utsname.should_not be_nil
10
- conf['utsname'].should_not be_nil
11
- conf[:utsname].should_not be_nil
12
- conf.network_ipv4.should_not be_nil
6
+ expect(conf.content).to be_a Hash
7
+ expect(conf.attributes).to be_an Array
8
+ expect(conf.attributes).to_not be_empty
9
+ expect(conf.utsname).to_not be_nil
10
+ expect(conf['utsname']).to_not be_nil
11
+ expect(conf[:utsname]).to_not be_nil
12
+ expect(conf.network_ipv4).to_not be_nil
13
13
  end
14
14
 
15
15
  it 'saves config data into file' do
@@ -17,6 +17,6 @@ describe LXC::Configuration do
17
17
  conf.save_to_file('/tmp/lxc.txt')
18
18
  c1 = LXC::Configuration.new(fixture('configuration.txt'))
19
19
  c2 = LXC::Configuration.new(File.read('/tmp/lxc.txt'))
20
- c1.content.should eq(c2.content)
20
+ expect(c1.content).to eq(c2.content)
21
21
  end
22
- end
22
+ end
@@ -3,28 +3,29 @@ require 'spec_helper'
3
3
  describe LXC::Container do
4
4
  subject { LXC::Container.new('app') }
5
5
 
6
- it { should respond_to(:name) }
7
- it { should respond_to(:state) }
8
- it { should respond_to(:pid) }
9
-
10
- it 'has proper default attributes' do
11
- subject.name.should eq('app')
12
- subject.state.should be_nil
13
- subject.pid.should be_nil
6
+ it { should respond_to :name }
7
+ it { should respond_to :status }
8
+ it { should respond_to :state }
9
+ it { should respond_to :pid }
10
+
11
+ describe '#name' do
12
+ it 'should be set to "app"' do
13
+ expect(subject.name).to eq 'app'
14
+ end
14
15
  end
15
16
 
16
17
  describe '#exists?' do
17
18
  context 'for existing container' do
18
19
  it 'returns true' do
19
20
  stub_lxc('ls') { "app\napp2" }
20
- subject.exists?.should be_true
21
+ expect(subject).to exist
21
22
  end
22
23
  end
23
24
 
24
25
  context 'for non-existing container' do
25
26
  it 'returns false' do
26
27
  stub_lxc('ls') { "app2\napp3" }
27
- subject.exists?.should be_false
28
+ expect(subject).to_not exist
28
29
  end
29
30
  end
30
31
  end
@@ -32,41 +33,60 @@ describe LXC::Container do
32
33
  describe '#status' do
33
34
  it 'returns STOPPED' do
34
35
  stub_lxc('info', '-n', 'app') { fixture('lxc-info-stopped.txt') }
35
- subject.status.should eq({:state => 'STOPPED', :pid => '-1'})
36
+ expect(subject.status).to eq LXC::Status.new('STOPPED', '-1')
36
37
  end
37
38
 
38
39
  it 'returns RUNNING' do
39
40
  stub_lxc('info', '-n', 'app') { fixture('lxc-info-running.txt') }
40
- subject.status.should eq({:state => 'RUNNING', :pid => '2125'})
41
+ expect(subject.status).to eq LXC::Status.new('RUNNING', '2125')
41
42
  end
42
43
  end
43
44
 
44
45
  describe '#destroy' do
45
46
  it 'raises error if container does not exist' do
46
47
  stub_lxc('ls') { "app2" }
47
- proc { subject.destroy }.
48
- should raise_error LXC::ContainerError, "Container does not exist."
48
+
49
+ expect {
50
+ subject.destroy
51
+ }.to raise_error LXC::ContainerError, "Container does not exist."
49
52
  end
50
53
 
51
54
  it 'raises error if container is running' do
52
- stub_lxc('ls') { "app" }
53
- stub_lxc('info', '-n', 'app') { fixture('lxc-info-running.txt') }
54
- proc { subject.destroy }.
55
- should raise_error LXC::ContainerError, "Container is running. Stop it first or use force=true"
55
+ subject.stub(:exists?).and_return(true)
56
+ subject.stub(:running?).and_return(true)
57
+
58
+ expect {
59
+ subject.destroy
60
+ }.to raise_error LXC::ContainerError, "Container is running. Stop it first or use force=true"
61
+ end
62
+
63
+ context 'with force=true' do
64
+ before do
65
+ stub_lxc('ls') { 'app' }
66
+ stub_lxc('info', '-n', 'app') { fixture 'lxc-info-running.txt' }
67
+ stub_lxc('stop', '-n', 'app') { '' }
68
+ stub_lxc('info', '-n', 'app') { fixture 'lxc-info-stopped.txt' }
69
+ stub_lxc('destroy', '-n', 'app') { '' }
70
+ stub_lxc('ls') { '' }
71
+ end
72
+
73
+ it 'stops and destroys container' do
74
+ expect(subject.destroy(true)).to be_true
75
+ end
56
76
  end
57
77
  end
58
78
 
59
79
  describe '#memory_usage' do
60
80
  it 'returns the amount of used memory' do
61
81
  stub_lxc('cgroup', '-n', 'app', 'memory.usage_in_bytes') { "3280896\n" }
62
- subject.memory_usage.should eq(3280896)
82
+ expect(subject.memory_usage).to eq(3280896)
63
83
  end
64
84
  end
65
85
 
66
86
  describe '#memory_limit' do
67
87
  it 'returns the memory limit' do
68
88
  stub_lxc('cgroup', '-n', 'app', 'memory.limit_in_bytes') { "268435456\n" }
69
- subject.memory_limit.should eq(268435456)
89
+ expect(subject.memory_limit).to eq(268435456)
70
90
  end
71
91
  end
72
92
 
@@ -74,8 +94,9 @@ describe LXC::Container do
74
94
  it 'raises error if container is not running' do
75
95
  stub_lxc('info', '-n', 'app') { fixture('lxc-info-stopped.txt') }
76
96
 
77
- proc { subject.processes }.
78
- should raise_error LXC::ContainerError, "Container is not running"
97
+ expect {
98
+ subject.processes
99
+ }.to raise_error LXC::ContainerError, "Container is not running"
79
100
  end
80
101
 
81
102
  it 'returns list of all processes' do
@@ -83,16 +104,16 @@ describe LXC::Container do
83
104
  stub_lxc('ps', '-n', 'app', '--', '-eo pid,user,%cpu,%mem,args') { fixture('lxc-ps-aux.txt') }
84
105
 
85
106
  list = subject.processes
86
- list.should be_an Array
107
+ expect(list).to be_an Array
87
108
 
88
109
  p = list.first
89
- p.should be_a Hash
90
- p.should have_key('pid')
91
- p.should have_key('user')
92
- p.should have_key('cpu')
93
- p.should have_key('memory')
94
- p.should have_key('command')
95
- p.should have_key('args')
110
+ expect(p).to be_a Hash
111
+ expect(p).to have_key('pid')
112
+ expect(p).to have_key('user')
113
+ expect(p).to have_key('cpu')
114
+ expect(p).to have_key('memory')
115
+ expect(p).to have_key('command')
116
+ expect(p).to have_key('args')
96
117
  end
97
118
  end
98
119
 
@@ -100,7 +121,7 @@ describe LXC::Container do
100
121
  context 'when container does not exist' do
101
122
  it 'returns false' do
102
123
  stub_lxc('ls') { "foo-app" }
103
- subject.stopped?.should be_false
124
+ expect(subject).to_not be_stopped
104
125
  end
105
126
  end
106
127
 
@@ -109,14 +130,14 @@ describe LXC::Container do
109
130
  stub_lxc('ls') { 'app' }
110
131
  stub_lxc('info', '-n', 'app') { fixture('lxc-info-stopped.txt') }
111
132
 
112
- subject.stopped?.should be_true
133
+ expect(subject).to be_stopped
113
134
  end
114
135
 
115
136
  it 'returns false if running' do
116
137
  stub_lxc('ls') { 'app' }
117
138
  stub_lxc('info', '-n', 'app') { fixture('lxc-info-running.txt') }
118
139
 
119
- subject.stopped?.should be_false
140
+ expect(subject).to_not be_stopped
120
141
  end
121
142
  end
122
143
  end
@@ -128,7 +149,7 @@ describe LXC::Container do
128
149
  end
129
150
 
130
151
  it 'returns cpu shares value' do
131
- subject.cpu_shares.should eq 1024
152
+ expect(subject.cpu_shares).to eq 1024
132
153
  end
133
154
  end
134
155
 
@@ -138,7 +159,17 @@ describe LXC::Container do
138
159
  end
139
160
 
140
161
  it 'returns nil' do
141
- subject.cpu_shares.should be_nil
162
+ expect(subject.cpu_shares).to be_nil
163
+ end
164
+ end
165
+
166
+ context 'when run command is nil' do
167
+ before do
168
+ subject.stub(:run).and_return(nil)
169
+ end
170
+
171
+ it 'should return nil' do
172
+ expect(subject.cpu_shares).to be_nil
142
173
  end
143
174
  end
144
175
  end
@@ -150,7 +181,7 @@ describe LXC::Container do
150
181
  end
151
182
 
152
183
  it 'returns usage in seconds' do
153
- subject.cpu_usage.should eq 4239.0819
184
+ expect(subject.cpu_usage).to eq 4239.0819
154
185
  end
155
186
  end
156
187
 
@@ -160,7 +191,17 @@ describe LXC::Container do
160
191
  end
161
192
 
162
193
  it 'returns nil' do
163
- subject.cpu_usage.should be_nil
194
+ expect(subject.cpu_usage).to be_nil
195
+ end
196
+ end
197
+
198
+ context 'when run command is nil' do
199
+ before do
200
+ subject.stub(:run).and_return(nil)
201
+ end
202
+
203
+ it 'should return nil' do
204
+ expect(subject.cpu_usage).to be_nil
164
205
  end
165
206
  end
166
207
  end
@@ -178,7 +219,7 @@ describe LXC::Container do
178
219
 
179
220
  it 'executes a command with container name' do
180
221
  stub_lxc("info", "-n", "app") { "info" }
181
- subject.info.should eq "info"
222
+ expect(subject.info).to eq "info"
182
223
  end
183
224
  end
184
- end
225
+ end
data/spec/lxc_spec.rb CHANGED
@@ -18,101 +18,112 @@ describe LXC do
18
18
  end
19
19
 
20
20
  it 'returns true if all files are found' do
21
- LXC.installed?.should be_true
21
+ expect(LXC.installed?).to be_true
22
22
  end
23
23
 
24
24
  it 'returns false on missing files' do
25
25
  FileUtils.rm("/tmp/lxc/lxc-version")
26
- LXC.installed?.should be_false
26
+ expect(LXC.installed?).to be_false
27
27
  end
28
28
  end
29
29
 
30
- it 'returns installed version' do
31
- stub_lxc('version') { fixture('lxc-version.txt') }
32
- LXC.version.should eq('0.7.5')
30
+ describe '.version' do
31
+ it 'returns installed LXC version' do
32
+ stub_lxc('version') { fixture('lxc-version.txt') }
33
+ expect(LXC.version).to eq('0.7.5')
34
+ end
33
35
  end
34
36
 
35
- it 'returns config hash with attributes' do
36
- stub_lxc('checkconfig') { fixture('lxc-checkconfig.txt') }
37
-
38
- info = LXC.config
39
- info.should be_a Hash
40
-
41
- info['namespaces'].should be_true
42
- info['utsname_namespace'].should be_true
43
- info['ipc_namespace'].should be_true
44
- info['pid_namespace'].should be_true
45
- info['user_namespace'].should be_true
46
- info['network_namespace'].should be_true
47
- info['cgroup'].should be_true
48
- info['cgroup_clone_children_flag'].should be_true
49
- info['cgroup_device'].should be_true
50
- info['cgroup_sched'].should be_true
51
- info['cgroup_cpu_account'].should be_true
52
- info['cgroup_memory_controller'].should be_true
53
- info['cgroup_cpuset'].should be_true
54
- info['veth_pair_device'].should be_true
55
- info['macvlan'].should be_true
56
- info['vlan'].should be_true
57
- info['file_capabilities'].should be_true
37
+ describe '.config' do
38
+ it 'returns config hash with attributes' do
39
+ stub_lxc('checkconfig') { fixture('lxc-checkconfig.txt') }
40
+
41
+ info = LXC.config
42
+ expect(info).to be_a(Hash)
43
+
44
+ expect(info['namespaces']).to be_true
45
+ expect(info['utsname_namespace']).to be_true
46
+ expect(info['ipc_namespace']).to be_true
47
+ expect(info['pid_namespace']).to be_true
48
+ expect(info['user_namespace']).to be_true
49
+ expect(info['network_namespace']).to be_true
50
+ expect(info['cgroup']).to be_true
51
+ expect(info['cgroup_clone_children_flag']).to be_true
52
+ expect(info['cgroup_device']).to be_true
53
+ expect(info['cgroup_sched']).to be_true
54
+ expect(info['cgroup_cpu_account']).to be_true
55
+ expect(info['cgroup_memory_controller']).to be_true
56
+ expect(info['cgroup_cpuset']).to be_true
57
+ expect(info['veth_pair_device']).to be_true
58
+ expect(info['macvlan']).to be_true
59
+ expect(info['vlan']).to be_true
60
+ expect(info['file_capabilities']).to be_true
61
+ end
58
62
  end
59
63
 
60
- it 'returns a single container' do
61
- c = LXC.container('foo')
62
- c.should be_a LXC::Container
63
- c.name.should eq('foo')
64
- end
64
+ describe '.container' do
65
+ it 'returns a container for name' do
66
+ c = LXC.container('foo')
65
67
 
66
- it 'returns all available containers' do
67
- stub_lxc('ls') { "vm0\nvm1\nvm0" }
68
- list = LXC.containers
69
- list.should be_an Array
70
- list.size.should eq(2)
71
- list.first.should be_a LXC::Container
72
- list.first.name.should eq('vm0')
68
+ expect(c).to be_a LXC::Container
69
+ expect(c.name).to eq('foo')
70
+ end
73
71
  end
74
72
 
75
- it 'returns filtered list of containers' do
76
- stub_lxc('ls') { "vm0\nvm1\nfoo\n"}
77
- list = LXC.containers("vm")
78
- list.size.should eq(2)
79
- end
73
+ describe '.containers' do
74
+ it 'returns all available containers' do
75
+ stub_lxc('ls') { "vm0\nvm1\nvm0" }
76
+
77
+ list = LXC.containers
78
+ expect(list).to be_an Array
79
+ expect(list.size).to eq(2)
80
+ expect(list.first).to be_a LXC::Container
81
+ expect(list.first.name).to eq('vm0')
82
+ end
80
83
 
81
- context 'sudo' do
82
- class Foo
83
- include LXC::Shell
84
+ context 'with argument' do
85
+ it 'returns containers filtered by name' do
86
+ stub_lxc('ls') { "vm0\nvm1\nfoo\n"}
87
+
88
+ list = LXC.containers("vm")
89
+ expect(list.size).to eq(2)
90
+ end
84
91
  end
92
+ end
85
93
 
86
- before do
87
- LXC.use_sudo = true
94
+ describe '.sudo' do
95
+ before { LXC.use_sudo = true }
96
+ let(:result) do
97
+ klass = Struct.new(:out)
98
+ klass.new(fixture('lxc-version.txt'))
88
99
  end
89
100
 
90
101
  it 'executes command using sudo' do
91
- LXC.use_sudo.should be_true
102
+ expect(LXC.use_sudo).to be_true
103
+
104
+ POSIX::Spawn::Child.stub(:new).
105
+ with('sudo lxc-version').
106
+ and_return(result)
92
107
 
93
- bar = Foo.new
94
- bar.should_receive(:'`').with('sudo lxc-version').and_return(fixture('lxc-version.txt'))
95
- bar.run('version').should_not be_empty
108
+ expect(LXC.run('version')).to eq 'lxc version: 0.7.5'
96
109
  end
97
110
  end
98
111
 
99
- context '.use_sudo' do
100
- class Bar
101
- include LXC::Shell
102
- end
112
+ describe '.use_sudo' do
113
+ class Bar ; include LXC::Shell ; end
103
114
 
104
115
  it 'should be true' do
105
116
  foo = Bar.new
106
- foo.use_sudo.should eq(true)
107
- LXC.use_sudo.should eq(true)
117
+ expect(foo.use_sudo).to be_true
118
+ expect(LXC.use_sudo).to be_true
108
119
  end
109
120
 
110
121
  it 'should be false' do
111
122
  LXC.use_sudo = false
112
123
  foo = Bar.new
113
124
 
114
- LXC.use_sudo.should eq(false)
115
- foo.use_sudo.should eq(false)
125
+ expect(LXC.use_sudo).to be_false
126
+ expect(foo.use_sudo).to be_false
116
127
  end
117
128
  end
118
- end
129
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  $:.unshift File.expand_path("../..", __FILE__)
2
2
 
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_filter "/.bundle/"
6
+ end
7
+
3
8
  require 'lib/lxc'
4
9
 
5
10
  def fixture_path(filename=nil)
@@ -13,5 +18,9 @@ end
13
18
 
14
19
  def stub_lxc(command, *args)
15
20
  output = yield
16
- LXC.should_receive(:run).with(command, *args).and_return(output)
21
+
22
+ LXC.should_receive(:run).
23
+ exactly(1).times.
24
+ with(command, *args).
25
+ and_return(output)
17
26
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe LXC::Status do
4
+ describe '.new' do
5
+ let(:status) { LXC::Status.new('RUNNING', '12345') }
6
+
7
+ it 'makes state downcase' do
8
+ expect(status.state).to eq 'running'
9
+ end
10
+
11
+ it 'converts given pid into integer' do
12
+ expect(status.pid).to be_an Integer
13
+ end
14
+ end
15
+
16
+ describe '#to_hash' do
17
+ let(:status) { LXC::Status.new('RUNNING', '12345') }
18
+
19
+ it 'returns a hash representation' do
20
+ result = status.to_hash
21
+ expect(result).to be_a Hash
22
+ expect(result).to include 'state', 'pid'
23
+ end
24
+ end
25
+
26
+ describe '#to_s' do
27
+ let(:status) { LXC::Status.new('RUNNING', '12345') }
28
+
29
+ it 'returns a string representation' do
30
+ expect(status.to_s).to eq 'state=running pid=12345'
31
+ end
32
+ end
33
+ end
metadata CHANGED
@@ -1,64 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lxc-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
5
- prerelease:
4
+ version: 0.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Dan Sosedoff
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-23 00:00:00.000000000 Z
11
+ date: 2013-09-22 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: posix-spawn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.6
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.6
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: rake
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ! '>='
31
+ - - '>='
20
32
  - !ruby/object:Gem::Version
21
33
  version: '0'
22
34
  type: :development
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ! '>='
38
+ - - '>='
28
39
  - !ruby/object:Gem::Version
29
40
  version: '0'
30
41
  - !ruby/object:Gem::Dependency
31
42
  name: rspec
32
43
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
44
  requirements:
35
45
  - - ~>
36
46
  - !ruby/object:Gem::Version
37
- version: '2.6'
47
+ version: '2.13'
38
48
  type: :development
39
49
  prerelease: false
40
50
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
51
  requirements:
43
52
  - - ~>
44
53
  - !ruby/object:Gem::Version
45
- version: '2.6'
54
+ version: '2.13'
46
55
  - !ruby/object:Gem::Dependency
47
56
  name: simplecov
48
57
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
58
  requirements:
51
59
  - - ~>
52
60
  - !ruby/object:Gem::Version
53
- version: '0.4'
61
+ version: '0.7'
54
62
  type: :development
55
63
  prerelease: false
56
64
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
65
  requirements:
59
66
  - - ~>
60
67
  - !ruby/object:Gem::Version
61
- version: '0.4'
68
+ version: '0.7'
62
69
  description: Ruby wrapper to manage LXC (Linux Containers).
63
70
  email:
64
71
  - dan.sosedoff@gmail.com
@@ -72,14 +79,15 @@ files:
72
79
  - Gemfile
73
80
  - README.md
74
81
  - Rakefile
82
+ - Vagrantfile
75
83
  - lib/lxc.rb
76
84
  - lib/lxc/configuration.rb
77
85
  - lib/lxc/configuration_options.rb
78
86
  - lib/lxc/container.rb
79
- - lib/lxc/errors.rb
80
87
  - lib/lxc/shell.rb
88
+ - lib/lxc/status.rb
81
89
  - lib/lxc/version.rb
82
- - lxc.gemspec
90
+ - lxc-ruby.gemspec
83
91
  - spec/configuration_spec.rb
84
92
  - spec/container_spec.rb
85
93
  - spec/fixtures/configuration.txt
@@ -90,35 +98,29 @@ files:
90
98
  - spec/fixtures/lxc-version.txt
91
99
  - spec/lxc_spec.rb
92
100
  - spec/spec_helper.rb
101
+ - spec/status_spec.rb
93
102
  homepage: http://github.com/sosedoff/lxc-ruby
94
103
  licenses: []
104
+ metadata: {}
95
105
  post_install_message:
96
106
  rdoc_options: []
97
107
  require_paths:
98
108
  - lib
99
109
  required_ruby_version: !ruby/object:Gem::Requirement
100
- none: false
101
110
  requirements:
102
- - - ! '>='
111
+ - - '>='
103
112
  - !ruby/object:Gem::Version
104
113
  version: '0'
105
- segments:
106
- - 0
107
- hash: 2803095474129589431
108
114
  required_rubygems_version: !ruby/object:Gem::Requirement
109
- none: false
110
115
  requirements:
111
- - - ! '>='
116
+ - - '>='
112
117
  - !ruby/object:Gem::Version
113
118
  version: '0'
114
- segments:
115
- - 0
116
- hash: 2803095474129589431
117
119
  requirements: []
118
120
  rubyforge_project:
119
- rubygems_version: 1.8.25
121
+ rubygems_version: 2.0.5
120
122
  signing_key:
121
- specification_version: 3
123
+ specification_version: 4
122
124
  summary: Ruby wrapper to LXC
123
125
  test_files:
124
126
  - spec/configuration_spec.rb
@@ -131,3 +133,5 @@ test_files:
131
133
  - spec/fixtures/lxc-version.txt
132
134
  - spec/lxc_spec.rb
133
135
  - spec/spec_helper.rb
136
+ - spec/status_spec.rb
137
+ has_rdoc:
data/lib/lxc/errors.rb DELETED
@@ -1,5 +0,0 @@
1
- module LXC
2
- class Error < StandardError ; end
3
- class ContainerError < Error ; end
4
- class ConfigurationError < Error ; end
5
- end