Docker build update

This commit is contained in:
LukeGus
2024-12-07 01:18:52 -06:00
parent a81b4834ce
commit 02acc72bf6
5 changed files with 134 additions and 102 deletions

View File

@@ -8,7 +8,7 @@ on:
tag_name: tag_name:
description: "Custom tag name for the Docker image" description: "Custom tag name for the Docker image"
required: false required: false
default: "development-latest" default: ""
jobs: jobs:
build: build:
@@ -44,10 +44,12 @@ jobs:
- name: Determine Docker image tag - name: Determine Docker image tag
run: | run: |
echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
if [ -n "${{ github.event.inputs.tag_name }}" ]; then if [ "${{ github.event.inputs.tag_name }}" == "" ]; then
IMAGE_TAG="${{ github.event.inputs.tag_name }}" # If the tag_name input is an empty string, default to branch-name-development-latest
IMAGE_TAG="${{ github.ref_name }}-development-latest"
else else
IMAGE_TAG="development-latest" # If tag_name is provided, use it
IMAGE_TAG="${{ github.event.inputs.tag_name }}"
fi fi
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV

69
.idea/workspace.xml generated
View File

@@ -4,10 +4,12 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="8497df64-d86b-4c98-ac58-c157d9d3fb1e" name="Changes" comment="Silent resize cmds &amp; Auto resize terminal #1"> <list default="true" id="8497df64-d86b-4c98-ac58-c157d9d3fb1e" name="Changes" comment="Silent resize cmds &amp; Auto resize terminal #2">
<change beforePath="$PROJECT_DIR$/.github/workflows/docker-image.yml" beforeDir="false" afterPath="$PROJECT_DIR$/.github/workflows/docker-image.yml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/backend/server.js" beforeDir="false" afterPath="$PROJECT_DIR$/backend/server.js" afterDir="false" /> <change beforePath="$PROJECT_DIR$/backend/server.js" beforeDir="false" afterPath="$PROJECT_DIR$/backend/server.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/src/App.jsx" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/App.jsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/frontend/src/App.jsx" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/src/App.jsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/info.txt" beforeDir="false" afterPath="$PROJECT_DIR$/info.txt" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -42,32 +44,32 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;ASKED_SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;, "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;Shell Script.Node Server.js Start.executor&quot;: &quot;Run&quot;, "Shell Script.Node Server.js Start.executor": "Run",
&quot;Shell Script.Run backend and frontend.executor&quot;: &quot;Run&quot;, "Shell Script.Run backend and frontend.executor": "Run",
&quot;Shell Script.run_backend_frontend.executor&quot;: &quot;Run&quot;, "Shell Script.run_backend_frontend.executor": "Run",
&quot;git-widget-placeholder&quot;: &quot;alpha-1.0&quot;, "git-widget-placeholder": "release-1.0",
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;, "ignore.virus.scanning.warn.message": "true",
&quot;last_opened_file_path&quot;: &quot;D:/Programming Projects/SSH-Project-JB&quot;, "last_opened_file_path": "D:/Programming Projects/SSH-Project-JB",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "nodejs_package_manager_path": "npm",
&quot;npm.run_start.executor&quot;: &quot;Run&quot;, "npm.run_start.executor": "Run",
&quot;npm.run_start_frontend.executor&quot;: &quot;Run&quot;, "npm.run_start_frontend.executor": "Run",
&quot;npm.run_start_node_backend.executor&quot;: &quot;Run&quot;, "npm.run_start_node_backend.executor": "Run",
&quot;npm.run_start_vite.executor&quot;: &quot;Run&quot;, "npm.run_start_vite.executor": "Run",
&quot;npm.start.executor&quot;: &quot;Run&quot;, "npm.start.executor": "Run",
&quot;settings.editor.selected.configurable&quot;: &quot;ml.llm.LLMConfigurable&quot;, "settings.editor.selected.configurable": "ml.llm.LLMConfigurable",
&quot;ts.external.directory.path&quot;: &quot;D:\\Program Files (x86)\\Applications\\Jetbrains Webstorm\\WebStorm 2024.3.1\\plugins\\javascript-plugin\\jsLanguageServicesImpl\\external&quot;, "ts.external.directory.path": "D:\\Program Files (x86)\\Applications\\Jetbrains Webstorm\\WebStorm 2024.3.1\\plugins\\javascript-plugin\\jsLanguageServicesImpl\\external",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "vue.rearranger.settings.migration": "true"
} }
}</component> }]]></component>
<component name="RunManager" selected="Shell Script.run_backend_frontend"> <component name="RunManager" selected="Shell Script.run_backend_frontend">
<configuration name="run_backend_frontend" type="ShConfigurationType"> <configuration name="run_backend_frontend" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="Start-Process &quot;powershell&quot; -ArgumentList &quot;-NoProfile&quot;, &quot;-Command npm run start-vite&quot;; Start-Process &quot;powershell&quot; -ArgumentList &quot;-NoProfile&quot;, &quot;-Command npm run start-server&quot; " /> <option name="SCRIPT_TEXT" value="Start-Process &quot;powershell&quot; -ArgumentList &quot;-NoProfile&quot;, &quot;-Command npm run start-vite&quot;; Start-Process &quot;powershell&quot; -ArgumentList &quot;-NoProfile&quot;, &quot;-Command npm run start-server&quot; " />
@@ -116,7 +118,7 @@
<updated>1733439468142</updated> <updated>1733439468142</updated>
<workItem from="1733439479708" duration="5489000" /> <workItem from="1733439479708" duration="5489000" />
<workItem from="1733448523969" duration="3535000" /> <workItem from="1733448523969" duration="3535000" />
<workItem from="1733549186397" duration="3810000" /> <workItem from="1733549186397" duration="5748000" />
</task> </task>
<task id="LOCAL-00001" summary="Nano zoom fix #11"> <task id="LOCAL-00001" summary="Nano zoom fix #11">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -214,7 +216,15 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1733553128900</updated> <updated>1733553128900</updated>
</task> </task>
<option name="localTasksCounter" value="13" /> <task id="LOCAL-00013" summary="Silent resize cmds &amp; Auto resize terminal #2">
<option name="closed" value="true" />
<created>1733553902375</created>
<option name="number" value="00013" />
<option name="presentableId" value="LOCAL-00013" />
<option name="project" value="LOCAL" />
<updated>1733553902375</updated>
</task>
<option name="localTasksCounter" value="14" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -252,6 +262,7 @@
<MESSAGE value="Terminal size fix #18 (rows &amp; cols fix)" /> <MESSAGE value="Terminal size fix #18 (rows &amp; cols fix)" />
<MESSAGE value="Test ntfy build notification system" /> <MESSAGE value="Test ntfy build notification system" />
<MESSAGE value="Silent resize cmds &amp; Auto resize terminal #1" /> <MESSAGE value="Silent resize cmds &amp; Auto resize terminal #1" />
<option name="LAST_COMMIT_MESSAGE" value="Silent resize cmds &amp; Auto resize terminal #1" /> <MESSAGE value="Silent resize cmds &amp; Auto resize terminal #2" />
<option name="LAST_COMMIT_MESSAGE" value="Silent resize cmds &amp; Auto resize terminal #2" />
</component> </component>
</project> </project>

View File

@@ -15,21 +15,22 @@ const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => { wss.on('connection', (ws) => {
console.log('WebSocket connection established'); console.log('WebSocket connection established');
let conn = null; // Declare SSH client outside to manage lifecycle let conn = null;
let stream = null;
let interval = null;
ws.on('message', (message) => { ws.on('message', (message) => {
try { try {
const data = JSON.parse(message); // Try parsing the incoming message as JSON const data = JSON.parse(message);
// Check if message contains SSH connection details
if (data.host && data.port && data.username && data.password) { if (data.host && data.port && data.username && data.password) {
if (conn) { if (conn) {
conn.end(); // Close any previous connection before starting a new one conn.end();
} }
conn = new ssh2.Client(); // Create a new SSH connection instance conn = new ssh2.Client();
const interval = setInterval(() => { interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) { if (ws.readyState === WebSocket.OPEN) {
ws.ping(); ws.ping();
} else { } else {
@@ -37,78 +38,81 @@ wss.on('connection', (ws) => {
} }
}, 15000); }, 15000);
// When the SSH connection is ready
conn.on('ready', () => { conn.on('ready', () => {
console.log('SSH Connection established'); console.log('SSH Connection established');
conn.shell((err, sshStream) => {
// Start an interactive shell session
conn.shell((err, stream) => {
if (err) { if (err) {
console.log(`SSH Error: ${err}`); console.log(`SSH Error: ${err}`);
ws.send(`Error: ${err}`); ws.send(`Error: ${err}`);
return; return;
} }
// Handle data from SSH session stream = sshStream;
stream.on('data', (data) => {
console.log(`SSH Output: ${data}`); // Send stty commands for resizing rows and columns
ws.send(data.toString()); // Send the SSH output back to WebSocket client const resizeCommand = (rows, cols) => {
return `stty rows ${rows} cols ${cols}\n`;
};
// Adjust terminal size once shell is ready
ws.on('message', (msg) => {
try {
const input = JSON.parse(msg);
if (input.type === 'resize') {
const resizeCmd = resizeCommand(input.rows, input.cols);
stream.write(resizeCmd); // Resize the terminal in SSH
} else {
stream.write(msg); // Regular input handling
}
} catch (e) {
// If it's not JSON, it's a regular key press
stream.write(msg);
}
});
stream.on('data', (data) => {
console.log(`SSH Output: ${data}`);
ws.send(data.toString()); // Send the data back to the client once
}); });
// Handle stream close event
stream.on('close', () => { stream.on('close', () => {
console.log('SSH stream closed'); console.log('SSH stream closed');
conn.end(); conn.end();
}); });
// When the WebSocket client sends a message (from terminal input), forward it to the SSH stream // Send only the resize commands initially without `stty sane`
ws.on('message', (msg) => { const initialResizeCmd = resizeCommand(24, 80); // Example initial size
const input = JSON.parse(msg); stream.write(initialResizeCmd); // Set terminal size
if (input.type === 'resize') {
const resizeCommand = `stty rows ${input.rows} cols ${input.cols}\n`;
stream.write(resizeCommand);
} else {
stream.write(input);
}
});
}); });
}).on('error', (err) => { }).on('error', (err) => {
console.log('SSH Connection Error: ', err); console.log('SSH Connection Error: ', err);
ws.send(`SSH Error: ${err}`); ws.send(`SSH Error: ${err}`);
}).connect({ }).connect({
host: data.host, // Host provided from the client host: data.host,
port: data.port, // Default SSH port port: data.port,
username: data.username, // Username provided from the client username: data.username,
password: data.password, // Password provided from the client password: data.password,
keepaliveInterval: 10000, // Send a heartbeat every 10 seconds keepaliveInterval: 10000,
keepaliveCountMax: 5, // Allow three missed heartbeats before considering the connection dead keepaliveCountMax: 5,
}); });
} }
} catch (error) { } catch (error) {
// If message is not valid JSON (i.e., terminal input), treat it as raw text and send it to SSH console.log('Received non-JSON message: ', message);
console.log('Received non-JSON message, sending to SSH session:', message);
if (conn) {
const stream = conn._stream; // Access the SSH stream directly
if (stream && stream.writable) {
stream.write(message); // Write raw input message to SSH stream
}
} else {
console.error('SSH connection is not established yet.');
}
} }
}); });
// Handle WebSocket close event
ws.on('close', () => { ws.on('close', () => {
console.log('WebSocket closed');
clearInterval(interval);
if (conn) { if (conn) {
conn.end(); // Close SSH connection when WebSocket client disconnects conn.end();
} }
if (interval) {
clearInterval(interval);
}
console.log('WebSocket connection closed');
}); });
}); });
// Start the WebSocket server on port 8081 // Start HTTP server
server.listen(8081, () => { server.listen(8081, () => {
console.log('WebSocket server is listening on ws://localhost:8081'); console.log('WebSocket server listening on ws://localhost:8081');
}); });

View File

@@ -10,7 +10,7 @@ const App = () => {
const fitAddon = useRef(null); const fitAddon = useRef(null);
const socket = useRef(null); const socket = useRef(null);
const [host, setHost] = useState(''); const [host, setHost] = useState('');
const [port, setPort] = useState('22'); const [port, setPort] = useState(22);
const [username, setUsername] = useState(''); const [username, setUsername] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [isConnected, setIsConnected] = useState(false); const [isConnected, setIsConnected] = useState(false);
@@ -27,6 +27,8 @@ const App = () => {
macOptionIsMeta: true, macOptionIsMeta: true,
allowProposedApi: true, allowProposedApi: true,
scrollback: 5000, scrollback: 5000,
// Do not enable local echo
disableStdin: false,
}); });
// Initialize and attach the fit addon to the terminal // Initialize and attach the fit addon to the terminal
@@ -38,12 +40,6 @@ const App = () => {
// Resize terminal to fit the container initially // Resize terminal to fit the container initially
fitAddon.current.fit(); fitAddon.current.fit();
terminal.current.onData((data) => {
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
socket.current.send(data);
}
});
// Adjust terminal size on window resize // Adjust terminal size on window resize
const handleResize = () => { const handleResize = () => {
fitAddon.current.fit(); fitAddon.current.fit();
@@ -73,7 +69,7 @@ const App = () => {
return; return;
} }
socket.current = new WebSocket(wsUrl); socket.current = new WebSocket("ws://localhost:8081");
socket.current.onopen = () => { socket.current.onopen = () => {
terminal.current.writeln(`Connected to WebSocket server at ${wsUrl}`); terminal.current.writeln(`Connected to WebSocket server at ${wsUrl}`);
@@ -91,6 +87,8 @@ const App = () => {
}; };
socket.current.onmessage = (event) => { socket.current.onmessage = (event) => {
// Write the incoming data from WebSocket to the terminal
// This ensures that data coming from the WebSocket server is shown in the terminal
terminal.current.write(event.data); terminal.current.write(event.data);
}; };
@@ -102,10 +100,27 @@ const App = () => {
terminal.current.writeln('Disconnected from WebSocket server.'); terminal.current.writeln('Disconnected from WebSocket server.');
setIsConnected(false); setIsConnected(false);
}; };
// Handle terminal input and send it over WebSocket
terminal.current.onData((data) => {
// Send input data over WebSocket without echoing it back to the terminal
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
socket.current.send(data); // Only send to WebSocket, no echo
}
});
}; };
const handleInputChange = (event, setState) => { const handleInputChange = (event, setState, isNumber = false) => {
setState(event.target.value); let value = event.target.value;
if (isNumber) {
value = Number(value); // Convert to number if it's a number field
if (isNaN(value)) {
value = ''; // Optional: set an empty string if the input is invalid
}
}
setState(value); // Set the state with the appropriate value
}; };
const handleSideBarHiding = () => { const handleSideBarHiding = () => {
@@ -114,7 +129,7 @@ const App = () => {
return ( return (
<div className="app-container"> <div className="app-container">
<div className="main-content"> <div className={`main-content ${isSideBarHidden ? 'with-sidebar-hidden' : ''}`}>
<div className={`sidebar ${isSideBarHidden ? 'hidden' : ''}`}> <div className={`sidebar ${isSideBarHidden ? 'hidden' : ''}`}>
<h2>Connection Details</h2> <h2>Connection Details</h2>
<input <input
@@ -124,10 +139,10 @@ const App = () => {
onChange={(e) => handleInputChange(e, setHost)} onChange={(e) => handleInputChange(e, setHost)}
/> />
<input <input
type="text" type="number"
placeholder="Port" placeholder="Port"
value={port} value={port}
onChange={(e) => handleInputChange(e, setPort)} onChange={(e) => handleInputChange(e, setPort, true)}
/> />
<input <input
type="text" type="text"

View File

@@ -2,7 +2,7 @@ Currently:
make the cmds run at start not show up make the cmds run at start not show up
see if it auto resizes the terminal via cmds after the browser window size has changed or +/- clicked (does not) see if it auto resizes the terminal via cmds after the browser window size has changed or +/- clicked (does not)
before release, call this version 1.0 (don't do beta and shit/come uip with naming scheme like 1.1 or just increment by 1 and when to go to next version) before release, call this version 1.0 (don't do beta and shit/come uip with naming scheme like 1.1 or just increment by 1 and when to go to next version)
fix all the giuthub workflow problems fix all the giuthub workflow problems (fixed I think)
Overall Features: Overall Features:
SSH/RDP(?)/VNC(?) SSH/RDP(?)/VNC(?)