terminal-socket-handler.ts 4.7 KB

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