lxc_ssh 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b1299d54895480465b61dca5ec7b400375465399
4
+ data.tar.gz: 4694ed8006155c5d7d9bc7aa5d6f360c5847a8a1
5
+ SHA512:
6
+ metadata.gz: db2af76937ab694f8352c0a46f9ec049d0fd6490f4b856e3087f33a118a8d48615cf70d750a1bd1331f291db7984e419487dbf7bed1d7cf2ed255612ebafbc38
7
+ data.tar.gz: 22c78717be1114db31aef462339dcf3f709d5d09030a51cd95ba7945d304a7448dcd246f81decc52856fcc327840d38593d1268054b454f8feb5308a971b9bbf
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lxc_ssh.gemspec
4
+ gemspec
@@ -0,0 +1,127 @@
1
+ # lxc_ssh
2
+
3
+ lxc_ssh is a ruby gem for managing lxc host systems over an ssh connection.
4
+ Supports LXC version 1.0 and higher. Depends on net-ssh (https://github.com/net-ssh/net-ssh).
5
+
6
+
7
+ ## Installation
8
+
9
+ !! NOT AT RUBYGEMS.ORG YET !!
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'lxc_ssh'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install lxc_ssh
24
+
25
+ ## Usage
26
+
27
+ First create a connection to your system over ssh (currently only the ssh default port is supported)
28
+ and authenticate as a privileged user (lxc is installed to /usr in this case):
29
+
30
+ ```ruby
31
+ con = LxcSsh::Connection.new
32
+ con.connect('my.cool.host', 'root', nil, '/usr')
33
+ ```
34
+
35
+ If no exception occured, you're ready to go.
36
+
37
+ #### Get containers
38
+
39
+ ```ruby
40
+ containers = con.manager.containers
41
+ ```
42
+
43
+
44
+ #### Get specific container information
45
+
46
+ ```ruby
47
+ container = con.manager.container 'my-fancy-container-name'
48
+ ```
49
+
50
+ Result:
51
+
52
+ ```ruby
53
+ #<LxcSsh::Container:0x00000000c7ea48 @name="my-fancy-container-name",
54
+ @pid="1234",
55
+ @state="RUNNING",
56
+ @memory_usage=0,
57
+ @memory_limit=0,
58
+ @cpu_shares=1024,
59
+ @cpu_usage="23994168167209",
60
+ @ip="192.168.0.2">
61
+ ```
62
+
63
+ #### Get container config
64
+
65
+ ```ruby
66
+ config = con.manager.container_config 'my-fancy-container-name'
67
+ puts config['lxc.network.veth.pair']
68
+ ```
69
+
70
+
71
+ #### Update config items
72
+
73
+ ```ruby
74
+ config = con.manager.container_config 'my-fancy-container-name'
75
+ config['lxc.network.veth.pair'] = 'none'
76
+ con.manager.write_config 'my-fancy-container-name', config
77
+ ```
78
+
79
+ ### Create container
80
+
81
+ ```ruby
82
+ con.manager.create_container 'testcontainer', 'gentoo'
83
+ ```
84
+
85
+ #### Start container
86
+
87
+ ```ruby
88
+ con.manager.start_container 'testcontainer'
89
+ ```
90
+
91
+ #### Stop container
92
+
93
+ ```ruby
94
+ con.manager.stop_container 'testcontainer'
95
+ ```
96
+
97
+ #### Destroy container
98
+
99
+ ```ruby
100
+ con.manager.destroy_container 'testcontainer'
101
+ ```
102
+
103
+ #### Create container
104
+
105
+ ```ruby
106
+ con.manager.create_container 'testcontainer', 'gentoo'
107
+ ```
108
+
109
+ #### Get templates
110
+
111
+ ```ruby
112
+ con.manager.template_names
113
+ ```
114
+
115
+ #### Get template help text
116
+
117
+ ```ruby
118
+ puts con.manager.template_help 'archlinux'
119
+ ```
120
+
121
+ ## Contributing
122
+
123
+ 1. Fork it ( https://github.com/dprandzioch/lxc_ssh/fork )
124
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
125
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
126
+ 4. Push to the branch (`git push origin my-new-feature`)
127
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,12 @@
1
+ require 'lxc_ssh/version.rb'
2
+ require "lxc_ssh/connection.rb"
3
+ require "lxc_ssh/container.rb"
4
+ require "lxc_ssh/container_info.rb"
5
+ require "lxc_ssh/container_config.rb"
6
+ require "lxc_ssh/manager.rb"
7
+ require "lxc_ssh/manager/specific_manager10.rb"
8
+
9
+ module LxcSsh
10
+ LIBNAME = 'lxc_ssh'
11
+ LIBDIR = File.expand_path("../#{LIBNAME}", __FILE__)
12
+ end
@@ -0,0 +1,54 @@
1
+ require 'net/ssh'
2
+
3
+ module LxcSsh
4
+ class Connection
5
+
6
+ attr_reader :manager
7
+
8
+ # Initializes the connection
9
+ def initialize
10
+ @session = nil
11
+ @manager = nil
12
+ @lxc_version = nil
13
+ @lxc_path = nil
14
+ end
15
+
16
+ # Connects to the host system via ssh and authenticates by
17
+ # either public key or password authentication
18
+ #
19
+ # @param hostname [String] SSH Hostname
20
+ # @param username [String] SSH Username
21
+ # @param password [String] SSH Password
22
+ # @param lxc_path [String] LXC installation path (default: /usr)
23
+ def connect(hostname, username, password, lxc_path = '/usr')
24
+ if @password.nil?
25
+ # pubkey
26
+ @session = Net::SSH.start(hostname, username)
27
+ else
28
+ @session = Net::SSH.start(hostname, username, password)
29
+ end
30
+
31
+ @lxc_path = lxc_path
32
+ @lxc_version = obtain_version
33
+ @manager = self.init_manager
34
+ end
35
+
36
+ # Obtains the version number of the lxc installation
37
+ #
38
+ # @return string
39
+ def obtain_version
40
+ output = @session.exec! @lxc_path + "/bin/lxc-start --version"
41
+
42
+ output.strip
43
+ end
44
+
45
+ # Initializes the lxc manager object
46
+ def init_manager
47
+ if @lxc_version.nil?
48
+ raise 'no lxc version set, please detect and set the lxc version using detect_lxc_version'
49
+ end
50
+
51
+ @manager = LxcSsh::Manager.new(@session, @lxc_version, @lxc_path)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,35 @@
1
+ module LxcSsh
2
+ class Container
3
+
4
+ attr_accessor :name,
5
+ :state,
6
+ :pid,
7
+ :ip,
8
+ :memory_usage,
9
+ :memory_limit,
10
+ :cpu_shares,
11
+ :cpu_usage
12
+
13
+ # Checks if the container is running
14
+ #
15
+ # @return [Boolean]
16
+ def running?
17
+ @state == 'RUNNING'
18
+ end
19
+
20
+ # Checks if the container is frozen
21
+ #
22
+ # @return [Boolean]
23
+ def frozen?
24
+ @state == 'FROZEN'
25
+ end
26
+
27
+ # Checks if the container is stopped
28
+ #
29
+ # @return [Boolean]
30
+ def stopped?
31
+ !running? && !frozen?
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,85 @@
1
+ module LxcSsh
2
+ class ContainerConfig
3
+
4
+ # Loads the configuration object with the config files' content
5
+ #
6
+ # @param data [String] config file contents
7
+ def initialize(data)
8
+ @content = parse(data)
9
+ end
10
+
11
+ # Loads the configuration object with the config files' content
12
+ #
13
+ # @param data [String] config file contents
14
+ # @return [Hash]
15
+ def parse(data)
16
+ items = {}
17
+
18
+ # only lines starting with 'lxc.'
19
+ lines = data.lines.map(&:strip).select do |line|
20
+ line.start_with?('lxc.')
21
+ end
22
+
23
+ # process lines
24
+ lines.each do |line|
25
+ key, value = line.split('=').map(&:strip)
26
+
27
+ if items.key?(key) == false
28
+ items[key] = []
29
+ end
30
+
31
+ items[key] << value
32
+ end
33
+
34
+ items.each_pair do |key, val|
35
+ if val.length == 1
36
+ items[key] = val.first
37
+ end
38
+ end
39
+
40
+ items
41
+ end
42
+
43
+ # Array-style accessor (getter)
44
+ #
45
+ # @param key [String] key of the hash
46
+ # @return [Object]
47
+ def [](key)
48
+ if key.kind_of?(String) == false
49
+ raise ArgumentError, 'key must be a string'
50
+ end
51
+
52
+ @content[key]
53
+ end
54
+
55
+ # Array-style accessor (setter)
56
+ #
57
+ # @param key [String] key of the hash
58
+ # @param val [Object] value to set
59
+ def []=(key, val)
60
+ @content[key] = val
61
+ end
62
+
63
+ # Generates a config string from the current object context
64
+ #
65
+ # @return [Hash]
66
+ def config_contents
67
+ lines = []
68
+
69
+ @content.each_pair do |key, value|
70
+ if value.class == Array
71
+ # multiple values assigned for a single key, order is important!
72
+ lines << value.map do |val|
73
+ key + ' = ' + val
74
+ end
75
+ else
76
+ line = key + ' = ' + value
77
+ lines << line
78
+ end
79
+ end
80
+
81
+ lines.join('\n')
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,7 @@
1
+ module LxcSsh
2
+ class ContainerInfo
3
+
4
+ attr_accessor :pid, :state
5
+
6
+ end
7
+ end
@@ -0,0 +1,114 @@
1
+ module LxcSsh
2
+ class Manager
3
+
4
+ # Initializes the lxc manager by creating an instance of the version-specific
5
+ # lxc manager for the detected version
6
+ #
7
+ # @param session [SSH::Connection::Session] ssh session
8
+ # @param lxc_version [String] lxc version string
9
+ # @param lxc_path [String] lxc installation path
10
+ def initialize(session, lxc_version, lxc_path)
11
+ @lxc_path = lxc_path
12
+ @specific_manager = nil
13
+
14
+ # LXC APIs mac change in the future, therefore a version specific adapter
15
+ # must be used
16
+ if Gem::Version.new(lxc_version) >= Gem::Version.new('1.0')
17
+ @specific_manager = LxcSsh::SpecificManager10.new(session, lxc_path)
18
+ # other version checks go here
19
+ else
20
+ raise 'lxc versions < 1.0 are not supported'
21
+ end
22
+ end
23
+
24
+ # Returns an array of lxc containers
25
+ #
26
+ # @return [Array]
27
+ def container_names
28
+ @specific_manager.container_names
29
+ end
30
+
31
+ # Returns an array containing objects with container metadata
32
+ #
33
+ # @return [Array]
34
+ def containers
35
+ @specific_manager.containers
36
+ end
37
+
38
+ # Returns a LxcSsh::ContainerConfig object for the container name
39
+ #
40
+ # @return [LxcSsh::ContainerConfig]
41
+ def container_config(name)
42
+ @specific_manager.container_config name
43
+ end
44
+
45
+ # Returns an LxcSsh::Container object for the given container name
46
+ #
47
+ # @return [LxcSsh::Container]
48
+ def container(name)
49
+ @specific_manager.get_container_obj name
50
+ end
51
+
52
+ # Writes the config file contents back to the container config
53
+ #
54
+ # @param container_name [String] the container to use
55
+ # @param config [String] configuration string to save
56
+ def write_config(name, config)
57
+ @specific_manager.write_config name, config
58
+ end
59
+
60
+ # Returns an array containing all templates
61
+ #
62
+ # @todo check path
63
+ #
64
+ # @return [Array]
65
+ def template_names
66
+ @specific_manager.template_names
67
+ end
68
+
69
+ # Returns the template help text for a given template name
70
+ #
71
+ # @param template_name [String] template to use (without 'lxc-'-prefix)
72
+ # @return [String]
73
+ def template_help(name)
74
+ @specific_manager.template_help name
75
+ end
76
+
77
+ # Creates a container with the default configuration and additional template options
78
+ # and returns the output as a string
79
+ #
80
+ # @param name [String] container name
81
+ # @param template [String] template name (without 'lxc-'-prefix)
82
+ # @param template_options [String] additional template options
83
+ #
84
+ # @return [String]
85
+ def create_container(name, template, template_options = nil)
86
+ @specific_manager.create_container name, template, template_options
87
+ end
88
+
89
+ # Starts a container with the given name
90
+ #
91
+ # @param name [String] container name
92
+ # @return [Boolean]
93
+ def start_container(name)
94
+ @specific_manager.start_container name
95
+ end
96
+
97
+ # Stops a container
98
+ #
99
+ # @param name [String] container name
100
+ # @return [Boolean]
101
+ def stop_container(name)
102
+ @specific_manager.stop_container name
103
+ end
104
+
105
+ # Destroys a container with the given name
106
+ #
107
+ # @param name [String] container name
108
+ # @return [Boolean]
109
+ def destroy_container(name)
110
+ @specific_manager.destroy_container name
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,244 @@
1
+ module LxcSsh
2
+ class SpecificManager10
3
+
4
+ # Initializes the manager
5
+ #
6
+ # @param session [SSH::Connection::Session] ssh session
7
+ # @param lxc_path [String] lxc installation path
8
+ def initialize(session, lxc_path)
9
+ @session = session
10
+ @lxc_path = lxc_path
11
+ end
12
+
13
+ # Returns an array of lxc containers
14
+ #
15
+ # @return [Array]
16
+ def container_names
17
+ result = @session.exec! @lxc_path + '/bin/lxc-ls'
18
+
19
+ result.lines.map(&:strip).uniq
20
+ end
21
+
22
+ # Returns an array containing objects with container metadata
23
+ #
24
+ # @return [Array]
25
+ def containers
26
+ containers = []
27
+
28
+ container_names.each do |name|
29
+ containers << get_container_obj(name)
30
+ end
31
+
32
+ containers
33
+ end
34
+
35
+ # Returns an LxcSsh::Container object for the given container name
36
+ #
37
+ # @return [LxcSsh::Container]
38
+ def get_container_obj(name)
39
+ container = Container.new
40
+ container.name = name
41
+
42
+ info = info(name)
43
+ container.pid = info.pid
44
+ container.state = info.state
45
+
46
+ container.memory_usage = run_cmd("lxc-cgroup", name, "memory.usage_in_bytes").strip.to_i
47
+ container.memory_limit = run_cmd("lxc-cgroup", name, "memory.limit_in_bytes").strip.to_i
48
+ container.cpu_shares = run_cmd("lxc-cgroup", name, "cpu.shares").strip.to_i
49
+ container.cpu_usage = cpu_usage name
50
+ container.ip = ip_addr name
51
+
52
+ container
53
+ end
54
+
55
+ # Returns a LxcSsh::ContainerConfig object for the container name
56
+ #
57
+ # @return [LxcSsh::ContainerConfig]
58
+ def container_config(name)
59
+ contents = config_contents name
60
+
61
+ ContainerConfig.new contents
62
+ end
63
+
64
+ # Writes the config file contents back to the container config
65
+ #
66
+ # @todo verify function
67
+ # @todo escape contents variable
68
+ #
69
+ # @param container_name [String] the container to use
70
+ # @param config [String] configuration string to save
71
+ def write_config(container_name, config)
72
+ if !config.kind_of?(ContainerConfig)
73
+ raise ArgumentError, "config must be a instance of ContainerConfig"
74
+ end
75
+
76
+ contents = config.config_contents
77
+
78
+ @session.exec! "echo -e '" + contents + "' > " + config_path(container_name)
79
+ end
80
+
81
+ # Returns an array containing all templates
82
+ #
83
+ # @todo check path
84
+ #
85
+ # @return [Array]
86
+ def template_names
87
+ output = @session.exec! "ls -1 " + @lxc_path + "/share/lxc/templates/"
88
+ output.gsub! 'lxc-', ''
89
+
90
+ result = output.lines.map(&:strip).uniq
91
+
92
+ result
93
+ end
94
+
95
+ # Returns the template help text for a given template name
96
+ #
97
+ # @param template_name [String] template to use (without 'lxc-'-prefix)
98
+ # @return [String]
99
+ def template_help(template_name)
100
+ output = run_cmd("lxc-create", nil, "-t lxc-#{template_name} -h")
101
+
102
+ output
103
+ end
104
+
105
+ # Creates a container with the default configuration and additional template options
106
+ # and returns the output as a string
107
+ #
108
+ # @param name [String] container name
109
+ # @param template [String] template name (without 'lxc-'-prefix)
110
+ # @param template_options [String] additional template options
111
+ #
112
+ # @return [String]
113
+ def create_container(name, template, template_options = nil)
114
+ args = "-t #{template}"
115
+
116
+ if template_options.nil? == false
117
+ args += " -- #{template_options}"
118
+ end
119
+
120
+ output = run_cmd("lxc-create", name, args)
121
+
122
+ output
123
+ end
124
+
125
+ # Starts a container with the given name
126
+ #
127
+ # @param name [String] container name
128
+ # @return [Boolean]
129
+ def start_container(name)
130
+ output = run_cmd("lxc-start", name, '-d')
131
+
132
+ output.nil?
133
+ end
134
+
135
+ # Stops a container
136
+ #
137
+ # @param name [String] container name
138
+ # @return [Boolean]
139
+ def stop_container(name)
140
+ output = run_cmd("lxc-stop", name)
141
+
142
+ output.nil?
143
+ end
144
+
145
+ # Destroys a container with the given name
146
+ #
147
+ # @param name [String] container name
148
+ # @return [Boolean]
149
+ def destroy_container(name)
150
+ output = run_cmd("lxc-destroy", name)
151
+
152
+ output.nil?
153
+ end
154
+
155
+ protected
156
+ # Executes a lxc command
157
+ #
158
+ # @param lxc_binary [String] lxc binary name
159
+ # @param container_name [String] container name (if needed, otherwise nil)
160
+ # @param params [String] additional parameter string to append
161
+ # @return [String]
162
+ def run_cmd(xlc_binary, container_name = nil, params = nil)
163
+ cmd = @lxc_path + '/bin/' + xlc_binary
164
+
165
+ if container_name.nil? == false
166
+ cmd += ' -n ' + container_name
167
+ end
168
+
169
+ cmd += ' '
170
+
171
+ if params.nil? == false
172
+ cmd += params
173
+ end
174
+
175
+ @session.exec!(cmd)
176
+ end
177
+
178
+ # Loads the lxc container path using lxc-config
179
+ #
180
+ # @return [String]
181
+ def container_path(name)
182
+ output = run_cmd("lxc-config", nil, "lxc.lxcpath").strip
183
+
184
+ "#{output}/#{name}"
185
+ end
186
+
187
+ # Returns the config file path for a given container
188
+ #
189
+ # @return [String]
190
+ def config_path(name)
191
+ container_path(name) + '/config'
192
+ end
193
+
194
+ # Obtains the contents of a container config file
195
+ #
196
+ # @return [String]
197
+ def config_contents(name)
198
+ @session.exec! 'cat ' + config_path(name)
199
+ end
200
+
201
+ # Returns the containers current cpu usage
202
+ #
203
+ # @return [String]
204
+ def cpu_usage(name)
205
+ result = run_cmd("lxc-cgroup", name, "cpuacct.usage").strip
206
+
207
+ result
208
+ end
209
+
210
+ # Returns the containers ip address
211
+ #
212
+ # @todo what happens if multiple ip addresses are configured
213
+ #
214
+ # @param name [String] container name
215
+ # @return [String]
216
+ def ip_addr(name)
217
+ output = run_cmd("lxc-info", name, "-i")
218
+
219
+ if output.nil?
220
+ return nil
221
+ end
222
+
223
+ result = output.scan(/^IP:\s+([0-9.]+)$/).flatten
224
+
225
+ result.first.nil? || result.first.empty? ? nil : result.first
226
+ end
227
+
228
+ # Returns a LxcSsh::ContainerInfo object containing the most essential information.
229
+ #
230
+ # @param name [String] container name
231
+ # @return [LxcSsh::ContainerInfo]
232
+ def info(name)
233
+ output = run_cmd("lxc-info", name)
234
+ result = output.scan(/^State:\s+([\w]+)|PID:\s+(-?[\d]+)$/).flatten
235
+
236
+ ci = ContainerInfo.new
237
+ ci.state = result.first
238
+ ci.pid = result.last
239
+
240
+ ci
241
+ end
242
+
243
+ end
244
+ end
@@ -0,0 +1,3 @@
1
+ module LxcSsh
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lxc_ssh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Prandzioch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-ssh
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.9'
55
+ description: lxc_ssh is a ruby gem for managing lxc host systems over an ssh connection.
56
+ Supports LXC version 1.0 and higher. Depends on net-ssh.
57
+ email:
58
+ - david@backport.net
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - Gemfile
64
+ - README.md
65
+ - Rakefile
66
+ - lib/lxc_ssh.rb
67
+ - lib/lxc_ssh/connection.rb
68
+ - lib/lxc_ssh/container.rb
69
+ - lib/lxc_ssh/container_config.rb
70
+ - lib/lxc_ssh/container_info.rb
71
+ - lib/lxc_ssh/manager.rb
72
+ - lib/lxc_ssh/manager/specific_manager10.rb
73
+ - lib/lxc_ssh/version.rb
74
+ homepage: https://github.com/dprandzioch/lxc_ssh
75
+ licenses:
76
+ - GPL-2.0
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.2.2
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: LXC CLI wrapper using SSH
98
+ test_files: []