blob: 66e0eceff01711f6ae1e0bdf56b7eebd322b9aef [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as vscode from "vscode";
import * as fs from 'fs';
import { runCommandInTerminal } from "./terminalRunner";
import { COMMAND_PREFIX } from "../extension";
import path = require("path");
import { promisify } from "util";
import * as Handlebars from "handlebars";
interface ConfigFiles {
applicationProperties : string | null;
bootstrapProperties: string | null;
}
const readFile = promisify(fs.readFile);
export class SSHSession {
private readonly username: string;
private readonly host: string;
constructor(username: string, host: string) {
this.username = username;
this.host = host;
}
open(sessionName?: string) {
let terminalName = sessionName || `${this.username}@${this.host}`;
const sshCommand = `ssh ${this.username}@${this.host}`;
runCommandInTerminal(sshCommand, `SSH: ${terminalName}`);
}
async runDocker(context: vscode.ExtensionContext, dockerImage: string, isRepositoryPrivate: boolean) {
const configFiles: ConfigFiles = await vscode.commands.executeCommand(COMMAND_PREFIX + '.config.file.path') as ConfigFiles;
const { applicationProperties, bootstrapProperties } = configFiles;
let bearerTokenFile: string | undefined;
const applicationPropertiesRemotePath = `/home/${this.username}/application.properties`;
const bootstrapPropertiesRemotePath = `/home/${this.username}/bootstrap.properties`;
const bearerTokenRemotePath = `/home/${this.username}/token.txt`;
const applicationPropertiesContainerPath = "/home/app/application.properties";
const bootstrapPropertiesContainerPath = "/home/app/bootstrap.properties";
const ocirServer = dockerImage.split('/')[0];
const remotePathToCopyTo = `/home/${this.username}/`;
let sshCommand = "";
let mountVolume = "";
let micronautConfigFilesEnv = "";
let filesToCopy = "";
let renameFilesCommand = "";
const removeOldFilesCommand = `rm -f ${bootstrapPropertiesRemotePath} ${applicationPropertiesRemotePath} ${bearerTokenRemotePath}`;
if (isRepositoryPrivate) {
bearerTokenFile = await vscode.commands.executeCommand(COMMAND_PREFIX + '.cloud.assets.createBearerToken', ocirServer);
if (bearerTokenFile) {
filesToCopy = bearerTokenFile;
renameFilesCommand = `mv ${remotePathToCopyTo}${path.basename(bearerTokenFile)} ${bearerTokenRemotePath} && `;
}
}
if (bootstrapProperties) {
filesToCopy += ` ${bootstrapProperties}`;
renameFilesCommand += ` mv ${remotePathToCopyTo}${path.basename(bootstrapProperties)} ${bootstrapPropertiesRemotePath} && `;
mountVolume = `-v ${bootstrapPropertiesRemotePath}:${bootstrapPropertiesContainerPath}:Z `;
micronautConfigFilesEnv = `${bootstrapPropertiesContainerPath}`;
}
if (applicationProperties) {
filesToCopy += ` ${applicationProperties}`;
renameFilesCommand += ` mv ${remotePathToCopyTo}${path.basename(applicationProperties)} ${applicationPropertiesRemotePath} && `;
mountVolume += ` -v ${applicationPropertiesRemotePath}:${applicationPropertiesContainerPath}:Z`;
micronautConfigFilesEnv += `${bootstrapProperties ? "," : ""}${applicationPropertiesContainerPath}`;
}
let templateFilePath = path.join(context.extensionPath, "templates", "run-container.sh.handlebars");
const template = await this.getTemplateFromPath(templateFilePath);
const script = template({
username: this.username,
isRepositoryPrivate,
bearerTokenRemotePath,
ocirServer,
dockerImage,
mountVolume,
micronautConfigFilesEnv
});
const tempDir = process.env.TEMP || process.env.TMP || '/tmp';
const scriptName = `run-container-${Date.now()}.sh`;
const runContainerScript = path.join(tempDir, scriptName);
fs.writeFileSync(runContainerScript, script);
renameFilesCommand += ` mv -f ${scriptName} run-container.sh `;
sshCommand = `scp ${filesToCopy} ${runContainerScript} ${this.username}@${this.host}:${remotePathToCopyTo} && `
sshCommand += `ssh ${this.username}@${this.host} "${removeOldFilesCommand} && ${renameFilesCommand} && rm -f ${scriptName} && chmod +x run-container.sh && ./run-container.sh" `
runCommandInTerminal(sshCommand, `Container: ${this.username}@${this.host}`)
}
private async getTemplateFromPath(path: string): Promise<HandlebarsTemplateDelegate<any>> {
const templateFile = await readFile(path, "utf-8");
return Handlebars.compile(templateFile);
}
}