Skip to content

Instantly share code, notes, and snippets.

@jt0dd
Created April 8, 2024 17:23
Show Gist options
  • Save jt0dd/cee5117a2dc58bdb851d488c05a44049 to your computer and use it in GitHub Desktop.
Save jt0dd/cee5117a2dc58bdb851d488c05a44049 to your computer and use it in GitHub Desktop.
async function executeCommands(ssh, commands) {
let commandOutput = ''; // Collect command output
let currentIndex = 0; // Track the current command index
let outputs = []
// Function to write the next command if available
const writeNextCommand = () => {
if (currentIndex < commands.length) {
console.log('Executing command:', commands[currentIndex], 'of commands', commands);
ssh.shellStream.write(`${commands[currentIndex]}\n`);
currentIndex++;
}
};
ssh.shellStream.on('data', (data) => {
commandOutput += data.toString(); // Append data to command output
const commandOutputLines = commandOutput.split('\n');
const commandOutputLastLine = commandOutputLines.slice(-1);
console.log('commandOutput', '(', commandOutputLines.length, ')', commandOutputLines.slice(-3));
console.log('Checking if commandOutputLastLine (', commandOutputLastLine, ') includes termination strings...')
if ((commandOutputLastLine.includes("$ ") || commandOutputLastLine.includes("# "))) {
console.log('Command completion detected.');
if (currentIndex < commands.length) {
// A new command prompt detected, execute next command
console.log('Moving to next command...');
writeNextCommand();
} else {
console.log('Commands complete...');
return outputs;
}
} else {
// Check if the output meets the success criteria defined by the regex
console.log('Output not complete, pushing to outputs buffer...');
outputs.push(commandOutput);
}
});
ssh.shellStream.stderr.on('data', (data) => {
console.error('STDERR: ', data.toString());
throw new Error(data.toString())
});
// Start executing the first command
writeNextCommand();
}
async function pollSSHInstallStatus(ip, port, username, sshKeyPath) {
const maxAttempts = 500; // Maximum number of attempts for the checks
const delayBetweenAttempts = 10000; // Delay between attempts in milliseconds
let attempt = 1;
while (attempt <= maxAttempts) {
try {
// Connect to the server
await ssh.connect({
host: ip,
port: port,
username: username,
privateKeyPath: sshKeyPath
});
// Request a shell session and store it in the ssh object for reuse
ssh.shellStream = await ssh.requestShell();
// Execute the 'ludus-install-status' command and wait for the success criteria to be met
const commands = [
"sudo su root", // Switch to root
"whoami", // Confirm current user
"ludus-install-status" // Then check ludus install status
];
const successRegex = /Ludus install completed successfully\nRoot API key: (ROOT\.[\w+@]+)$/;
const results = await executeCommands(ssh, commands);
console.log('Got', results.length, 'command results:', results)
if (results.length > 0) {
console.log('results', results);
for (let i = 0; i < results.length; i++) {
const result = results[i];
console.log('Comparing:\n', result, "to:\n", successRegex);
const match = result.match(successRegex);
if (match && match[1]) {
// Extracted Root API Key
const rootApiKey = match[1];
console.log('Ludus install completed successfully. Root API key:', rootApiKey);
return rootApiKey;
}
}
}
await new Promise(resolve => setTimeout(resolve, delayBetweenAttempts));
attempt++;
} catch (error) {
console.error(`Attempt ${attempt}: `, error.message);
// Wait for a bit before the next attempt
await new Promise(resolve => setTimeout(resolve, delayBetweenAttempts));
attempt++;
}
}
if (attempt > maxAttempts) {
console.error('Exceeded maximum number of attempts');
}
ssh.shellStream.end(); // Close the shell stream
ssh.dispose(); // Dispose of the SSH connection properly
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment