/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.storage.template;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.log4j.Logger;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.exception.CloudRuntimeException;
import com.trilead.ssh2.SCPClient;
public class ScpTemplateDownloader extends TemplateDownloaderBase implements TemplateDownloader {
private static final Logger s_logger = Logger.getLogger(ScpTemplateDownloader.class);
public ScpTemplateDownloader(StorageLayer storageLayer, String downloadUrl, String toDir, long maxTemplateSizeInBytes, DownloadCompleteCallback callback) {
super(storageLayer, downloadUrl, toDir, maxTemplateSizeInBytes, callback);
URI uri;
try {
uri = new URI(_downloadUrl);
} catch (URISyntaxException e) {
s_logger.warn("URI syntax error: " + _downloadUrl);
_status = Status.UNRECOVERABLE_ERROR;
return;
}
String path = uri.getPath();
String filename = path.substring(path.lastIndexOf("/") + 1);
_toFile = toDir + File.separator + filename;
}
@Override
public long download(boolean resume, DownloadCompleteCallback callback) {
if (_status == Status.ABORTED ||
_status == Status.UNRECOVERABLE_ERROR ||
_status == Status.DOWNLOAD_FINISHED) {
return 0;
}
_resume = resume;
_start = System.currentTimeMillis();
URI uri;
try {
uri = new URI(_downloadUrl);
} catch (URISyntaxException e1) {
_status = Status.UNRECOVERABLE_ERROR;
return 0;
}
String username = uri.getUserInfo();
String queries = uri.getQuery();
String password = null;
if (queries != null) {
String[] qs = queries.split("&");
for (String q : qs) {
String[] tokens = q.split("=");
if (tokens[0].equalsIgnoreCase("password")) {
password = tokens[1];
break;
}
}
}
int port = uri.getPort();
if (port == -1) {
port = 22;
}
long length = 0;
File file = new File(_toFile);
com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(uri.getHost(), port);
try {
if (_storage != null) {
file.createNewFile();
_storage.setWorldReadableAndWriteable(file);
}
sshConnection.connect(null, 60000, 60000);
if (!sshConnection.authenticateWithPassword(username, password)) {
throw new CloudRuntimeException("Unable to authenticate");
}
SCPClient scp = new SCPClient(sshConnection);
String src = uri.getPath();
_status = Status.IN_PROGRESS;
scp.get(src, _toDir);
if (!file.exists()) {
_status = Status.UNRECOVERABLE_ERROR;
s_logger.debug("unable to scp the file " + _downloadUrl);
return 0;
}
_status = Status.DOWNLOAD_FINISHED;
_totalBytes = file.length();
String downloaded = "(download complete)";
_errorString = "Downloaded " + _remoteSize + " bytes " + downloaded;
_downloadTime += System.currentTimeMillis() - _start;
return _totalBytes;
} catch (Exception e) {
s_logger.warn("Unable to download " + _downloadUrl, e);
_status = TemplateDownloader.Status.UNRECOVERABLE_ERROR;
_errorString = e.getMessage();
return 0;
} finally {
sshConnection.close();
if (_status == Status.UNRECOVERABLE_ERROR && file.exists()) {
file.delete();
}
if (callback != null) {
callback.downloadComplete(_status);
}
}
}
@Override
public int getDownloadPercent() {
if (_status == Status.DOWNLOAD_FINISHED) {
return 100;
} else if (_status == Status.IN_PROGRESS) {
return 50;
} else {
return 0;
}
}
public static void main(String[] args) {
String url ="scp://root@sol10-2/root/alex/agent.zip?password=password";
TemplateDownloader td = new ScpTemplateDownloader(null, url,"/tmp/mysql", TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES, null);
long bytes = td.download(true, null);
if (bytes > 0) {
System.out.println("Downloaded (" + bytes + " bytes)" + " in " + td.getDownloadTime()/1000 + " secs");
} else {
System.out.println("Failed download");
}
}
}