in src/library/Connect/LocalEnvironmentManager.cs [582:661]
private async Task<string> _DownloadFileAsync(
int remoteAgentLocalPort,
WorkloadInfo workloadInfo,
string path,
string localPath,
CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(localPath))
{
localPath = _fileSystem.Path.GetTempFilePath(Guid.NewGuid().ToString("N").Substring(0, 8));
}
if (!path.StartsWith("/"))
{
path = '/' + path;
}
// If container path is not mentioned, use remote agent API
if (string.IsNullOrEmpty(workloadInfo.WorkingContainer))
{
var httpClient = new HttpClient()
{
BaseAddress = new Uri($"http://{IPAddress.Loopback}:{remoteAgentLocalPort}")
};
this._ReportProgress(Resources.DownloadingFromFormat, path);
string tarFile = _fileSystem.Path.GetTempFilePath(Guid.NewGuid().ToString("N") + ".tar.gz");
string downloadPath = $"/api/download/files{path}";
Exception downloadException = null;
for (int retry = 0; retry < 3; retry++)
{
try
{
using (var downloadResponse = await httpClient.GetAsync(downloadPath))
{
downloadResponse.EnsureSuccessStatusCode();
using (var outputStream = _fileSystem.CreateFile(tarFile))
{
await downloadResponse.Content.CopyToAsync(outputStream);
}
_fileSystem.CreateDirectory(localPath);
var tarCommand = "tar";
var tarArguments = $"xzf {tarFile}";
var (exitCode, output) = this._platform.ExecuteAndReturnOutput(tarCommand,
tarArguments,
timeout: TimeSpan.FromSeconds(30),
stdOutCallback: (line) => _log.Info(line),
stdErrCallback: (line) => _log.Error(line),
workingDirectory: localPath);
if (exitCode != 0)
{
this._ReportProgress(Resources.RunningTarCommandFailed, tarCommand, tarArguments, exitCode, output);
_log.Warning($"Running {tarCommand} {tarArguments} failed with exit code {exitCode}: {output}");
}
}
this._ReportProgress(Resources.DownloadCompletedMessage);
break;
}
catch (Exception ex)
{
downloadException = ex;
_log.ExceptionAsWarning(ex);
this._ReportProgress(Resources.DownloadFailed, ex.Message);
this._ReportProgress(Resources.RetryingMessage, ex.Message);
await Task.Delay(1000);
}
}
if (downloadException != null)
{
this._ReportProgress(Resources.DownloadFailed, downloadException.Message);
}
}
// Container path is mentioned, use kubectl to copy
else
{
this._CopyDirectoryFromContainerKubectl(workloadInfo, workloadInfo.WorkingContainer, localPath, cancellationToken);
}
return localPath;
}