docker-socket-handler.ts 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. import { SocketHandler } from "../socket-handler.js";
  2. import { DockgeServer } from "../dockge-server";
  3. import { callbackError, checkLogin, DockgeSocket, ValidationError } from "../util-server";
  4. import { Stack } from "../stack";
  5. // @ts-ignore
  6. import composerize from "composerize";
  7. export class DockerSocketHandler extends SocketHandler {
  8. create(socket : DockgeSocket, server : DockgeServer) {
  9. socket.on("deployStack", async (name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown, callback) => {
  10. try {
  11. checkLogin(socket);
  12. const stack = await this.saveStack(socket, server, name, composeYAML, composeENV, isAdd);
  13. await stack.deploy(socket);
  14. server.sendStackList();
  15. callback({
  16. ok: true,
  17. msg: "Deployed",
  18. });
  19. stack.joinCombinedTerminal(socket);
  20. } catch (e) {
  21. callbackError(e, callback);
  22. }
  23. });
  24. socket.on("saveStack", async (name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown, callback) => {
  25. try {
  26. checkLogin(socket);
  27. this.saveStack(socket, server, name, composeYAML, composeENV, isAdd);
  28. callback({
  29. ok: true,
  30. "msg": "Saved"
  31. });
  32. server.sendStackList();
  33. } catch (e) {
  34. callbackError(e, callback);
  35. }
  36. });
  37. socket.on("deleteStack", async (name : unknown, callback) => {
  38. try {
  39. checkLogin(socket);
  40. if (typeof(name) !== "string") {
  41. throw new ValidationError("Name must be a string");
  42. }
  43. const stack = await Stack.getStack(server, name);
  44. try {
  45. await stack.delete(socket);
  46. } catch (e) {
  47. server.sendStackList();
  48. throw e;
  49. }
  50. server.sendStackList();
  51. callback({
  52. ok: true,
  53. msg: "Deleted"
  54. });
  55. } catch (e) {
  56. callbackError(e, callback);
  57. }
  58. });
  59. socket.on("getStack", async (stackName : unknown, callback) => {
  60. try {
  61. checkLogin(socket);
  62. if (typeof(stackName) !== "string") {
  63. throw new ValidationError("Stack name must be a string");
  64. }
  65. const stack = await Stack.getStack(server, stackName);
  66. if (stack.isManagedByDockge) {
  67. stack.joinCombinedTerminal(socket);
  68. }
  69. callback({
  70. ok: true,
  71. stack: stack.toJSON(),
  72. });
  73. } catch (e) {
  74. callbackError(e, callback);
  75. }
  76. });
  77. // requestStackList
  78. socket.on("requestStackList", async (callback) => {
  79. try {
  80. checkLogin(socket);
  81. server.sendStackList();
  82. callback({
  83. ok: true,
  84. msg: "Updated"
  85. });
  86. } catch (e) {
  87. callbackError(e, callback);
  88. }
  89. });
  90. // startStack
  91. socket.on("startStack", async (stackName : unknown, callback) => {
  92. try {
  93. checkLogin(socket);
  94. if (typeof(stackName) !== "string") {
  95. throw new ValidationError("Stack name must be a string");
  96. }
  97. const stack = await Stack.getStack(server, stackName);
  98. await stack.start(socket);
  99. callback({
  100. ok: true,
  101. msg: "Started"
  102. });
  103. server.sendStackList();
  104. stack.joinCombinedTerminal(socket);
  105. } catch (e) {
  106. callbackError(e, callback);
  107. }
  108. });
  109. // stopStack
  110. socket.on("stopStack", async (stackName : unknown, callback) => {
  111. try {
  112. checkLogin(socket);
  113. if (typeof(stackName) !== "string") {
  114. throw new ValidationError("Stack name must be a string");
  115. }
  116. const stack = await Stack.getStack(server, stackName);
  117. await stack.stop(socket);
  118. callback({
  119. ok: true,
  120. msg: "Stopped"
  121. });
  122. server.sendStackList();
  123. } catch (e) {
  124. callbackError(e, callback);
  125. }
  126. });
  127. // restartStack
  128. socket.on("restartStack", async (stackName : unknown, callback) => {
  129. try {
  130. checkLogin(socket);
  131. if (typeof(stackName) !== "string") {
  132. throw new ValidationError("Stack name must be a string");
  133. }
  134. const stack = await Stack.getStack(server, stackName);
  135. await stack.restart(socket);
  136. callback({
  137. ok: true,
  138. msg: "Restarted"
  139. });
  140. server.sendStackList();
  141. } catch (e) {
  142. callbackError(e, callback);
  143. }
  144. });
  145. // updateStack
  146. socket.on("updateStack", async (stackName : unknown, callback) => {
  147. try {
  148. checkLogin(socket);
  149. if (typeof(stackName) !== "string") {
  150. throw new ValidationError("Stack name must be a string");
  151. }
  152. const stack = await Stack.getStack(server, stackName);
  153. await stack.update(socket);
  154. callback({
  155. ok: true,
  156. msg: "Updated"
  157. });
  158. server.sendStackList();
  159. } catch (e) {
  160. callbackError(e, callback);
  161. }
  162. });
  163. // down stack
  164. socket.on("downStack", async (stackName : unknown, callback) => {
  165. try {
  166. checkLogin(socket);
  167. if (typeof(stackName) !== "string") {
  168. throw new ValidationError("Stack name must be a string");
  169. }
  170. const stack = await Stack.getStack(server, stackName);
  171. await stack.down(socket);
  172. callback({
  173. ok: true,
  174. msg: "Downed"
  175. });
  176. server.sendStackList();
  177. } catch (e) {
  178. callbackError(e, callback);
  179. }
  180. });
  181. // Services status
  182. socket.on("serviceStatusList", async (stackName : unknown, callback) => {
  183. try {
  184. checkLogin(socket);
  185. if (typeof(stackName) !== "string") {
  186. throw new ValidationError("Stack name must be a string");
  187. }
  188. const stack = await Stack.getStack(server, stackName, true);
  189. const serviceStatusList = Object.fromEntries(await stack.getServiceStatusList());
  190. callback({
  191. ok: true,
  192. serviceStatusList,
  193. });
  194. } catch (e) {
  195. callbackError(e, callback);
  196. }
  197. });
  198. // getExternalNetworkList
  199. socket.on("getDockerNetworkList", async (callback) => {
  200. try {
  201. checkLogin(socket);
  202. const dockerNetworkList = server.getDockerNetworkList();
  203. callback({
  204. ok: true,
  205. dockerNetworkList,
  206. });
  207. } catch (e) {
  208. callbackError(e, callback);
  209. }
  210. });
  211. // composerize
  212. socket.on("composerize", async (dockerRunCommand : unknown, callback) => {
  213. try {
  214. checkLogin(socket);
  215. if (typeof(dockerRunCommand) !== "string") {
  216. throw new ValidationError("dockerRunCommand must be a string");
  217. }
  218. const composeTemplate = composerize(dockerRunCommand);
  219. callback({
  220. ok: true,
  221. composeTemplate,
  222. });
  223. } catch (e) {
  224. callbackError(e, callback);
  225. }
  226. });
  227. }
  228. async saveStack(socket : DockgeSocket, server : DockgeServer, name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown) : Promise<Stack> {
  229. // Check types
  230. if (typeof(name) !== "string") {
  231. throw new ValidationError("Name must be a string");
  232. }
  233. if (typeof(composeYAML) !== "string") {
  234. throw new ValidationError("Compose YAML must be a string");
  235. }
  236. if (typeof(composeENV) !== "string") {
  237. throw new ValidationError("Compose ENV must be a string");
  238. }
  239. if (typeof(isAdd) !== "boolean") {
  240. throw new ValidationError("isAdd must be a boolean");
  241. }
  242. const stack = new Stack(server, name, composeYAML, composeENV, false);
  243. await stack.save(isAdd);
  244. return stack;
  245. }
  246. }