import vscode from 'vscode'; import fs from 'fs'; import path from 'path'; import os from 'os'; import QuickAccessTreeProvider from './views/quick-access-tree'; import SIHome from './home'; import * as utils from './utils'; const {NodeSSH} = require('node-ssh') class SuperIDEExtension { constructor() { this.siHome = undefined; this.context = undefined; this.subscriptions = []; } async activate(context) { this.context = context; this.siHome = new SIHome(context); this.subscriptions.push( vscode.window.registerTreeDataProvider( 'superide.quickAccess', new QuickAccessTreeProvider() ) ); this.registerGlobalCommands(); this.startSuperIDEHome(); } async startSuperIDEHome() { vscode.commands.executeCommand('superide.showHome'); } // TODO: finish firstConnect (automatically) async connectRemoteContainer() { const host = 'mengning.com.cn'; const username = 'linux'; const password = 'a7%Xs&&TXG'; const port = 31874; console.log('Connecting to remote container...'); // detect if local ssh config has the host registered // TODO: use remote.SSH.configFile const sshConfigPath = path.join(os.homedir(), '.ssh', 'config'); if (fs.existsSync(sshConfigPath)) { const config = fs.readFileSync(sshConfigPath, 'utf8'); // TODO: more robust regex if (config.includes(host)) { console.log('Host already registered in local ssh config'); // TODO: connect the specified folder } else { // the host has not been registered in the local ssh config // connect the host and add the public key to the remote authorized_keys const defaultPublicKeyPath = path.join(os.homedir(), '.ssh', 'id_rsa.pub'); // TODO: if there is no public key, generate one const publicKey = fs.readFileSync(defaultPublicKeyPath, 'utf8'); await this.firstConnect( host, username, password, port, publicKey ) // append the host to the local ssh config file const sshConfigContent = `\n Host ${host} HostName ${host} Port ${port} User ${username} PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa `; // append the host to the local ssh config file fs.writeFileSync(sshConfigPath, sshConfigContent, { encoding: 'utf8', flag: 'a' }); console.log('Host registered in local ssh config'); // connect the host with remote-ssh extension await vscode.commands.executeCommand('opensshremotes.openEmptyWindowInCurrentWindow', host) .then(() => { console.log('Connected to host'); }) .catch((error) => { console.error('Error connecting to host: ', error); }); } } } async firstConnect(host, username, password, port, publicKey) { const ssh = new NodeSSH(); ssh.connect({ host: host, username: username, password: password, port: port }).then(() => { console.log('Connected successfully'); ssh.execCommand(`mkdir -p ~/.ssh && echo '${publicKey}' >> ~/.ssh/authorized_keys`, ) .then(result => { if (result.stdout) console.log('STDOUT: ' + result.stdout); if (result.stderr) console.log('STDERR: ' + result.stderr); }); }).catch(error => { console.log('Error: ', error); }); } registerGlobalCommands() { this.subscriptions.push( vscode.commands.registerCommand('superide.showHome', (url) => this.siHome.toggle(url) ), vscode.commands.registerCommand('superide.connectRemoteContainer', () => this.connectRemoteContainer() ) ); } disposeSubscriptions() { utils.disposeSubscriptions(this.subscriptions); } deactivate() { this.disposeSubscriptions(); } } export const extension = new SuperIDEExtension(); export function activate(context) { extension.activate(context); return extension; } export function deactivate() { extension.deactivate(); }