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,101 @@
1
+ /* Pretty printing styles. Used with prettify.js. */
2
+ /* Vim sunburst theme by David Leibovic */
3
+ pre .str {
4
+ color: #65B042;
5
+ }
6
+ /* string - green */
7
+ pre .kwd {
8
+ color: #E28964;
9
+ }
10
+ /* keyword - dark pink */
11
+ pre .com {
12
+ color: #AEAEAE;
13
+ font-style: italic;
14
+ }
15
+ /* comment - gray */
16
+ pre .typ {
17
+ color: #89bdff;
18
+ }
19
+ /* type - light blue */
20
+ pre .lit {
21
+ color: #3387CC;
22
+ }
23
+ /* literal - blue */
24
+ pre .pun {
25
+ color: #fff;
26
+ }
27
+ /* punctuation - white */
28
+ pre .pln {
29
+ color: #fff;
30
+ }
31
+ /* plaintext - white */
32
+ pre .tag {
33
+ color: #89bdff;
34
+ }
35
+ /* html/xml tag - light blue */
36
+ pre .atn {
37
+ color: #bdb76b;
38
+ }
39
+ /* html/xml attribute name - khaki */
40
+ pre .atv {
41
+ color: #65B042;
42
+ }
43
+ /* html/xml attribute value - green */
44
+ pre .dec {
45
+ color: #3387CC;
46
+ }
47
+ /* decimal - blue */
48
+ /* Specify class=linenums on a pre to get line numbering */
49
+ ol.linenums {
50
+ margin-top: 0;
51
+ margin-bottom: 0;
52
+ color: #AEAEAE;
53
+ }
54
+ /* IE indents via margin-left */
55
+ li.L0,
56
+ li.L1,
57
+ li.L2,
58
+ li.L3,
59
+ li.L5,
60
+ li.L6,
61
+ li.L7,
62
+ li.L8 {
63
+ list-style-type: none;
64
+ }
65
+ /* Alternate shading for lines */
66
+ @media print {
67
+ pre .str {
68
+ color: #060;
69
+ }
70
+ pre .kwd {
71
+ color: #006;
72
+ font-weight: bold;
73
+ }
74
+ pre .com {
75
+ color: #600;
76
+ font-style: italic;
77
+ }
78
+ pre .typ {
79
+ color: #404;
80
+ font-weight: bold;
81
+ }
82
+ pre .lit {
83
+ color: #044;
84
+ }
85
+ pre .pun {
86
+ color: #440;
87
+ }
88
+ pre .pln {
89
+ color: #000;
90
+ }
91
+ pre .tag {
92
+ color: #006;
93
+ font-weight: bold;
94
+ }
95
+ pre .atn {
96
+ color: #404;
97
+ }
98
+ pre .atv {
99
+ color: #060;
100
+ }
101
+ }
@@ -0,0 +1,36 @@
1
+ /*
2
+ RequireJS 2.1.15 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
3
+ Available via the MIT or new BSD license.
4
+ see: http://github.com/jrburke/requirejs for details
5
+ */
6
+ var requirejs,require,define;
7
+ (function(ba){function G(b){return"[object Function]"===K.call(b)}function H(b){return"[object Array]"===K.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function T(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function t(b,c){return fa.call(b,c)}function m(b,c){return t(b,c)&&b[c]}function B(b,c){for(var d in b)if(t(b,d)&&c(b[d],d))break}function U(b,c,d,e){c&&B(c,function(c,g){if(d||!t(b,g))e&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
8
+ RegExp)?(b[g]||(b[g]={}),U(b[g],c,d,e)):b[g]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function ca(b){throw b;}function da(b){if(!b)return b;var c=ba;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,e){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=e;d&&(c.originalError=d);return c}function ga(b){function c(a,k,b){var f,l,c,d,e,g,i,p,k=k&&k.split("/"),h=j.map,n=h&&h["*"];if(a){a=a.split("/");l=a.length-1;j.nodeIdCompat&&
9
+ Q.test(a[l])&&(a[l]=a[l].replace(Q,""));"."===a[0].charAt(0)&&k&&(l=k.slice(0,k.length-1),a=l.concat(a));l=a;for(c=0;c<l.length;c++)if(d=l[c],"."===d)l.splice(c,1),c-=1;else if(".."===d&&!(0===c||1==c&&".."===l[2]||".."===l[c-1])&&0<c)l.splice(c-1,2),c-=2;a=a.join("/")}if(b&&h&&(k||n)){l=a.split("/");c=l.length;a:for(;0<c;c-=1){e=l.slice(0,c).join("/");if(k)for(d=k.length;0<d;d-=1)if(b=m(h,k.slice(0,d).join("/")))if(b=m(b,e)){f=b;g=c;break a}!i&&(n&&m(n,e))&&(i=m(n,e),p=c)}!f&&i&&(f=i,g=p);f&&(l.splice(0,
10
+ g,f),a=l.join("/"))}return(f=m(j.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(k){if(k.getAttribute("data-requiremodule")===a&&k.getAttribute("data-requirecontext")===i.contextName)return k.parentNode.removeChild(k),!0})}function e(a){var k=m(j.paths,a);if(k&&H(k)&&1<k.length)return k.shift(),i.require.undef(a),i.makeRequire(null,{skipMap:!0})([a]),!0}function n(a){var k,c=a?a.indexOf("!"):-1;-1<c&&(k=a.substring(0,c),a=a.substring(c+1,a.length));return[k,a]}function p(a,
11
+ k,b,f){var l,d,e=null,g=k?k.name:null,j=a,p=!0,h="";a||(p=!1,a="_@r"+(K+=1));a=n(a);e=a[0];a=a[1];e&&(e=c(e,g,f),d=m(r,e));a&&(e?h=d&&d.normalize?d.normalize(a,function(a){return c(a,g,f)}):-1===a.indexOf("!")?c(a,g,f):a:(h=c(a,g,f),a=n(h),e=a[0],h=a[1],b=!0,l=i.nameToUrl(h)));b=e&&!d&&!b?"_unnormalized"+(O+=1):"";return{prefix:e,name:h,parentMap:k,unnormalized:!!b,url:l,originalName:j,isDefine:p,id:(e?e+"!"+h:h)+b}}function s(a){var k=a.id,b=m(h,k);b||(b=h[k]=new i.Module(a));return b}function q(a,
12
+ k,b){var f=a.id,c=m(h,f);if(t(r,f)&&(!c||c.defineEmitComplete))"defined"===k&&b(r[f]);else if(c=s(a),c.error&&"error"===k)b(c.error);else c.on(k,b)}function w(a,b){var c=a.requireModules,f=!1;if(b)b(a);else if(v(c,function(b){if(b=m(h,b))b.error=a,b.events.error&&(f=!0,b.emit("error",a))}),!f)g.onError(a)}function x(){R.length&&(ha.apply(A,[A.length,0].concat(R)),R=[])}function y(a){delete h[a];delete V[a]}function F(a,b,c){var f=a.map.id;a.error?a.emit("error",a.error):(b[f]=!0,v(a.depMaps,function(f,
13
+ d){var e=f.id,g=m(h,e);g&&(!a.depMatched[d]&&!c[e])&&(m(b,e)?(a.defineDep(d,r[e]),a.check()):F(g,b,c))}),c[f]=!0)}function D(){var a,b,c=(a=1E3*j.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],l=[],g=!1,h=!0;if(!W){W=!0;B(V,function(a){var i=a.map,j=i.id;if(a.enabled&&(i.isDefine||l.push(a),!a.error))if(!a.inited&&c)e(j)?g=b=!0:(f.push(j),d(j));else if(!a.inited&&(a.fetched&&i.isDefine)&&(g=!0,!i.prefix))return h=!1});if(c&&f.length)return a=C("timeout","Load timeout for modules: "+f,null,
14
+ f),a.contextName=i.contextName,w(a);h&&v(l,function(a){F(a,{},{})});if((!c||b)&&g)if((z||ea)&&!X)X=setTimeout(function(){X=0;D()},50);W=!1}}function E(a){t(r,a[0])||s(p(a[0],null,!0)).init(a[1],a[2])}function I(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!Y?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||Y)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function J(){var a;
15
+ for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var W,Z,i,L,X,j={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},h={},V={},$={},A=[],r={},S={},aa={},K=1,O=1;L={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?r[a.map.id]=a.exports:a.exports=r[a.map.id]={}},module:function(a){return a.module?
16
+ a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return m(j.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};Z=function(a){this.events=m($,a.id)||{};this.map=a;this.shim=m(j.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Z.prototype={init:function(a,b,c,f){f=f||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=
17
+ c;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
18
+ this.map.url;S[a]||(S[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var f=this.exports,l=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(l)){if(this.events.error&&this.map.isDefine||g.onError!==ca)try{f=i.execCb(c,l,b,f)}catch(d){a=d}else f=i.execCb(c,l,b,f);this.map.isDefine&&void 0===f&&((b=this.module)?f=b.exports:this.usingExports&&
19
+ (f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(r[c]=f,g.onResourceLoad))g.onResourceLoad(i,this.map,this.depMaps);y(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
20
+ this.map,b=a.id,d=p(a.prefix);this.depMaps.push(d);q(d,"defined",u(this,function(f){var l,d;d=m(aa,this.map.id);var e=this.map.name,P=this.map.parentMap?this.map.parentMap.name:null,n=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(e=f.normalize(e,function(a){return c(a,P,!0)})||""),f=p(a.prefix+"!"+e,this.map.parentMap),q(f,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(h,f.id)){this.depMaps.push(f);
21
+ if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else d?(this.map.url=i.nameToUrl(d),this.load()):(l=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(h,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),l.fromText=u(this,function(f,c){var d=a.name,e=p(d),P=M;c&&(f=c);P&&(M=!1);s(e);t(j.config,b)&&(j.config[d]=j.config[b]);try{g.exec(f)}catch(h){return w(C("fromtexteval",
22
+ "fromText eval for "+b+" failed: "+h,h,[b]))}P&&(M=!0);this.depMaps.push(e);i.completeLoad(d);n([d],l)}),f.load(a.name,n,l,j))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,u(this,function(a,b){var c,f;if("string"===typeof a){a=p(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(L,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;q(a,"defined",u(this,function(a){this.defineDep(b,
23
+ a);this.check()}));this.errback&&q(a,"error",u(this,this.errback))}c=a.id;f=h[c];!t(L,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,u(this,function(a){var b=m(h,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:j,contextName:b,registry:h,defined:r,urlFetched:S,defQueue:A,Module:Z,makeModuleMap:p,
24
+ nextTick:g.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=j.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(j[b]||(j[b]={}),U(j[b],a,!0,!0)):j[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(aa[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),j.shim=b);a.packages&&v(a.packages,function(a){var b,
25
+ a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(j.paths[b]=a.location);j.pkgs[b]=a.name+"/"+(a.main||"main").replace(ia,"").replace(Q,"")});B(h,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=p(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ba,arguments));return b||a.exports&&da(a.exports)}},makeRequire:function(a,e){function j(c,d,m){var n,q;e.enableBuildCallback&&(d&&G(d))&&(d.__requireJsBuild=
26
+ !0);if("string"===typeof c){if(G(d))return w(C("requireargs","Invalid require call"),m);if(a&&t(L,c))return L[c](h[a.id]);if(g.get)return g.get(i,c,a,j);n=p(c,a,!1,!0);n=n.id;return!t(r,n)?w(C("notloaded",'Module name "'+n+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[n]}J();i.nextTick(function(){J();q=s(p(null,a));q.skipMap=e.skipMap;q.init(c,d,m,{enabled:!0});D()});return j}e=e||{};U(j,{isBrowser:z,toUrl:function(b){var d,e=b.lastIndexOf("."),k=b.split("/")[0];if(-1!==
27
+ e&&(!("."===k||".."===k)||1<e))d=b.substring(e,b.length),b=b.substring(0,e);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return t(r,p(b,a,!1,!0).id)},specified:function(b){b=p(b,a,!1,!0).id;return t(r,b)||t(h,b)}});a||(j.undef=function(b){x();var c=p(b,a,!0),e=m(h,b);d(b);delete r[b];delete S[c.url];delete $[b];T(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&($[b]=e.events),y(b))});return j},enable:function(a){m(h,a.id)&&s(a).enable()},completeLoad:function(a){var b,
28
+ c,d=m(j.shim,a)||{},g=d.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=m(h,a);if(!b&&!t(r,a)&&c&&!c.inited){if(j.enforceDefine&&(!g||!da(g)))return e(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,d.deps||[],d.exportsFn])}D()},nameToUrl:function(a,b,c){var d,e,h;(d=m(j.pkgs,a))&&(a=d);if(d=m(aa,a))return i.nameToUrl(d,b,c);if(g.jsExtRegExp.test(a))d=a+(b||"");else{d=j.paths;a=a.split("/");for(e=a.length;0<e;e-=1)if(h=a.slice(0,
29
+ e).join("/"),h=m(d,h)){H(h)&&(h=h[0]);a.splice(0,e,h);break}d=a.join("/");d+=b||(/^data\:|\?/.test(d)||c?"":".js");d=("/"===d.charAt(0)||d.match(/^[\w\+\.\-]+:/)?"":j.baseUrl)+d}return j.urlArgs?d+((-1===d.indexOf("?")?"?":"&")+j.urlArgs):d},load:function(a,b){g.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ja.test((a.currentTarget||a.srcElement).readyState))N=null,a=I(a),i.completeLoad(a.id)},onScriptError:function(a){var b=I(a);if(!e(b.id))return w(C("scripterror",
30
+ "Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var g,x,y,D,I,E,N,J,s,O,ka=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,la=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,Q=/\.js$/,ia=/^\.\//;x=Object.prototype;var K=x.toString,fa=x.hasOwnProperty,ha=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),ea=!z&&"undefined"!==typeof importScripts,ja=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,
31
+ Y="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},q={},R=[],M=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;q=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(q=require,require=void 0);g=requirejs=function(b,c,d,e){var n,p="_";!H(b)&&"string"!==typeof b&&(n=b,H(c)?(b=c,c=d,d=e):b=[]);n&&n.context&&(p=n.context);(e=m(F,p))||(e=F[p]=g.s.newContext(p));n&&e.configure(n);return e.require(b,c,d)};g.config=function(b){return g(b)};
32
+ g.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=g);g.version="2.1.15";g.jsExtRegExp=/^\/|:|\?|\.js$/;g.isBrowser=z;x=g.s={contexts:F,newContext:ga};g({});v(["toUrl","undef","defined","specified"],function(b){g[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;g.onError=ca;g.createNode=function(b){var c=
33
+ b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};g.load=function(b,c,d){var e=b&&b.config||{};if(z)return e=g.createNode(e,c,d),e.setAttribute("data-requirecontext",b.contextName),e.setAttribute("data-requiremodule",c),e.attachEvent&&!(e.attachEvent.toString&&0>e.attachEvent.toString().indexOf("[native code"))&&!Y?(M=!0,e.attachEvent("onreadystatechange",b.onScriptLoad)):
34
+ (e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)),e.src=d,J=e,D?y.insertBefore(e,D):y.appendChild(e),J=null,e;if(ea)try{importScripts(d),b.completeLoad(c)}catch(m){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,m,[c]))}};z&&!q.skipDataMain&&T(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(I=b.getAttribute("data-main"))return s=I,q.baseUrl||(E=s.split("/"),s=E.pop(),O=E.length?E.join("/")+"/":"./",q.baseUrl=
35
+ O),s=s.replace(Q,""),g.jsExtRegExp.test(s)&&(s=I),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var e,g;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(ka,"").replace(la,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(M){if(!(e=J))N&&"interactive"===N.readyState||T(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return N=b}),e=N;e&&(b||
36
+ (b=e.getAttribute("data-requiremodule")),g=F[e.getAttribute("data-requirecontext")])}(g?g.defQueue:R).push([b,c,d])};define.amd={jQuery:!0};g.exec=function(b){return eval(b)};g(q)}})(this);
data/apidoc.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "WhiteFuse Node API",
3
+ "version": "0.8.0",
4
+ "description": "Virtualization node RESTful API documentation",
5
+ "url" : "https://mynode.local:1357/v1",
6
+ "header": {
7
+ "filename": "_docs/rest/header.md"
8
+ },
9
+ "order": [
10
+ "GetContainers",
11
+ "GetContainer",
12
+ "CreateContainer",
13
+ "DeleteContainer",
14
+ "StartContainer",
15
+ "StopContainer",
16
+ "KillContainer",
17
+ "NodeInfo"
18
+ ],
19
+ "template": {
20
+ "withCompare": true,
21
+ "withGenerator": true
22
+ }
23
+ }
data/bin/wf_node_api ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/ruby
2
+ =begin
3
+ __ ___ _ _ _____ ____ __ __
4
+ \ \ / / |__ (_) |_ ___| ___| _ ___ ___ / ___| \/ |
5
+ \ \ /\ / /| '_ \| | __/ _ \ |_ | | | / __|/ _ \ | | |\/| |
6
+ \ V V / | | | | | || __/ _|| |_| \__ \ __/ |___| | | |
7
+ \_/\_/ |_| |_|_|\__\___|_| \__,_|___/\___|\____|_| |_|
8
+ Container Manager
9
+
10
+ Copyright (C) 2015 David Prandzioch <kontakt@davidprandzioch.de>
11
+
12
+ This program is free software; you can redistribute it and/or
13
+ modify it under the terms of the GNU General Public License
14
+ as published by the Free Software Foundation; either version 2
15
+ of the License, or (at your option) any later version.
16
+
17
+ This program is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with this program; if not, write to the Free Software
24
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25
+ =end
26
+
27
+ THIS_FILE = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
28
+ THIS_PATH = "#{File.dirname(THIS_FILE)}/../"
29
+ require File.join(THIS_PATH, 'lib/wf_node_api.rb')
30
+
31
+ config_template = File.read(File.join(THIS_PATH, 'lib/wf_node_api/config/config_template.erb'))
32
+
33
+ if Process.uid != 0
34
+ raise 'wf_node_api must be started as root user'
35
+ end
36
+
37
+ # @todo bsd: /usr/local/etc/wf_node_api.conf
38
+ config_path = '/etc/wf_node_api.conf'
39
+
40
+ if false == File.exists?(config_path)
41
+ puts 'No config file exists. Trying to create...'
42
+
43
+ @api_token = SecureRandom.uuid
44
+
45
+ tpl = ERB.new(config_template)
46
+ File.write(config_path, tpl.result(binding()))
47
+
48
+ puts "Configuration has been written to #{config_path}"
49
+ puts "You can now execute 'wf_node_api start' to run in daemon mode."
50
+
51
+ exit 0
52
+ end
53
+
54
+ load config_path
55
+ ConfigCheck.run
56
+
57
+ $logger = Logger.new($log_file)
58
+ $logger.level = $log_level
59
+
60
+ if ARGV[0] == "check"
61
+ ContainerManager.new($container_type).check
62
+ exit 0
63
+ end
64
+
65
+ if ARGV.empty?
66
+ webrick_options = {
67
+ :Host => $http_bind_addr,
68
+ :Port => 1357,
69
+ :Logger => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
70
+ :SSLEnable => true,
71
+ :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
72
+ :SSLCertName => [ [ 'CN', WEBrick::Utils::getservername ] ],
73
+ :RequestTimeout => 600
74
+ }
75
+
76
+ Rack::Handler::WEBrick.run Api::NodeApi, webrick_options
77
+ exit 0
78
+ else
79
+ Daemons.run(__FILE__)
80
+ end
@@ -0,0 +1,360 @@
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 Api
27
+ class NodeApi < Grape::API
28
+ format :json
29
+ version 'v1'
30
+
31
+ =begin
32
+ @apiDefine NotFoundError
33
+ @apiError (Not Found 404) error Object was not found
34
+
35
+ @apiErrorExample 404 Not Found
36
+ HTTP/1.1 404 Not Found
37
+ {
38
+ "error": "Not Found"
39
+ }
40
+ =end
41
+
42
+ =begin
43
+ @apiDefine ArgumentError
44
+ @apiError (Bad Request 400) error Invalid arguments supplied
45
+
46
+ @apiErrorExample 400 Bad Request
47
+ HTTP/1.1 400 Bad Request
48
+ {
49
+ "error": "The supplied container name is invalid"
50
+ }
51
+ =end
52
+
53
+ =begin
54
+ @apiDefine UnauthorizedError
55
+ @apiError (Unauthorized 401) error No valid API token was supplied
56
+
57
+ @apiErrorExample 401 Unauthorized
58
+ HTTP/1.1 401 Unauthorized
59
+ {
60
+ "error": "Unauthorized"
61
+ }
62
+ =end
63
+ before do
64
+ error!('Unauthorized', 401) unless headers['X-Api-Token'] == $api_token
65
+
66
+ @man = ContainerManager.new($container_type)
67
+ @resman = ResourceManager.new('linux')
68
+ end
69
+
70
+ =begin
71
+ @apiDefine InternalError
72
+ @apiError (Internal Server Error 500) error The process could not be requested due to an internal error
73
+
74
+ @apiErrorExample 500 Internal Server Error
75
+ HTTP/1.1 500 Internal Server Error
76
+ {
77
+ "error": "Unknown error occured"
78
+ }
79
+ =end
80
+ rescue_from :all do |e|
81
+ error_response(message: e.message, status: 500)
82
+ end
83
+
84
+ get '/' do
85
+ {}
86
+ end
87
+
88
+ =begin
89
+ @api {get} /info Request node information
90
+ @apiVersion 1.0.0
91
+ @apiName NodeInfo
92
+ @apiGroup Node
93
+
94
+ @apiDescription Returns an array containing useful information about the node itself
95
+ and the resources available on it.
96
+
97
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
98
+
99
+ @apiSuccess {String} container_type The configured container type (lxc or vserver)
100
+ @apiSuccess {String} hostname The hostname of the system
101
+ @apiSuccess {String} api_version The version number of the node api
102
+ @apiSuccess {Integer} total_cpu_cores The number of cpu cores available totally
103
+ @apiSuccess {Integer} free_cpu_cores The number of free cpu cores
104
+
105
+ @apiUse UnauthorizedError
106
+
107
+ @apiUse InternalError
108
+ =end
109
+ get '/info' do
110
+ info = {}
111
+
112
+ info['container_type'] = $container_type
113
+ info['hostname'] = `#{$cmd_hostname}`.strip
114
+ info['api_version'] = WfNodeApi::VERSION
115
+ info['total_cpu_cores'] = @resman.total_cpu_cores
116
+ info['free_cpu_cores'] = @man.free_cpu_core_count(@resman)
117
+
118
+ info
119
+ end
120
+
121
+ =begin
122
+ @api {get} /containers Request container list
123
+ @apiVersion 1.0.0
124
+ @apiName GetContainers
125
+ @apiGroup Container
126
+
127
+ @apiDescription Returns an array of containers which are available on the node.
128
+
129
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
130
+
131
+ @apiSuccess {Object[]} containers List of available containers
132
+ @apiSuccess {String} containers.name Name of the container
133
+ @apiSuccess {String} containers.state State of the container (either 'RUNNING' or 'STOPPED')
134
+ @apiSuccess {String} containers.ip_address IP address assigned to the container
135
+ @apiSuccess {Integer} containers.cpu_cores Number of Vcores
136
+ @apiSuccess {Integer} containers.memory_limit_bytes Memory limit in bytes
137
+ @apiSuccess {Integer} containers.memory_usage_bytes Current amount of memory usage in bytes
138
+ @apiSuccess {Integer} containers.disk_space_gb Available disk space in GB
139
+ @apiSuccess {Integer} containers.disk_usage_gb Current amount of disk usage in GB
140
+ @apiSuccess {String} containers.container_type Container type, could be either 'lxc' or 'vserver'
141
+
142
+ @apiUse UnauthorizedError
143
+
144
+
145
+ @apiUse InternalError
146
+ =end
147
+ get '/containers' do
148
+ @man.containers
149
+ end
150
+
151
+ =begin
152
+ @api {post} /containers Create a container
153
+ @apiVersion 1.0.0
154
+ @apiName CreateContainer
155
+ @apiGroup Container
156
+
157
+ @apiDescription Creates a container. Returns 201 on success!
158
+
159
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
160
+
161
+ @apiParam {String} name Name of the container (must be unique per node)
162
+ @apiParam {String} ip_address Valid IPv4 address
163
+ @apiParam {Integer} disk_size_gb Container disk size in GB
164
+ @apiParam {Integer} memory_limit_mb Memory limt in MB
165
+ @apiParam {Integer} cpu_core_count Amount of Vcores assigned to the container
166
+
167
+ @apiSuccess {String} success Success message
168
+ @apiSuccess {String} output STDOUT from container creation
169
+
170
+ @apiUse UnauthorizedError
171
+ @apiUse ArgumentError
172
+ @apiUse InternalError
173
+ =end
174
+ params do
175
+ requires :name, type: String
176
+ requires :ip_address, type: String
177
+ requires :disk_size_gb, type: Integer
178
+ requires :memory_limit_mb, type: Integer
179
+ requires :cpu_core_count, type: Integer
180
+ end
181
+ post '/containers' do
182
+ begin
183
+ res = @man.create_container(params[:name],
184
+ params[:ip_address],
185
+ params[:disk_size_gb],
186
+ params[:memory_limit_mb],
187
+ params[:cpu_core_count]
188
+ )
189
+
190
+ return { success: 'container was created', output: res }
191
+ rescue ArgumentError => e
192
+ error!(e.message, 400)
193
+ rescue ::NotFoundError => e
194
+ error!('Not Found', 404)
195
+ end
196
+ end
197
+
198
+ =begin
199
+ @api {get} /containers/:name Request container by its name
200
+ @apiVersion 1.0.0
201
+ @apiName GetContainer
202
+ @apiGroup Container
203
+
204
+ @apiDescription Returns information on a specific container
205
+
206
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
207
+
208
+ @apiParam {String} name Unique name of the container
209
+
210
+ @apiSuccess {String} name Name of the container
211
+ @apiSuccess {String} state State of the container (either 'RUNNING' or 'STOPPED')
212
+ @apiSuccess {String} ip_address IP address assigned to the container
213
+ @apiSuccess {Integer} cpu_cores Number of Vcores
214
+ @apiSuccess {Integer} memory_limit_bytes Memory limit in bytes
215
+ @apiSuccess {Integer} memory_usage_bytes Current amount of memory usage in bytes
216
+ @apiSuccess {Integer} disk_space_gb Available disk space in GB
217
+ @apiSuccess {Integer} disk_usage_gb Current amount of disk usage in GB
218
+ @apiSuccess {String} container_type Container type, could be either 'lxc' or 'vserver'
219
+
220
+ @apiUse UnauthorizedError
221
+ @apiUse InternalError
222
+ @apiUse NotFoundError
223
+ =end
224
+ params do
225
+ requires :name, type: String
226
+ end
227
+ get '/containers/:name' do
228
+ begin
229
+ return @man.container(params[:name])
230
+ rescue ::NotFoundError => e
231
+ error!('Not Found', 404)
232
+ end
233
+ end
234
+
235
+ =begin
236
+ @api {put} /containers/:name/start Start a container
237
+ @apiVersion 1.0.0
238
+ @apiName StartContainer
239
+ @apiGroup Container
240
+
241
+ @apiDescription Starts a container if it exists
242
+
243
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
244
+
245
+ @apiParam {String} name Unique name of the container
246
+
247
+ @apiSuccess {String} success Success message
248
+ @apiSuccess {String} output STDOUT from container start
249
+
250
+ @apiUse UnauthorizedError
251
+ @apiUse NotFoundError
252
+ @apiUse InternalError
253
+ =end
254
+ params do
255
+ requires :name, type: String
256
+ end
257
+ put '/containers/:name/start' do
258
+ begin
259
+ res = @man.start(params[:name])
260
+ return { success: 'container has been started', output: res }
261
+ rescue ::NotFoundError => e
262
+ error!('Not Found', 404)
263
+ end
264
+ end
265
+
266
+ =begin
267
+ @api {put} /containers/:name/stop Stop a container
268
+ @apiVersion 1.0.0
269
+ @apiName StopContainer
270
+ @apiGroup Container
271
+
272
+ @apiDescription Stops a container if it exists
273
+
274
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
275
+
276
+ @apiParam {String} name Unique name of the container
277
+
278
+ @apiSuccess {String} success Success message
279
+ @apiSuccess {String} output STDOUT from container stop
280
+
281
+ @apiUse UnauthorizedError
282
+ @apiUse NotFoundError
283
+ @apiUse InternalError
284
+ =end
285
+ params do
286
+ requires :name, type: String
287
+ end
288
+ put '/containers/:name/stop' do
289
+ begin
290
+ res = @man.stop(params[:name])
291
+ return { success: 'container has been stopped', output: res }
292
+ rescue ::NotFoundError => e
293
+ error!('Not Found', 404)
294
+ end
295
+ end
296
+
297
+ =begin
298
+ @api {put} /containers/:name/kill Kill a container
299
+ @apiVersion 1.0.0
300
+ @apiName KillContainer
301
+ @apiGroup Container
302
+
303
+ @apiDescription Kills a container if it exists. Does essentially the same as StopContainer
304
+ but forces the container to shut down and does not care about processes running on it.
305
+
306
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
307
+
308
+ @apiParam {String} name Unique name of the container
309
+
310
+ @apiSuccess {String} success Success message
311
+ @apiSuccess {String} output STDOUT from container kill
312
+
313
+ @apiUse UnauthorizedError
314
+ @apiUse NotFoundError
315
+ @apiUse InternalError
316
+ =end
317
+ params do
318
+ requires :name, type: String
319
+ end
320
+ put '/containers/:name/kill' do
321
+ begin
322
+ res = @man.kill(params[:name])
323
+ return { success: 'container has been killed', output: res }
324
+ rescue ::NotFoundError => e
325
+ error('Not Found', 404)
326
+ end
327
+ end
328
+
329
+ =begin
330
+ @api {delete} /containers/:name Delete a container
331
+ @apiVersion 1.0.0
332
+ @apiName DeleteContainer
333
+ @apiGroup Container
334
+
335
+ @apiDescription Deletes a container if it exists.
336
+
337
+ @apiHeader {String} X-Api-Token API token (from /etc/wf_node_api.conf)
338
+
339
+ @apiParam {String} name Unique name of the container
340
+
341
+ @apiSuccess {String} success Success message
342
+ @apiSuccess {String} output STDOUT from container deletion
343
+
344
+ @apiUse UnauthorizedError
345
+ @apiUse NotFoundError
346
+ @apiUse InternalError
347
+ =end
348
+ params do
349
+ requires :name, type: String
350
+ end
351
+ delete '/containers/:name' do
352
+ begin
353
+ res = @man.delete(params[:name])
354
+ return { success: 'container has been deleted', output: res }
355
+ rescue ::NotFoundError => e
356
+ error!('Not Found', 404)
357
+ end
358
+ end
359
+ end
360
+ end
@@ -0,0 +1,50 @@
1
+ # bind address for the rest api
2
+ $http_bind_addr = '0.0.0.0'
3
+
4
+ # ssl cert path - not working right now
5
+ $ssl_crt_path = ''
6
+ $ssl_key_path = ''
7
+
8
+ $api_token = '<%= @api_token %>'
9
+
10
+ $log_file = '/var/log/wf_node_api.log'
11
+ $log_level = Logger::INFO
12
+
13
+ # container name
14
+ # possible values: lxc, vserver, ezjail
15
+ $container_type = 'lxc'
16
+
17
+ # command for getting the hostname
18
+ $cmd_hostname = 'hostname'
19
+
20
+ $lxc_container_config_path = '/var/lib/lxc/[name]/config'
21
+ $lxc_ip_netmask = 24
22
+
23
+
24
+ $lxc_cgroup_mount_path = '/sys/fs/cgroup'
25
+
26
+ # lxc specific commands
27
+ $lxc_cmd_ls = 'lxc-ls'
28
+ $lxc_cmd_start = 'lxc-start -n [name] -d'
29
+ # dont set the timeout too high (broken pipes)
30
+ $lxc_cmd_stop = 'lxc-stop -n [name] --timeout=15'
31
+ $lxc_cmd_kill = 'lxc-stop -n [name] -k'
32
+ $lxc_cmd_info = 'lxc-info -n [name] -H'
33
+ $lxc_cmd_destroy = 'lxc-destroy -n [name] -f'
34
+ $lxc_cmd_create = 'lxc-create -t centos -n [name]'
35
+
36
+
37
+ # linux-vserver specific commands
38
+ $vserver_cmd_ls = 'ls -1 /etc/vservers'
39
+ $vserver_cmd_start = 'vserver [name] start'
40
+ $vserver_cmd_stop = 'vserver [name] stop'
41
+ $vserver_cmd_stat = 'vserver-stat | grep [name]$'
42
+ $vserver_cmd_destroy = "echo 'y' | vserver [name] delete"
43
+ #$vserver_cmd_create = "vserver [name] build -m clone --context [context] --hostname [name] --interface eth0:[ip_address]/24 -- --source /vservers/test"
44
+ $vserver_cmd_create = "vserver [name] build -m debootstrap --context [context] --hostname [name] --interface eth0:[ip_address]/24 -- -d wheezy -m http://ftp.de.debian.org/debian"
45
+
46
+ $vserver_cmd_get_memory_limit = 'vlimit -c [context] -a -d | grep RSS'
47
+
48
+ $vserver_config_dir = '/etc/vservers/[name]'
49
+
50
+ $page_size_cmd = 'getconf PAGESIZE'