in Tasks/CopyFilesOverSSHV0/copyfilesoverssh.ts [102:248]
async function run() {
let sshHelper: SshHelper;
try {
tl.setResourcePath(path.join(__dirname, 'task.json'));
// read SSH endpoint input
const sshEndpoint = tl.getInput('sshEndpoint', true);
const username: string = tl.getEndpointAuthorizationParameter(sshEndpoint, 'username', false);
const password: string = tl.getEndpointAuthorizationParameter(sshEndpoint, 'password', true); //passphrase is optional
const privateKey: string = process.env['ENDPOINT_DATA_' + sshEndpoint + '_PRIVATEKEY']; //private key is optional, password can be used for connecting
const hostname: string = tl.getEndpointDataParameter(sshEndpoint, 'host', false);
let port: string = tl.getEndpointDataParameter(sshEndpoint, 'port', true); //port is optional, will use 22 as default port if not specified
if (!port) {
console.log(tl.loc('UseDefaultPort'));
port = '22';
}
const readyTimeout = getReadyTimeoutVariable();
const useFastPut: boolean = !(process.env['USE_FAST_PUT'] === 'false');
// set up the SSH connection configuration based on endpoint details
let sshConfig;
if (privateKey) {
tl.debug('Using private key for ssh connection.');
sshConfig = {
host: hostname,
port: port,
username: username,
privateKey: privateKey,
passphrase: password,
readyTimeout: readyTimeout,
useFastPut: useFastPut
}
} else {
// use password
tl.debug('Using username and password for ssh connection.');
sshConfig = {
host: hostname,
port: port,
username: username,
password: password,
readyTimeout: readyTimeout,
useFastPut: useFastPut
}
}
// contents is a multiline input containing glob patterns
const contents: string[] = tl.getDelimitedInput('contents', '\n', true);
const sourceFolder: string = tl.getPathInput('sourceFolder', true, true);
let targetFolder: string = tl.getInput('targetFolder');
if (!targetFolder) {
targetFolder = "./";
} else {
// '~/' is unsupported
targetFolder = targetFolder.replace(/^~\//, "./");
}
// read the copy options
const cleanTargetFolder: boolean = tl.getBoolInput('cleanTargetFolder', false);
const overwrite: boolean = tl.getBoolInput('overwrite', false);
const failOnEmptySource: boolean = tl.getBoolInput('failOnEmptySource', false);
const flattenFolders: boolean = tl.getBoolInput('flattenFolders', false);
if (!tl.stats(sourceFolder).isDirectory()) {
throw tl.loc('SourceNotFolder');
}
// initialize the SSH helpers, set up the connection
sshHelper = new SshHelper(sshConfig);
await sshHelper.setupConnection();
if (cleanTargetFolder && await sshHelper.checkRemotePathExists(targetFolder)) {
console.log(tl.loc('CleanTargetFolder', targetFolder));
const isWindowsOnTarget: boolean = tl.getBoolInput('isWindowsOnTarget', false);
const cleanTargetFolderCmd: string = utils.getCleanTargetFolderCmd(targetFolder, isWindowsOnTarget);
try {
await sshHelper.runCommandOnRemoteMachine(cleanTargetFolderCmd, null);
} catch (err) {
throw tl.loc('CleanTargetFolderFailed', err);
}
}
// identify the files to copy
const filesToCopy: string[] = getFilesToCopy(sourceFolder, contents);
// copy files to remote machine
if (filesToCopy) {
tl.debug('Number of files to copy = ' + filesToCopy.length);
tl.debug('filesToCopy = ' + filesToCopy);
let failureCount = 0;
console.log(tl.loc('CopyingFiles', filesToCopy.length));
for (const fileToCopy of filesToCopy) {
try {
tl.debug('fileToCopy = ' + fileToCopy);
let relativePath;
if (flattenFolders) {
relativePath = path.basename(fileToCopy);
} else {
relativePath = fileToCopy.substring(sourceFolder.length)
.replace(/^\\/g, "")
.replace(/^\//g, "");
}
tl.debug('relativePath = ' + relativePath);
let targetPath = path.posix.join(targetFolder, relativePath);
if (!path.isAbsolute(targetPath) && !utils.pathIsUNC(targetPath)) {
targetPath = `./${targetPath}`;
}
console.log(tl.loc('StartedFileCopy', fileToCopy, targetPath));
if (!overwrite) {
const fileExists: boolean = await sshHelper.checkRemotePathExists(targetPath);
if (fileExists) {
throw tl.loc('FileExists', targetPath);
}
}
targetPath = utils.unixyPath(targetPath);
// looks like scp can only handle one file at a time reliably
await sshHelper.uploadFile(fileToCopy, targetPath);
} catch (err) {
tl.error(tl.loc('FailedOnFile', fileToCopy, err));
failureCount++;
}
}
console.log(tl.loc('CopyCompleted', filesToCopy.length));
if (failureCount) {
tl.setResult(tl.TaskResult.Failed, tl.loc('NumberFailed', failureCount));
}
} else if (failOnEmptySource) {
throw tl.loc('NothingToCopy');
} else {
tl.warning(tl.loc('NothingToCopy'));
}
} catch (err) {
tl.setResult(tl.TaskResult.Failed, err);
} finally {
// close the client connection to halt build execution
if (sshHelper) {
tl.debug('Closing the client connection');
await sshHelper.closeConnection();
}
}
}