terminal-socket-handler.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { SocketHandler } from "../socket-handler.js";
  2. import { DockgeServer } from "../dockge-server";
  3. import { callbackError, checkLogin, DockgeSocket, ValidationError } from "../util-server";
  4. import { log } from "../log";
  5. import yaml from "yaml";
  6. import path from "path";
  7. import fs from "fs";
  8. import {
  9. allowedCommandList,
  10. allowedRawKeys,
  11. getComposeTerminalName, getContainerExecTerminalName,
  12. isDev,
  13. PROGRESS_TERMINAL_ROWS
  14. } from "../util-common";
  15. import { InteractiveTerminal, MainTerminal, Terminal } from "../terminal";
  16. import { Stack } from "../stack";
  17. export class TerminalSocketHandler extends SocketHandler {
  18. create(socket : DockgeSocket, server : DockgeServer) {
  19. socket.on("terminalInput", async (terminalName : unknown, cmd : unknown, errorCallback) => {
  20. try {
  21. checkLogin(socket);
  22. if (typeof(terminalName) !== "string") {
  23. throw new Error("Terminal name must be a string.");
  24. }
  25. if (typeof(cmd) !== "string") {
  26. throw new Error("Command must be a string.");
  27. }
  28. let terminal = Terminal.getTerminal(terminalName);
  29. if (terminal instanceof InteractiveTerminal) {
  30. //log.debug("terminalInput", "Terminal found, writing to terminal.");
  31. terminal.write(cmd);
  32. } else {
  33. throw new Error("Terminal not found or it is not a Interactive Terminal.");
  34. }
  35. } catch (e) {
  36. if (e instanceof Error) {
  37. errorCallback({
  38. ok: false,
  39. msg: e.message,
  40. });
  41. }
  42. }
  43. });
  44. // Main Terminal
  45. socket.on("mainTerminal", async (terminalName : unknown, callback) => {
  46. try {
  47. checkLogin(socket);
  48. // TODO: Reset the name here, force one main terminal for now
  49. terminalName = "console";
  50. if (typeof(terminalName) !== "string") {
  51. throw new ValidationError("Terminal name must be a string.");
  52. }
  53. log.debug("deployStack", "Terminal name: " + terminalName);
  54. let terminal = Terminal.getTerminal(terminalName);
  55. if (!terminal) {
  56. terminal = new MainTerminal(server, terminalName);
  57. terminal.rows = 50;
  58. log.debug("deployStack", "Terminal created");
  59. }
  60. terminal.join(socket);
  61. terminal.start();
  62. callback({
  63. ok: true,
  64. });
  65. } catch (e) {
  66. callbackError(e, callback);
  67. }
  68. });
  69. // Interactive Terminal for containers
  70. socket.on("interactiveTerminal", async (stackName : unknown, serviceName : unknown, shell : unknown, callback) => {
  71. try {
  72. checkLogin(socket);
  73. if (typeof(stackName) !== "string") {
  74. throw new ValidationError("Stack name must be a string.");
  75. }
  76. if (typeof(serviceName) !== "string") {
  77. throw new ValidationError("Service name must be a string.");
  78. }
  79. if (typeof(shell) !== "string") {
  80. throw new ValidationError("Shell must be a string.");
  81. }
  82. log.debug("interactiveTerminal", "Stack name: " + stackName);
  83. log.debug("interactiveTerminal", "Service name: " + serviceName);
  84. // Get stack
  85. const stack = Stack.getStack(server, stackName);
  86. stack.joinContainerTerminal(socket, serviceName, shell);
  87. callback({
  88. ok: true,
  89. });
  90. } catch (e) {
  91. callbackError(e, callback);
  92. }
  93. });
  94. // Join Output Terminal
  95. socket.on("terminalJoin", async (terminalName : unknown, callback) => {
  96. if (typeof(callback) !== "function") {
  97. log.debug("console", "Callback is not a function.");
  98. return;
  99. }
  100. try {
  101. checkLogin(socket);
  102. if (typeof(terminalName) !== "string") {
  103. throw new ValidationError("Terminal name must be a string.");
  104. }
  105. let buffer : string = Terminal.getTerminal(terminalName)?.getBuffer() ?? "";
  106. if (!buffer) {
  107. log.debug("console", "No buffer found.");
  108. }
  109. callback({
  110. ok: true,
  111. buffer,
  112. });
  113. } catch (e) {
  114. callbackError(e, callback);
  115. }
  116. });
  117. // Close Terminal
  118. socket.on("terminalClose", async (terminalName : unknown, callback : unknown) => {
  119. });
  120. // TODO: Resize Terminal
  121. socket.on("terminalResize", async (rows : unknown) => {
  122. });
  123. }
  124. }