lxc-ruby 0.2.3 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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