wf_node_api 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/Gemfile +28 -0
  4. data/Gemfile.lock +66 -0
  5. data/LICENSE +340 -0
  6. data/Makefile +19 -0
  7. data/README.md +78 -0
  8. data/Rakefile +2 -0
  9. data/Vagrantfile +102 -0
  10. data/_docs/api/Api/NodeApi.html +123 -0
  11. data/_docs/api/Api.html +149 -0
  12. data/_docs/api/Config/Check.html +331 -0
  13. data/_docs/api/Config.html +115 -0
  14. data/_docs/api/ConfigCheck.html +365 -0
  15. data/_docs/api/ContainerManager.html +1632 -0
  16. data/_docs/api/ContainerManagerAdapter/Lxc.html +1352 -0
  17. data/_docs/api/ContainerManagerAdapter/Vserver.html +1358 -0
  18. data/_docs/api/ContainerManagerAdapter.html +151 -0
  19. data/_docs/api/Error/NotFound.html +134 -0
  20. data/_docs/api/Error.html +115 -0
  21. data/_docs/api/NotFoundError.html +157 -0
  22. data/_docs/api/OS.html +234 -0
  23. data/_docs/api/ResourceManager.html +322 -0
  24. data/_docs/api/ResourceManagerAdapter/Linux.html +326 -0
  25. data/_docs/api/ResourceManagerAdapter.html +149 -0
  26. data/_docs/api/WfNodeApi.html +163 -0
  27. data/_docs/api/_index.html +239 -0
  28. data/_docs/api/class_list.html +58 -0
  29. data/_docs/api/css/common.css +1 -0
  30. data/_docs/api/css/full_list.css +57 -0
  31. data/_docs/api/css/style.css +339 -0
  32. data/_docs/api/file.README.html +146 -0
  33. data/_docs/api/file_list.html +60 -0
  34. data/_docs/api/frames.html +26 -0
  35. data/_docs/api/index.html +146 -0
  36. data/_docs/api/js/app.js +219 -0
  37. data/_docs/api/js/full_list.js +181 -0
  38. data/_docs/api/js/jquery.js +4 -0
  39. data/_docs/api/method_list.html +273 -0
  40. data/_docs/api/top-level-namespace.html +244 -0
  41. data/_docs/rest/api_data.js +1 -0
  42. data/_docs/rest/api_data.json +1 -0
  43. data/_docs/rest/api_project.js +1 -0
  44. data/_docs/rest/api_project.json +1 -0
  45. data/_docs/rest/css/style.css +538 -0
  46. data/_docs/rest/header.md +3 -0
  47. data/_docs/rest/img/favicon.ico +0 -0
  48. data/_docs/rest/img/glyphicons-halflings-white.png +0 -0
  49. data/_docs/rest/img/glyphicons-halflings.png +0 -0
  50. data/_docs/rest/index.html +658 -0
  51. data/_docs/rest/locales/de.js +25 -0
  52. data/_docs/rest/locales/fr.js +25 -0
  53. data/_docs/rest/locales/locale.js +43 -0
  54. data/_docs/rest/locales/nl.js +25 -0
  55. data/_docs/rest/locales/pl.js +25 -0
  56. data/_docs/rest/locales/pt_br.js +25 -0
  57. data/_docs/rest/locales/ru.js +25 -0
  58. data/_docs/rest/locales/zh.js +25 -0
  59. data/_docs/rest/main.js +691 -0
  60. data/_docs/rest/utils/handlebars_helper.js +327 -0
  61. data/_docs/rest/utils/send_sample_request.js +158 -0
  62. data/_docs/rest/vendor/bootstrap-responsive.min.css +9 -0
  63. data/_docs/rest/vendor/bootstrap.min.css +9 -0
  64. data/_docs/rest/vendor/bootstrap.min.js +6 -0
  65. data/_docs/rest/vendor/diff_match_patch.min.js +49 -0
  66. data/_docs/rest/vendor/handlebars.min.js +28 -0
  67. data/_docs/rest/vendor/jquery.min.js +4 -0
  68. data/_docs/rest/vendor/lodash.min.js +61 -0
  69. data/_docs/rest/vendor/path-to-regexp/LICENSE +21 -0
  70. data/_docs/rest/vendor/path-to-regexp/index.js +205 -0
  71. data/_docs/rest/vendor/polyfill.js +100 -0
  72. data/_docs/rest/vendor/prettify/lang-apollo.js +2 -0
  73. data/_docs/rest/vendor/prettify/lang-basic.js +3 -0
  74. data/_docs/rest/vendor/prettify/lang-clj.js +18 -0
  75. data/_docs/rest/vendor/prettify/lang-css.js +2 -0
  76. data/_docs/rest/vendor/prettify/lang-dart.js +3 -0
  77. data/_docs/rest/vendor/prettify/lang-erlang.js +2 -0
  78. data/_docs/rest/vendor/prettify/lang-go.js +1 -0
  79. data/_docs/rest/vendor/prettify/lang-hs.js +2 -0
  80. data/_docs/rest/vendor/prettify/lang-lisp.js +3 -0
  81. data/_docs/rest/vendor/prettify/lang-llvm.js +1 -0
  82. data/_docs/rest/vendor/prettify/lang-lua.js +2 -0
  83. data/_docs/rest/vendor/prettify/lang-matlab.js +6 -0
  84. data/_docs/rest/vendor/prettify/lang-ml.js +2 -0
  85. data/_docs/rest/vendor/prettify/lang-mumps.js +2 -0
  86. data/_docs/rest/vendor/prettify/lang-n.js +4 -0
  87. data/_docs/rest/vendor/prettify/lang-pascal.js +3 -0
  88. data/_docs/rest/vendor/prettify/lang-proto.js +1 -0
  89. data/_docs/rest/vendor/prettify/lang-r.js +2 -0
  90. data/_docs/rest/vendor/prettify/lang-rd.js +1 -0
  91. data/_docs/rest/vendor/prettify/lang-scala.js +2 -0
  92. data/_docs/rest/vendor/prettify/lang-sql.js +2 -0
  93. data/_docs/rest/vendor/prettify/lang-tcl.js +3 -0
  94. data/_docs/rest/vendor/prettify/lang-tex.js +1 -0
  95. data/_docs/rest/vendor/prettify/lang-vb.js +2 -0
  96. data/_docs/rest/vendor/prettify/lang-vhdl.js +3 -0
  97. data/_docs/rest/vendor/prettify/lang-wiki.js +2 -0
  98. data/_docs/rest/vendor/prettify/lang-xq.js +3 -0
  99. data/_docs/rest/vendor/prettify/lang-yaml.js +2 -0
  100. data/_docs/rest/vendor/prettify/prettify.css +1 -0
  101. data/_docs/rest/vendor/prettify/prettify.js +30 -0
  102. data/_docs/rest/vendor/prettify/run_prettify.js +34 -0
  103. data/_docs/rest/vendor/prettify.css +101 -0
  104. data/_docs/rest/vendor/require.min.js +36 -0
  105. data/apidoc.json +23 -0
  106. data/bin/wf_node_api +80 -0
  107. data/lib/wf_node_api/api/node_api.rb +360 -0
  108. data/lib/wf_node_api/config/config_template.erb +50 -0
  109. data/lib/wf_node_api/config_check.rb +50 -0
  110. data/lib/wf_node_api/container_manager.rb +286 -0
  111. data/lib/wf_node_api/container_manager_adapter/lxc.rb +431 -0
  112. data/lib/wf_node_api/container_manager_adapter/vserver.rb +448 -0
  113. data/lib/wf_node_api/error/not_found.rb +27 -0
  114. data/lib/wf_node_api/os.rb +32 -0
  115. data/lib/wf_node_api/resource_manager.rb +49 -0
  116. data/lib/wf_node_api/resource_manager_adapter/linux.rb +53 -0
  117. data/lib/wf_node_api/translations.rb +38 -0
  118. data/lib/wf_node_api/version.rb +28 -0
  119. data/lib/wf_node_api.rb +57 -0
  120. data/manifests/files/dhozac-vserver.repo +4 -0
  121. data/wf-node-api.gemspec +53 -0
  122. metadata +221 -0
@@ -0,0 +1,448 @@
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 ContainerManagerAdapter
27
+ # Container adapter for linux-vserver. Encapsulates all vserver specific command line
28
+ # wrapping
29
+ class Vserver
30
+ # Lists all available containers
31
+ #
32
+ # @return [Array]
33
+ def containers
34
+ container_list = []
35
+
36
+ self.container_names.each do |item|
37
+ container_list << container(item)
38
+ end
39
+
40
+ container_list
41
+ end
42
+
43
+ # Starts a container with the given name
44
+ #
45
+ # @param name [String] The container name
46
+ #
47
+ # @raise [RuntimeError]
48
+ #
49
+ # @return [String] CLI output
50
+ def start(name)
51
+ res = Open3.capture3($vserver_cmd_start.gsub('[name]', name))
52
+
53
+ if res[2].exitstatus == 0 && state(name) == 'RUNNING'
54
+ $logger.info("container " + name + " successfully started")
55
+ return res[0].strip
56
+ end
57
+
58
+ $logger.warn("container " + name + " could not be started")
59
+ raise RuntimeError, res[1].strip
60
+ end
61
+
62
+ # Stops a container with the given name
63
+ #
64
+ # @param name [String] The container name
65
+ #
66
+ # @raise [RuntimeError]
67
+ #
68
+ # @return [String] CLI output
69
+ def stop(name)
70
+ if state(name) == 'STOPPED'
71
+ $logger.warn("container " + name + " could not be stopped, because it is not running")
72
+ raise RuntimeError, 'container is not running'
73
+ end
74
+
75
+ res = Open3.capture3($vserver_cmd_stop.gsub('[name]', name))
76
+
77
+ if res[2].exitstatus == 0 && state(name) == 'STOPPED'
78
+ $logger.info("container " + name + " successfully stopped")
79
+ return res[0].strip
80
+ end
81
+
82
+ $logger.warn("container " + name + " could not be stopped")
83
+ raise RuntimeError, res[1].strip
84
+ end
85
+
86
+ # Kills a container with the given name
87
+ #
88
+ # @param name [String] The container name
89
+ #
90
+ # @raise [RuntimeError]
91
+ #
92
+ # @return [String] CLI output
93
+ def kill(name)
94
+ return stop(name)
95
+ end
96
+
97
+ # Deletes a container with the given name
98
+ #
99
+ # @param name [String] The container name
100
+ #
101
+ # @raise [RuntimeError]
102
+ #
103
+ # @return [String] CLI output
104
+ def delete(name)
105
+ res = Open3.capture3($vserver_cmd_destroy.gsub('[name]', name))
106
+
107
+ if res[1].empty? && res[2].exitstatus == 0
108
+ $logger.info("container " + name + " successfully deleted")
109
+ return res[0].strip
110
+ end
111
+
112
+ $logger.warn("container" + name + " could not be deleted")
113
+ raise RuntimeError, res[1].strip
114
+ end
115
+
116
+ # Returns information for a single container
117
+ #
118
+ # @param name [String] The container name
119
+ #
120
+ # @return [Hash] Hash with information about the container
121
+ def container(name)
122
+ data = {}
123
+
124
+ data[:name] = name
125
+ data[:state] = translate_state(state(name))
126
+ data[:ip_address] = ip_addr(name)
127
+ data[:cpu_usage] = 0
128
+ data[:cpu_cores] = assigned_cpu_cores(name).count
129
+ data[:memory_limit_bytes] = memory_limit(name).to_i
130
+ data[:memory_usage_bytes] = memory_usage(name).to_i
131
+ data[:disk_space_gb] = 0
132
+ data[:disk_usage_gb] = 0
133
+ data[:container_type] = 'vserver'
134
+
135
+ data
136
+ end
137
+
138
+ # Creates a container with the given parameters
139
+ #
140
+ # @param name [String] The container name
141
+ # @param ip_address [String] A valid IPv4 address
142
+ # @param disk_size_gb [Integer] The disk size in GB
143
+ # @param memory_limit_mb [Integer] The memory limit in MB
144
+ # @param cpu_core_count [Integer] Amount of Vcores to assign. 0 for no limit
145
+ #
146
+ # @raise [RuntimeError]
147
+ #
148
+ # @return [String] CLI output
149
+ def create_container(name, ip_address, disk_size_gb, memory_limit_mb, cpu_core_count)
150
+ output = ''
151
+
152
+ begin
153
+ if cpu_core_count != 0
154
+ cpuset = generate_cpu_set(cpu_core_count, ResourceManager.new('linux'))
155
+ end
156
+
157
+ new_context = highest_context() + 1
158
+ cmd = $vserver_cmd_create.gsub('[name]', name).gsub('[ip_address]', ip_address).gsub('[context]', new_context.to_s)
159
+
160
+ create_result = Open3.capture3(cmd)
161
+
162
+ output += create_result[0]
163
+ output += create_result[1]
164
+
165
+ if create_result[2].exitstatus != 0
166
+ raise RuntimeError, 'command did not exit with status 0'
167
+ end
168
+
169
+ # memory limit
170
+ memory_limit_bytes = memory_limit_mb.to_i * 1024 * 1024
171
+ page_size = `#{$page_size_cmd}`.to_i
172
+ memory_limit_pages = memory_limit_bytes / page_size
173
+
174
+ write_config_file(name, '/rlimits/rss.hard', memory_limit_pages.to_s)
175
+
176
+ if cpu_core_count != 0
177
+ # cpu core limit
178
+ write_config_file(name, '/cgroup/cpuset.cpus', cpuset)
179
+ end
180
+
181
+ $logger.info("creation of container " + name + " successful")
182
+ return output.strip
183
+ rescue => e
184
+ $logger.warn("container " + name + " could not be created, rolling back...")
185
+
186
+ # rollback
187
+ delete(name) if exist?(name)
188
+
189
+ output += e.message
190
+ raise RuntimeError, output.strip
191
+ end
192
+ end
193
+
194
+ # Checks if a container with the given name exists
195
+ #
196
+ # @param name [String] The container name
197
+ #
198
+ # @return [Boolean] Existing/not existing
199
+ def exist?(name)
200
+ self.container_names.include?(name)
201
+ end
202
+
203
+ # Returns the amount of free cpu cores
204
+ #
205
+ # @param resman [ResourceManager] A ResourceManager instance
206
+ #
207
+ # @return [Integer] The amount of free cpu cores
208
+ def free_cpu_core_count(resman)
209
+ self.free_cpu_cores(resman).count
210
+ end
211
+
212
+ protected
213
+ # Writes the config file of a vserver
214
+ #
215
+ # @param name [String] The container name
216
+ # @param path [String] Filepath
217
+ # @param content [String] File contents
218
+ #
219
+ # @return [Boolean] Result of File.write
220
+ def write_config_file(name, path, content)
221
+ config_path = "#{$vserver_config_dir.gsub('[name]', name)}#{path}"
222
+ `mkdir -p #{File.dirname(config_path)}`
223
+
224
+ File.write(config_path, content)
225
+ end
226
+
227
+ # Reads the config file of a vserver
228
+ #
229
+ # @param name [String] The container name
230
+ #
231
+ # @raise [StandardError]
232
+ #
233
+ # @return [String] Contents of the configuration file
234
+ def read_config_file(name, path)
235
+ config_path = "#{$vserver_config_dir.gsub('[name]', name)}#{path}"
236
+
237
+ if File.exists?(config_path) == false
238
+ return nil
239
+ end
240
+
241
+ File.read(config_path).strip
242
+ end
243
+
244
+ # Creates a map of the vserver contexts
245
+ #
246
+ # @return [Hash]
247
+ def context_map
248
+ map = {}
249
+
250
+ containers.each() do |container|
251
+ map[container[:name]] = context(container[:name])
252
+ end
253
+
254
+ map
255
+ end
256
+
257
+ # Reads the context for a specific container
258
+ #
259
+ # @param name [String] The container name
260
+ #
261
+ # @raise [RuntimeError]
262
+ #
263
+ # @return [Integer] The context ID
264
+ def context(name)
265
+ file = "#{$vserver_config_dir.gsub('[name]', name)}/context"
266
+
267
+ if false == File.readable?(file)
268
+ raise RuntimeError, "file #{file} is not readable"
269
+ end
270
+
271
+ context = File.read(file)
272
+
273
+ context.to_i
274
+ end
275
+
276
+ # Returns the stats for a container
277
+ #
278
+ # @param name [String] The container name
279
+ #
280
+ # @return [Array] Stats
281
+ def vserver_stat(name)
282
+ res = `#{$vserver_cmd_stat.gsub('[name]', name)}`
283
+
284
+ res.split(' ').map(&:strip)
285
+ end
286
+
287
+ # Returns the current memory usage
288
+ #
289
+ # @param name [String] The container name
290
+ #
291
+ # @return [Integer] Memory usage
292
+ def memory_usage(name)
293
+ stat = vserver_stat(name)
294
+
295
+ if stat[2] == nil
296
+ return nil
297
+ end
298
+
299
+ (stat[2][0..-2].to_f * 1024.0 * 1024.0).to_i
300
+ end
301
+
302
+ # Finds the highest context
303
+ #
304
+ # @return [Integer] The highest context
305
+ def highest_context
306
+ contextmap = context_map()
307
+
308
+ if contextmap.empty?
309
+ return 1
310
+ end
311
+
312
+ contextmap.max_by{|k, v| v}.last
313
+ end
314
+
315
+ # Returns the ip address for a container
316
+ #
317
+ # @return [String] The IP address
318
+ def ip_addr(name)
319
+ read_config_file(name, '/interfaces/0/ip')
320
+ end
321
+
322
+ # Returns the state for a container
323
+ #
324
+ # @param name [String] The container name
325
+ #
326
+ # @return [String] Container status, STOPPED or RUNNING
327
+ def state(name)
328
+ output = `#{$vserver_cmd_stat.gsub('[name]', name)}`
329
+
330
+ if output.empty?
331
+ return 'STOPPED'
332
+ else
333
+ return 'RUNNING'
334
+ end
335
+ end
336
+
337
+ # Returns the memory limit for a container
338
+ #
339
+ # @param name [String] The container name
340
+ #
341
+ # @return [Integer|NilClass] Memory limit in bytes
342
+ def memory_limit(name)
343
+ ctx = context(name)
344
+ page_size = `#{$page_size_cmd}`.to_i
345
+
346
+ memory_limit_result = `#{$vserver_cmd_get_memory_limit.gsub('[context]', ctx.to_s)}`
347
+ parts = memory_limit_result.split(' ').map(&:strip)
348
+
349
+ if parts.empty?
350
+ return nil
351
+ else
352
+ return (parts.last.to_i * page_size)
353
+ end
354
+ end
355
+
356
+ # Gets the globally assigned cpu cores
357
+ #
358
+ # @return [Array]
359
+ def used_cpu_cores
360
+ used_cores = []
361
+
362
+ container_names.each do |c|
363
+ self.assigned_cpu_cores(c).each do |cpu|
364
+ used_cores.push(cpu)
365
+ end
366
+ end
367
+
368
+ used_cores
369
+ end
370
+
371
+ # Gets the cpu cores assigned to a container
372
+ #
373
+ # @param name [String] The container name
374
+ #
375
+ # @return [Array] with cpu core ids
376
+ def assigned_cpu_cores(name)
377
+ value = self.read_config_file(name, '/cgroup/cpuset.cpus')
378
+ used_cores = []
379
+
380
+ if value == nil
381
+ return used_cores
382
+ end
383
+
384
+ value.split(',').each do |cpu|
385
+ if cpu.include?('-')
386
+ range = Range.new(*cpu.split('-').map(&:to_i))
387
+
388
+ range.each do |i|
389
+ used_cores.push(i)
390
+ end
391
+ else
392
+ used_cores.push(cpu.to_i)
393
+ end
394
+ end
395
+
396
+ used_cores
397
+ end
398
+
399
+ # Finds free cpu cores
400
+ #
401
+ # @param resman [ResourceManager] A ResourceManager instance
402
+ #
403
+ # @return [Array] Free cpu cores
404
+ def free_cpu_cores(resman)
405
+ raise ArgumentError, 'no valid ResourceManager instance' unless resman.is_a?(ResourceManager)
406
+
407
+ free_cores = []
408
+ used_cores = self.used_cpu_cores()
409
+
410
+ (0..(resman.total_cpu_cores-1)).each do |i|
411
+ if used_cores.include?(i) == false
412
+ free_cores.push(i)
413
+ end
414
+ end
415
+
416
+ free_cores
417
+ end
418
+
419
+ # Generates a cpu set for a container
420
+ #
421
+ # @param count [Integer] Number of cpu cores to use
422
+ # @param resman [ResourceManager] A ResourceManager instance
423
+ #
424
+ # @raise [RuntimeError]
425
+ #
426
+ # @return [String] cpuset string
427
+ def generate_cpu_set(count, resman)
428
+ count = count.to_i
429
+ free_cores = self.free_cpu_cores(resman)
430
+
431
+ if count > free_cores.count
432
+ raise RuntimeError, 'not enough cpu cores left'
433
+ end
434
+
435
+ cores_to_use = []
436
+
437
+ count.times do
438
+ cores_to_use.push(free_cores.shift)
439
+ end
440
+
441
+ cores_to_use.join(',')
442
+ end
443
+
444
+ def container_names
445
+ `#{$vserver_cmd_ls}`.lines.map(&:strip).uniq
446
+ end
447
+ end
448
+ end
@@ -0,0 +1,27 @@
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
+ class NotFoundError < StandardError
27
+ end
@@ -0,0 +1,32 @@
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 OS
27
+ # Returns true if this is a linux system
28
+ # @return [Boolean]
29
+ def self.linux?
30
+ RUBY_PLATFORM.include?('linux')
31
+ end
32
+ end
@@ -0,0 +1,49 @@
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
+ # Top level class for resource management
27
+ class ResourceManager
28
+
29
+ # Initializes the ResourceManager with a matching adapter
30
+ #
31
+ # @raise [ArgumentError]
32
+ def initialize(type)
33
+ @resman = nil
34
+
35
+ if type == 'linux'
36
+ @resman = ResourceManagerAdapter::Linux.new
37
+ else
38
+ raise ArgumentError, 'invalid resourcemanager type supplied'
39
+ end
40
+ end
41
+
42
+ # Returns the total number of cpu cores available on the system
43
+ #
44
+ # @return [Integer]
45
+ def total_cpu_cores
46
+ @resman.total_cpu_cores
47
+ end
48
+
49
+ end
@@ -0,0 +1,53 @@
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 ResourceManagerAdapter
27
+ # ResourceManager adapter for Linux
28
+ class Linux
29
+
30
+ # Initializes the adapter
31
+ #
32
+ # @raise [RuntimeError]
33
+ def initialize
34
+ if $container_type == 'LXC' && File.exists?($lxc_cgroup_mount_path) == false
35
+ raise RuntimeError, 'no cgroup node found'
36
+ end
37
+ end
38
+
39
+ # Finds the total amount of cpu cores
40
+ #
41
+ # @return [Integer]
42
+ def total_cpu_cores
43
+ cpu_cores = `nproc`.strip.to_i
44
+
45
+ if $?.exitstatus != 0
46
+ raise RuntimeError, 'could not run nproc'
47
+ end
48
+
49
+ return cpu_cores
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,38 @@
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
+ # Translates a container state to the whitefuses states
27
+ #
28
+ # @param state [String] Original state
29
+ #
30
+ # @return [String] The translated state
31
+ def translate_state(state)
32
+ case state
33
+ when 'RUNNING'
34
+ return 'RUNNING'
35
+ else
36
+ return 'STOPPED'
37
+ end
38
+ end
@@ -0,0 +1,28 @@
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 WfNodeApi
27
+ VERSION = '0.6.0'
28
+ end