/*******************************************************************************
* Copyright (c) 2007-2017 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v 1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributor:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.openshift.reddeer.requirement;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import org.jboss.reddeer.common.logging.Logger;
import org.jboss.reddeer.junit.requirement.Requirement;
import org.jboss.tools.openshift.reddeer.exception.OpenShiftToolsException;
import org.jboss.tools.openshift.reddeer.requirement.OpenShiftCommandLineToolsRequirement.OCBinary;
import org.jboss.tools.openshift.reddeer.utils.FileHelper;
/**
* Requirement to download and extract OpenShift command line tools binary which is necessary
* for some functionality of OpenShift tools.
*
* @author mlabuda@redhat.com
* @author adietish@redhat.com
*
*/
public class OpenShiftCommandLineToolsRequirement implements Requirement<OCBinary> {
private static final String CLIENT_TOOLS_DESTINATION = "binaries";
private static final String SUFFIX_TAR_GZ = ".tar.gz";
private static final String SUFFIX_ZIP = ".zip";
private static final Logger LOGGER = new Logger(OpenShiftCommandLineToolsRequirement.class);
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface OCBinary {
}
@Override
public boolean canFulfill() {
return true;
}
@Override
public void fulfill() {
if (!OCBinaryFile.get().getFile().exists()) {
// symlink does not exist or exists but points to inexistent file
File downloadedOCBinary = downloadAndExtractOpenShiftClient();
createSymlink(downloadedOCBinary);
} else {
LOGGER.info("Binary is already downloaded.");
}
}
private void createSymlink(File downloadedOCBinary) {
try {
Files.deleteIfExists(Paths.get(OCBinaryFile.get().getFile().toURI()));
Files.createSymbolicLink(OCBinaryFile.get().getFile().toPath(), Paths.get(downloadedOCBinary.getAbsolutePath()));
} catch (IOException e) {
throw new OpenShiftToolsException(NLS.bind("Could not symlink {0} to {1}:\n{2}",
new Object[] { OCBinaryFile.get().getFile().getAbsolutePath(), downloadedOCBinary.getAbsolutePath(), e }));
}
}
@Override
public void setDeclaration(OCBinary declaration) {}
@Override
public void cleanUp() {}
public static String getOCLocation() {
return OCBinaryFile.get().getFile().getAbsolutePath();
}
private File downloadAndExtractOpenShiftClient() {
LOGGER.info("Creating directory binaries");
File outputDirectory = new File(CLIENT_TOOLS_DESTINATION);
FileHelper.createDirectory(outputDirectory);
String fileName = downloadArchive(getDownloadLink());
String extractedDirectory = extractArchive(fileName, outputDirectory);
if (StringUtils.isEmpty(extractedDirectory)
|| !(new File(extractedDirectory).exists())) {
throw new OpenShiftToolsException("Cannot extract archive " + fileName + ". "
+ "Archive does not extract into a single root folder.");
}
return new File(extractedDirectory, OCBinaryFile.get().getName());
}
private String downloadArchive(String downloadLink) {
if (StringUtils.isEmpty(downloadLink)) {
throw new OpenShiftToolsException("Cannot download OpenShift binary. No download known\n");
}
String fileName = null;
try {
URL downloadUrl = new URL(downloadLink);
fileName = getFileName(downloadUrl.getPath());
if (new File(fileName).exists()) {
return fileName;
}
try (FileOutputStream fileOutputStream = new FileOutputStream(fileName);
ReadableByteChannel readableByteChannel = Channels.newChannel(downloadUrl.openStream())) {
LOGGER.info("Downloading OpenShift binary.");
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException ex) {
throw new OpenShiftToolsException("Cannot download OpenShift binary.\n" + ex.getMessage());
}
} catch (MalformedURLException e) {
throw new OpenShiftToolsException(NLS.bind("Could not download \"{0}\". Invalid url.", downloadLink));
}
return fileName;
}
private String extractArchive(String fileName, File outputDirectory) {
if (StringUtils.isEmpty(fileName)) {
return null;
}
LOGGER.info(NLS.bind("Extracting OpenShift archive {0}.", fileName));
String extractedDirectory = null;
if (fileName.endsWith(SUFFIX_ZIP)) {
extractedDirectory = StringUtils.chomp(fileName, SUFFIX_ZIP);
FileHelper.unzipFile(new File(fileName), outputDirectory);
} else if (fileName.endsWith(SUFFIX_TAR_GZ)) {
extractedDirectory = StringUtils.chomp(fileName, SUFFIX_TAR_GZ);
FileHelper.extractTarGz(new File(fileName), outputDirectory);
}
return extractedDirectory;
}
private String getFileName(String urlPath) {
String[] pathParts = urlPath.split("/");
return Paths.get(CLIENT_TOOLS_DESTINATION, pathParts[pathParts.length - 1]).toString();
}
private String getDownloadLink() {
if (Platform.OS_LINUX.equals(Platform.getOS())) {
if (Platform.getOSArch().equals(Platform.ARCH_X86)) {
return ClientVersion.LINUX_1_3_32.getDownloadLink();
} else {
return ClientVersion.LINUX_1_3_64.getDownloadLink();
}
} else if (Platform.OS_WIN32.equals(Platform.getOSArch())){
return ClientVersion.WINDOWS_1_3_64.getDownloadLink();
} else if (Platform.OS_MACOSX.equals(Platform.getOS())){
return ClientVersion.MAC_1_3.getDownloadLink();
} else {
return null;
}
}
public enum ClientVersion {
LINUX_1_1_32("https://github.com/openshift/origin/releases/download/"
+ "v1.1/openshift-origin-v1.1-ac7a99a-linux-386.tar.gz"),
LINUX_1_1_64("https://github.com/openshift/origin/releases/download/"
+ "v1.1/openshift-origin-v1.1-ac7a99a-linux-amd64.tar.gz"),
WINDOWS_1_1_64("https://github.com/openshift/origin/releases/download/"
+ "v1.1/openshift-origin-v1.1-ac7a99a-windows-amd64.zip"),
LINUX_1_2_32("https://github.com/openshift/origin/releases/download/"
+ "v1.2.0/openshift-origin-client-tools-v1.2.0-2e62fab-linux-32bit.tar.gz"),
LINUX_1_2_64("https://github.com/openshift/origin/releases/download/"
+ "v1.2.0/openshift-origin-client-tools-v1.2.0-2e62fab-linux-64bit.tar.gz"),
WINDOWS_1_2_64("https://github.com/openshift/origin/releases/download/"
+ "v1.2.0/openshift-origin-client-tools-v1.2.0-2e62fab-windows.zip"),
MAC_1_2("https://github.com/openshift/origin/releases/download/"
+ "v1.2.0/openshift-origin-client-tools-v1.2.0-2e62fab-mac.zip"),
LINUX_1_3_32("https://github.com/openshift/origin/releases/download/"
+ "v1.3.2/openshift-origin-client-tools-v1.3.2-ac1d579-linux-32bit.tar.gz"),
LINUX_1_3_64("https://github.com/openshift/origin/releases/download/"
+ "v1.3.2/openshift-origin-client-tools-v1.3.2-ac1d579-linux-64bit.tar.gz"),
WINDOWS_1_3_64("https://github.com/openshift/origin/releases/download/"
+ "v1.3.2/openshift-origin-client-tools-v1.3.2-ac1d579-windows.zip"),
MAC_1_3("https://github.com/openshift/origin/releases/download/"
+ "v1.3.2/openshift-origin-client-tools-v1.3.2-ac1d579-mac.zip");
String url;
private ClientVersion(String url) {
this.url = url;
}
public String getDownloadLink() {
return url;
}
}
public enum OCBinaryFile {
LINUX("oc"),
MAC("oc"),
WINDOWS("oc.exe");
private String name;
private OCBinaryFile(String name) {
this.name = name;
}
public String getName() {
return name;
}
public File getFile() {
return new File(CLIENT_TOOLS_DESTINATION, getName());
}
public static OCBinaryFile get() {
if (Platform.OS_LINUX.equals(Platform.getOS())) {
return LINUX;
} else if (Platform.OS_MACOSX.equals(Platform.getOS())) {
return MAC;
} else if (Platform.OS_WIN32.equals(Platform.getOS())) {
return WINDOWS;
} else {
throw new OpenShiftToolsException("Could not determine oc binary name. Unknown operating system.");
}
}
}
}