wf_node_api 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +66 -0
- data/LICENSE +340 -0
- data/Makefile +19 -0
- data/README.md +78 -0
- data/Rakefile +2 -0
- data/Vagrantfile +102 -0
- data/_docs/api/Api/NodeApi.html +123 -0
- data/_docs/api/Api.html +149 -0
- data/_docs/api/Config/Check.html +331 -0
- data/_docs/api/Config.html +115 -0
- data/_docs/api/ConfigCheck.html +365 -0
- data/_docs/api/ContainerManager.html +1632 -0
- data/_docs/api/ContainerManagerAdapter/Lxc.html +1352 -0
- data/_docs/api/ContainerManagerAdapter/Vserver.html +1358 -0
- data/_docs/api/ContainerManagerAdapter.html +151 -0
- data/_docs/api/Error/NotFound.html +134 -0
- data/_docs/api/Error.html +115 -0
- data/_docs/api/NotFoundError.html +157 -0
- data/_docs/api/OS.html +234 -0
- data/_docs/api/ResourceManager.html +322 -0
- data/_docs/api/ResourceManagerAdapter/Linux.html +326 -0
- data/_docs/api/ResourceManagerAdapter.html +149 -0
- data/_docs/api/WfNodeApi.html +163 -0
- data/_docs/api/_index.html +239 -0
- data/_docs/api/class_list.html +58 -0
- data/_docs/api/css/common.css +1 -0
- data/_docs/api/css/full_list.css +57 -0
- data/_docs/api/css/style.css +339 -0
- data/_docs/api/file.README.html +146 -0
- data/_docs/api/file_list.html +60 -0
- data/_docs/api/frames.html +26 -0
- data/_docs/api/index.html +146 -0
- data/_docs/api/js/app.js +219 -0
- data/_docs/api/js/full_list.js +181 -0
- data/_docs/api/js/jquery.js +4 -0
- data/_docs/api/method_list.html +273 -0
- data/_docs/api/top-level-namespace.html +244 -0
- data/_docs/rest/api_data.js +1 -0
- data/_docs/rest/api_data.json +1 -0
- data/_docs/rest/api_project.js +1 -0
- data/_docs/rest/api_project.json +1 -0
- data/_docs/rest/css/style.css +538 -0
- data/_docs/rest/header.md +3 -0
- data/_docs/rest/img/favicon.ico +0 -0
- data/_docs/rest/img/glyphicons-halflings-white.png +0 -0
- data/_docs/rest/img/glyphicons-halflings.png +0 -0
- data/_docs/rest/index.html +658 -0
- data/_docs/rest/locales/de.js +25 -0
- data/_docs/rest/locales/fr.js +25 -0
- data/_docs/rest/locales/locale.js +43 -0
- data/_docs/rest/locales/nl.js +25 -0
- data/_docs/rest/locales/pl.js +25 -0
- data/_docs/rest/locales/pt_br.js +25 -0
- data/_docs/rest/locales/ru.js +25 -0
- data/_docs/rest/locales/zh.js +25 -0
- data/_docs/rest/main.js +691 -0
- data/_docs/rest/utils/handlebars_helper.js +327 -0
- data/_docs/rest/utils/send_sample_request.js +158 -0
- data/_docs/rest/vendor/bootstrap-responsive.min.css +9 -0
- data/_docs/rest/vendor/bootstrap.min.css +9 -0
- data/_docs/rest/vendor/bootstrap.min.js +6 -0
- data/_docs/rest/vendor/diff_match_patch.min.js +49 -0
- data/_docs/rest/vendor/handlebars.min.js +28 -0
- data/_docs/rest/vendor/jquery.min.js +4 -0
- data/_docs/rest/vendor/lodash.min.js +61 -0
- data/_docs/rest/vendor/path-to-regexp/LICENSE +21 -0
- data/_docs/rest/vendor/path-to-regexp/index.js +205 -0
- data/_docs/rest/vendor/polyfill.js +100 -0
- data/_docs/rest/vendor/prettify/lang-apollo.js +2 -0
- data/_docs/rest/vendor/prettify/lang-basic.js +3 -0
- data/_docs/rest/vendor/prettify/lang-clj.js +18 -0
- data/_docs/rest/vendor/prettify/lang-css.js +2 -0
- data/_docs/rest/vendor/prettify/lang-dart.js +3 -0
- data/_docs/rest/vendor/prettify/lang-erlang.js +2 -0
- data/_docs/rest/vendor/prettify/lang-go.js +1 -0
- data/_docs/rest/vendor/prettify/lang-hs.js +2 -0
- data/_docs/rest/vendor/prettify/lang-lisp.js +3 -0
- data/_docs/rest/vendor/prettify/lang-llvm.js +1 -0
- data/_docs/rest/vendor/prettify/lang-lua.js +2 -0
- data/_docs/rest/vendor/prettify/lang-matlab.js +6 -0
- data/_docs/rest/vendor/prettify/lang-ml.js +2 -0
- data/_docs/rest/vendor/prettify/lang-mumps.js +2 -0
- data/_docs/rest/vendor/prettify/lang-n.js +4 -0
- data/_docs/rest/vendor/prettify/lang-pascal.js +3 -0
- data/_docs/rest/vendor/prettify/lang-proto.js +1 -0
- data/_docs/rest/vendor/prettify/lang-r.js +2 -0
- data/_docs/rest/vendor/prettify/lang-rd.js +1 -0
- data/_docs/rest/vendor/prettify/lang-scala.js +2 -0
- data/_docs/rest/vendor/prettify/lang-sql.js +2 -0
- data/_docs/rest/vendor/prettify/lang-tcl.js +3 -0
- data/_docs/rest/vendor/prettify/lang-tex.js +1 -0
- data/_docs/rest/vendor/prettify/lang-vb.js +2 -0
- data/_docs/rest/vendor/prettify/lang-vhdl.js +3 -0
- data/_docs/rest/vendor/prettify/lang-wiki.js +2 -0
- data/_docs/rest/vendor/prettify/lang-xq.js +3 -0
- data/_docs/rest/vendor/prettify/lang-yaml.js +2 -0
- data/_docs/rest/vendor/prettify/prettify.css +1 -0
- data/_docs/rest/vendor/prettify/prettify.js +30 -0
- data/_docs/rest/vendor/prettify/run_prettify.js +34 -0
- data/_docs/rest/vendor/prettify.css +101 -0
- data/_docs/rest/vendor/require.min.js +36 -0
- data/apidoc.json +23 -0
- data/bin/wf_node_api +80 -0
- data/lib/wf_node_api/api/node_api.rb +360 -0
- data/lib/wf_node_api/config/config_template.erb +50 -0
- data/lib/wf_node_api/config_check.rb +50 -0
- data/lib/wf_node_api/container_manager.rb +286 -0
- data/lib/wf_node_api/container_manager_adapter/lxc.rb +431 -0
- data/lib/wf_node_api/container_manager_adapter/vserver.rb +448 -0
- data/lib/wf_node_api/error/not_found.rb +27 -0
- data/lib/wf_node_api/os.rb +32 -0
- data/lib/wf_node_api/resource_manager.rb +49 -0
- data/lib/wf_node_api/resource_manager_adapter/linux.rb +53 -0
- data/lib/wf_node_api/translations.rb +38 -0
- data/lib/wf_node_api/version.rb +28 -0
- data/lib/wf_node_api.rb +57 -0
- data/manifests/files/dhozac-vserver.repo +4 -0
- data/wf-node-api.gemspec +53 -0
- metadata +221 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
=begin
|
2
|
+
__ ___ _ _ _____ ____ __ __
|
3
|
+
\ \ / / |__ (_) |_ ___| ___| _ ___ ___ / ___| \/ |
|
4
|
+
\ \ /\ / /| '_ \| | __/ _ \ |_ | | | / __|/ _ \ | | |\/| |
|
5
|
+
\ V V / | | | | | || __/ _|| |_| \__ \ __/ |___| | | |
|
6
|
+
\_/\_/ |_| |_|_|\__\___|_| \__,_|___/\___|\____|_| |_|
|
7
|
+
Container Manager
|
8
|
+
|
9
|
+
Copyright (C) 2015 David Prandzioch <kontakt@davidprandzioch.de>
|
10
|
+
|
11
|
+
This program is free software; you can redistribute it and/or
|
12
|
+
modify it under the terms of the GNU General Public License
|
13
|
+
as published by the Free Software Foundation; either version 2
|
14
|
+
of the License, or (at your option) any later version.
|
15
|
+
|
16
|
+
This program is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU General Public License
|
22
|
+
along with this program; if not, write to the Free Software
|
23
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
24
|
+
=end
|
25
|
+
|
26
|
+
module ConfigCheck
|
27
|
+
|
28
|
+
# Runs the configuration check
|
29
|
+
#
|
30
|
+
# @raise [RuntimeError]
|
31
|
+
def self.run
|
32
|
+
if self.valid_container_type?($container_type) == false
|
33
|
+
raise RuntimeError, 'container_type is invalid'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Checks if the submitted container type is registered and valid
|
38
|
+
#
|
39
|
+
# @param container_type [String] The container type to check
|
40
|
+
#
|
41
|
+
# @raise [ArgumentError] If the container type is not set
|
42
|
+
#
|
43
|
+
# @return [Boolean] Result of the validation
|
44
|
+
def self.valid_container_type?(container_type)
|
45
|
+
raise ArgumentError 'container_type not set' if container_type.nil?
|
46
|
+
valid_types = ['lxc', 'vserver']
|
47
|
+
|
48
|
+
valid_types.include?(container_type)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
=begin
|
2
|
+
__ ___ _ _ _____ ____ __ __
|
3
|
+
\ \ / / |__ (_) |_ ___| ___| _ ___ ___ / ___| \/ |
|
4
|
+
\ \ /\ / /| '_ \| | __/ _ \ |_ | | | / __|/ _ \ | | |\/| |
|
5
|
+
\ V V / | | | | | || __/ _|| |_| \__ \ __/ |___| | | |
|
6
|
+
\_/\_/ |_| |_|_|\__\___|_| \__,_|___/\___|\____|_| |_|
|
7
|
+
Container Manager
|
8
|
+
|
9
|
+
Copyright (C) 2015 David Prandzioch <kontakt@davidprandzioch.de>
|
10
|
+
|
11
|
+
This program is free software; you can redistribute it and/or
|
12
|
+
modify it under the terms of the GNU General Public License
|
13
|
+
as published by the Free Software Foundation; either version 2
|
14
|
+
of the License, or (at your option) any later version.
|
15
|
+
|
16
|
+
This program is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU General Public License
|
22
|
+
along with this program; if not, write to the Free Software
|
23
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
24
|
+
=end
|
25
|
+
|
26
|
+
# Manager for containers, meta class
|
27
|
+
class ContainerManager
|
28
|
+
# Checks the installation with a simple test procedure
|
29
|
+
#
|
30
|
+
# @raise [StandardError]
|
31
|
+
def check
|
32
|
+
name = (0...8).map { (65 + rand(26)).chr }.join
|
33
|
+
puts "==> Random name for the container: #{name}"
|
34
|
+
|
35
|
+
# containers should return an array
|
36
|
+
puts "==> Listing containers"
|
37
|
+
res = containers()
|
38
|
+
#puts res.inspect
|
39
|
+
|
40
|
+
raise 'containers() failed' unless res.is_a?(Array)
|
41
|
+
puts "==> PASS"
|
42
|
+
|
43
|
+
# container should not work
|
44
|
+
puts "==> Getting container info on non-existant container (should not work)"
|
45
|
+
|
46
|
+
begin
|
47
|
+
res = container(name)
|
48
|
+
raise 'container() failed'
|
49
|
+
rescue => e
|
50
|
+
puts "==> PASS"
|
51
|
+
end
|
52
|
+
|
53
|
+
# delete should not work
|
54
|
+
puts "==> Delete non-existing container (should not work)"
|
55
|
+
|
56
|
+
begin
|
57
|
+
res = delete(name)
|
58
|
+
raise 'delete() failed'
|
59
|
+
rescue => e
|
60
|
+
puts "==> PASS"
|
61
|
+
end
|
62
|
+
|
63
|
+
# start should not work
|
64
|
+
puts "==> Starting non-existing container (should not work)"
|
65
|
+
|
66
|
+
begin
|
67
|
+
res = start(name)
|
68
|
+
raise 'start() failed'
|
69
|
+
rescue => e
|
70
|
+
puts "==> PASS"
|
71
|
+
end
|
72
|
+
|
73
|
+
# stop should not work
|
74
|
+
puts "==> Stopping non-existing container (should not work)"
|
75
|
+
|
76
|
+
begin
|
77
|
+
res = stop(name)
|
78
|
+
raise 'stop() failed'
|
79
|
+
rescue => e
|
80
|
+
puts "==> PASS"
|
81
|
+
end
|
82
|
+
|
83
|
+
# kill should not work
|
84
|
+
puts "==> Killing non-existing container (should not work)"
|
85
|
+
|
86
|
+
begin
|
87
|
+
res = kill(name)
|
88
|
+
raise 'kill() failed'
|
89
|
+
rescue => e
|
90
|
+
puts "==> PASS"
|
91
|
+
end
|
92
|
+
|
93
|
+
# create should work
|
94
|
+
puts "==> Create container"
|
95
|
+
create_container(name, '1.2.3.4', 1, 64, 1)
|
96
|
+
puts "==> PASS"
|
97
|
+
|
98
|
+
# start should work
|
99
|
+
puts "==> Starting container"
|
100
|
+
start(name)
|
101
|
+
puts "==> PASS"
|
102
|
+
|
103
|
+
# stop should work
|
104
|
+
puts "==> Stopping container"
|
105
|
+
stop(name)
|
106
|
+
puts "==> PASS"
|
107
|
+
|
108
|
+
# kill should not work
|
109
|
+
puts "==> Killing stopped container (should not work)"
|
110
|
+
|
111
|
+
begin
|
112
|
+
res = kill(name)
|
113
|
+
raise 'kill() failed'
|
114
|
+
rescue => e
|
115
|
+
puts "==> PASS"
|
116
|
+
end
|
117
|
+
|
118
|
+
# stop should not work
|
119
|
+
puts "==> Stopping stopped container (should not work)"
|
120
|
+
|
121
|
+
begin
|
122
|
+
res = stop(name)
|
123
|
+
raise 'stop() failed'
|
124
|
+
rescue => e
|
125
|
+
puts "==> PASS"
|
126
|
+
end
|
127
|
+
|
128
|
+
# start should work
|
129
|
+
puts "==> Starting container"
|
130
|
+
start(name)
|
131
|
+
puts "==> PASS"
|
132
|
+
|
133
|
+
# kill should work
|
134
|
+
puts "==> Killing container"
|
135
|
+
kill(name)
|
136
|
+
puts "==> PASS"
|
137
|
+
|
138
|
+
# delete should work
|
139
|
+
puts "==> Deleting container"
|
140
|
+
delete(name)
|
141
|
+
puts "==> PASS"
|
142
|
+
end
|
143
|
+
|
144
|
+
# Initializes the manager with the matching adapter
|
145
|
+
#
|
146
|
+
# @param container_type [String] Container adapter
|
147
|
+
#
|
148
|
+
# @raise [ArgumentError] if the container type is invalid
|
149
|
+
def initialize(container_type)
|
150
|
+
if container_type == 'lxc'
|
151
|
+
@adapter = ContainerManagerAdapter::Lxc.new
|
152
|
+
elsif container_type == 'vserver'
|
153
|
+
@adapter = ContainerManagerAdapter::Vserver.new
|
154
|
+
else
|
155
|
+
raise ArgumentError, 'invalid container type'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Lists all available containers
|
160
|
+
#
|
161
|
+
# @return [Array]
|
162
|
+
def containers
|
163
|
+
@adapter.containers
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns information for a single container
|
167
|
+
#
|
168
|
+
# @param name [String] The container name
|
169
|
+
#
|
170
|
+
# @raise [NotFoundError]
|
171
|
+
#
|
172
|
+
# @return [Hash] Hash with information about the container
|
173
|
+
def container(name)
|
174
|
+
if !@adapter.exist?(name)
|
175
|
+
raise ::NotFoundError
|
176
|
+
end
|
177
|
+
|
178
|
+
@adapter.container(name)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns the amount of free cpu cores
|
182
|
+
#
|
183
|
+
# @param resman [ResourceManager] A ResourceManager instance
|
184
|
+
#
|
185
|
+
# @return [Integer] The amount of free cpu cores
|
186
|
+
def free_cpu_core_count(resman)
|
187
|
+
@adapter.free_cpu_core_count(resman)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Starts a container with the given name
|
191
|
+
#
|
192
|
+
# @param name [String] The container name
|
193
|
+
#
|
194
|
+
# @raise [RuntimeError]
|
195
|
+
# @raise [NotFoundError]
|
196
|
+
#
|
197
|
+
# @return [String] CLI output
|
198
|
+
def start(name)
|
199
|
+
if !@adapter.exist?(name)
|
200
|
+
raise ::NotFoundError
|
201
|
+
end
|
202
|
+
|
203
|
+
@adapter.start(name)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Stops a container with the given name
|
207
|
+
#
|
208
|
+
# @param name [String] The container name
|
209
|
+
#
|
210
|
+
# @raise [RuntimeError]
|
211
|
+
# @raise [NotFoundError]
|
212
|
+
#
|
213
|
+
# @return [String] CLI output
|
214
|
+
def stop(name)
|
215
|
+
if !@adapter.exist?(name)
|
216
|
+
raise ::NotFoundError
|
217
|
+
end
|
218
|
+
|
219
|
+
@adapter.stop(name)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Kills a container with the given name
|
223
|
+
#
|
224
|
+
# @param name [String] The container name
|
225
|
+
#
|
226
|
+
# @raise [RuntimeError]
|
227
|
+
# @raise [NotFoundError]
|
228
|
+
#
|
229
|
+
# @return [String] CLI output
|
230
|
+
def kill(name)
|
231
|
+
if !@adapter.exist?(name)
|
232
|
+
raise ::NotFoundError
|
233
|
+
end
|
234
|
+
|
235
|
+
@adapter.kill(name)
|
236
|
+
end
|
237
|
+
|
238
|
+
# Deletes a container with the given name
|
239
|
+
#
|
240
|
+
# @param name [String] The container name
|
241
|
+
#
|
242
|
+
# @raise [RuntimeError]
|
243
|
+
# @raise [NotFoundError]
|
244
|
+
#
|
245
|
+
# @return [String] CLI output
|
246
|
+
def delete(name)
|
247
|
+
if !@adapter.exist?(name)
|
248
|
+
raise ::NotFoundError
|
249
|
+
end
|
250
|
+
|
251
|
+
@adapter.delete(name)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Creates a container with the given parameters
|
255
|
+
#
|
256
|
+
# @param name [String] The container name
|
257
|
+
# @param ip_address [String] A valid IPv4 address
|
258
|
+
# @param disk_size_gb [Integer] The disk size in GB
|
259
|
+
# @param memory_limit_mb [Integer] The memory limit in MB
|
260
|
+
# @param cpu_core_count [Integer] Amount of Vcores to assign
|
261
|
+
#
|
262
|
+
# @raise [RuntimeError]
|
263
|
+
# @raise [NotFoundError]
|
264
|
+
# @raise [ArgumentError]
|
265
|
+
#
|
266
|
+
# @return [String] CLI output
|
267
|
+
def create_container(name, ip_address, disk_size_gb, memory_limit_mb, cpu_core_count)
|
268
|
+
disk_size_gb = disk_size_gb.to_i
|
269
|
+
memory_limit_mb = memory_limit_mb.to_i
|
270
|
+
cpu_core_count = cpu_core_count.to_i
|
271
|
+
|
272
|
+
if name.nil? || name.empty? || (/^([A-Za-z0-9_]+)$/ =~ name).nil?
|
273
|
+
raise ArgumentError, 'container name is invalid'
|
274
|
+
end
|
275
|
+
|
276
|
+
if ip_address.nil? || ip_address.empty? || (/^#{Resolv::IPv4::Regex}$/ =~ ip_address).nil?
|
277
|
+
raise ArgumentError, 'the submitted ip address is not a valid ipv4 address'
|
278
|
+
end
|
279
|
+
|
280
|
+
if @adapter.exist?(name)
|
281
|
+
raise ::NotFoundError
|
282
|
+
end
|
283
|
+
|
284
|
+
@adapter.create_container(name, ip_address, disk_size_gb, memory_limit_mb, cpu_core_count)
|
285
|
+
end
|
286
|
+
end
|