You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
3.7 KiB
93 lines
3.7 KiB
1 year ago
|
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
||
|
const Docker = require('node-docker-api').Docker;
|
||
|
|
||
|
module.exports = {
|
||
|
data: new SlashCommandBuilder()
|
||
|
.setName("startcontainer")
|
||
|
.setDescription("Starts a Docker container")
|
||
|
.addStringOption(option =>
|
||
|
option.setName('container')
|
||
|
.setDescription('The container to start')
|
||
|
.setRequired(true)
|
||
|
.setAutocomplete(true)),
|
||
|
async autocomplete(interaction) {
|
||
|
try {
|
||
|
// Create docker client
|
||
|
const docker = new Docker({ socketPath: '/var/run/docker.sock' });
|
||
|
|
||
|
// Get list of running containers
|
||
|
const containers = await docker.container.list({ all: true, filters: { status: ['exited'] } });
|
||
|
const runningContainers = containers.map(c => c.data.Names[0].slice(1));
|
||
|
|
||
|
// Filter list of containers by focused value
|
||
|
const focusedValue = interaction.options.getFocused(true);
|
||
|
const filteredContainers = runningContainers.filter(container => container.startsWith(focusedValue.value));
|
||
|
|
||
|
//slice if more than 25
|
||
|
let sliced;
|
||
|
if (filteredContainers.length > 25) {
|
||
|
sliced = filteredContainers.slice(0, 25);
|
||
|
} else {
|
||
|
sliced = filteredContainers;
|
||
|
}
|
||
|
|
||
|
// Respond with filtered list of containers
|
||
|
await interaction.respond(sliced.map(container => ({ name: container, value: container })));
|
||
|
|
||
|
} catch (error) {
|
||
|
// Handle error
|
||
|
console.error(error);
|
||
|
await interaction.reply('An error occurred while getting the list of running containers.');
|
||
|
}
|
||
|
},
|
||
|
async execute(interaction) {
|
||
|
try {
|
||
|
// Get container name from options
|
||
|
const containerName = interaction.options.getString('container');
|
||
|
|
||
|
// Start container in interactive mode
|
||
|
await interaction.reply(`Starting container "${containerName}" in interactive mode...`);
|
||
|
const container = docker.getContainer(containerName);
|
||
|
const info = await container.inspect();
|
||
|
if (!info) {
|
||
|
await interaction.followUp(`Container "${containerName}" does not exist.`);
|
||
|
throw new Error(`Container "${containerName}" does not exist.`);
|
||
|
}
|
||
|
await container.start({
|
||
|
AttachStdin: true,
|
||
|
AttachStdout: true,
|
||
|
AttachStderr: true,
|
||
|
Tty: true,
|
||
|
OpenStdin: true,
|
||
|
StdinOnce: false
|
||
|
});
|
||
|
|
||
|
// Attach to container's streams
|
||
|
const stream = await container.attach({
|
||
|
stream: true,
|
||
|
stdin: true,
|
||
|
stdout: true,
|
||
|
stderr: true
|
||
|
});
|
||
|
|
||
|
// Use socket.io for real-time communication with the container
|
||
|
io.on('connection', (socket) => {
|
||
|
socket.on('containerInput', (data) => {
|
||
|
stream.write(data + '\n'); // Send input to the container
|
||
|
});
|
||
|
|
||
|
stream.on('data', (data) => {
|
||
|
socket.emit('containerOutput', data.toString()); // Send container's output to the client
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// Confirm that container was started
|
||
|
await interaction.followUp(`Container "${containerName}" was successfully started in interactive mode.`);
|
||
|
} catch (error) {
|
||
|
// Handle error
|
||
|
console.error(error);
|
||
|
await interaction.followUp(`An error occurred while trying to start the container "${containerName}" in interactive mode.`);
|
||
|
}
|
||
|
},
|
||
|
};
|