diff --git a/installation/.classpath b/installation/.classpath index 8cdc1b0d5e4deea2250b89532e7a7f115ae79d3a..4a3e44f04b0b09d443fde3576aca2cb6952c78f4 100644 --- a/installation/.classpath +++ b/installation/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="source/java"/> <classpathentry kind="src" path="sourceTest/java"/> - <classpathentry combineaccessrules="false" kind="src" path="/common"/> + <classpathentry combineaccessrules="false" kind="src" path="/common"/> <classpathentry kind="lib" path="/libraries/testng/testng-jdk15.jar" sourcepath="/libraries/testng/src.zip"/> <classpathentry kind="lib" path="/libraries/commons-lang/commons-lang.jar" sourcepath="/libraries/commons-lang/src.zip"/> <classpathentry kind="lib" path="/libraries/log4j/log4j.jar" sourcepath="/libraries/log4j/src.zip"/> @@ -10,16 +10,17 @@ <classpathentry kind="lib" path="/libraries/commons-collections/commons-collections.jar" sourcepath="/libraries/commons-collections/src.jar"/> <classpathentry kind="lib" path="/libraries/junit/junit.jar" sourcepath="/libraries/junit/src.jar"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-ant.jar"/> - <classpathentry kind="lib" path="/libraries/izpack/izpack-api.jar"/> + <classpathentry kind="lib" path="/libraries/izpack/izpack-api.jar" sourcepath="/libraries/izpack/sources/izpack.zip"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-compiler.jar"/> - <classpathentry kind="lib" path="/libraries/izpack/izpack-core.jar"/> + <classpathentry kind="lib" path="/libraries/izpack/izpack-core.jar" sourcepath="/libraries/izpack/sources/izpack.zip"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-event.jar"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-gui.jar"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-ini4j.jar"/> - <classpathentry kind="lib" path="/libraries/izpack/izpack-installer.jar"/> + <classpathentry kind="lib" path="/libraries/izpack/izpack-installer.jar" sourcepath="/libraries/izpack/sources/izpack.zip"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-native.jar"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-panel.jar"/> <classpathentry kind="lib" path="/libraries/izpack/izpack-tools.jar"/> - <classpathentry kind="lib" path="/libraries/izpack/izpack-uninstaller.jar"/> - <classpathentry kind="lib" path="/libraries/izpack/izpack-util.jar"/> + <classpathentry kind="lib" path="/libraries/izpack/izpack-uninstaller.jar" sourcepath="/libraries/izpack/sources/izpack.zip"/> + <classpathentry kind="lib" path="/libraries/izpack/izpack-util.jar" sourcepath="/libraries/izpack/sources/izpack.zip"/> + <classpathentry kind="output" path="bin"/> </classpath> diff --git a/installation/resource/installer/install.xml b/installation/resource/installer/install.xml index f1470062c0f68367ad2dd4cf0b9977ff21066683..69ab712f893fcbc8c411a2a846f1e64399ba19ea 100644 --- a/installation/resource/installer/install.xml +++ b/installation/resource/installer/install.xml @@ -2,7 +2,7 @@ <installation version="1.0"> <info> <appname>openBIS</appname> - <appversion>@{version.number}</appversion> + <appversion>@{version.number} (r@{revision.number})</appversion> <url>http://www.cisd.ethz.ch/software/openBIS</url> <uninstaller write="no"/> <javaversion>1.6</javaversion> diff --git a/installation/resource/tarball/extract.sh b/installation/resource/tarball/extract.sh new file mode 100644 index 0000000000000000000000000000000000000000..69ad9a5ff6b7351b50cae409f26d533f34492f55 --- /dev/null +++ b/installation/resource/tarball/extract.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +BASE=`dirname "$0"` +if [ ${BASE#/} == ${BASE} ]; then + BASE="`pwd`/${BASE}" +fi + +java -Djava.util.logging.config.file=$BASE/jul.config -cp $BASE/openBIS-installer.jar ch.systemsx.cisd.openbis.installer.izpack.Extractor "$@" \ No newline at end of file diff --git a/installation/source/java/ch/systemsx/cisd/openbis/installer/izpack/Extractor.java b/installation/source/java/ch/systemsx/cisd/openbis/installer/izpack/Extractor.java new file mode 100644 index 0000000000000000000000000000000000000000..ec4e5938c9e17a511b719f4f945385d8587fb1c7 --- /dev/null +++ b/installation/source/java/ch/systemsx/cisd/openbis/installer/izpack/Extractor.java @@ -0,0 +1,349 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed 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. + */ + +package ch.systemsx.cisd.openbis.installer.izpack; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.Pack200; + +import com.izforge.izpack.api.data.Info; +import com.izforge.izpack.api.data.Pack; +import com.izforge.izpack.api.data.PackFile; +import com.izforge.izpack.api.data.ResourceManager; +import com.izforge.izpack.api.exception.InstallerException; +import com.izforge.izpack.util.OsConstraintHelper; + +/** + * Helper class to extract a package from an openBIS self installing JAR. + * + * @author Franz-Josef Elmer + */ +public class Extractor +{ + private static final class VariableResolver + { + private final List<String[]> substitutions = new ArrayList<String[]>(); + + VariableResolver(String rootPath) + { + substitutions.add(new String[] { "$INSTALL_PATH/servers", rootPath }); + substitutions.add(new String[] { "$INSTALL_PATH", rootPath }); + substitutions.add(new String[] { "$INSTALL_TMPEXTRACT", rootPath }); + substitutions.add(new String[] { "$DATA_TMPEXTRACT", rootPath + "/datastore_server" }); + } + + public String resolve(String string) + { + String result = string; + for (String[] pair : substitutions) + { + result = result.replace(pair[0], pair[1]); + } + return result; + } + } + + private static final class Parameters + { + private static final String MISSING_PARAMETER_ERROR = "Missing parameters."; + + static Parameters parse(String[] args) + { + Parameters parameters = new Parameters(); + if (args.length < 2) + { + return setErrorMessage(parameters, MISSING_PARAMETER_ERROR); + } + String shortPackageName = args[0]; + parameters.installationPath = args[1]; + if (args[0].equals("-q")) + { + parameters.quiet = true; + if (args.length < 3) + { + return setErrorMessage(parameters, MISSING_PARAMETER_ERROR); + } + shortPackageName = args[1]; + parameters.installationPath = args[2]; + } + if (shortPackageName.equals("as")) + { + parameters.packageName = "openBIS Server"; + } else if (shortPackageName.equals("dss")) + { + parameters.packageName = "Datastore Server"; + } else if (shortPackageName.equals("scripts")) + { + parameters.packageName = "Administration Scripts"; + } else + { + parameters.errorMessage = "Unkown package '" + shortPackageName + "'."; + } + return parameters; + } + + private static Parameters setErrorMessage(Parameters parameters, String errorMessage) + { + parameters.errorMessage = errorMessage; + return parameters; + } + + private boolean quiet; + private String packageName; + private String installationPath; + private String errorMessage; + + boolean isQuiet() + { + return quiet; + } + + String getPackageName() + { + return packageName; + } + + String getInstallationPath() + { + return installationPath; + } + + String getErrorMessageOrNull() + { + return errorMessage; + } + } + + private static final class ConsoleOutput + { + private final boolean quiet; + + ConsoleOutput(boolean quiet) + { + this.quiet = quiet; + } + + void println(String message) + { + if (quiet == false) + { + System.out.println(message); + } + } + } + + public static void main(String[] args) throws Exception + { + Parameters parameters = Parameters.parse(args); + if (parameters.getErrorMessageOrNull() != null) + { + System.err.println("ERROR: " + parameters.getErrorMessageOrNull()); + System.err.println("Usage: java " + Extractor.class.getName() + + " [-q] as|dss|scripts <installation path>"); + System.exit(1); + } + + ConsoleOutput out = new ConsoleOutput(parameters.isQuiet()); + VariableResolver variableResolver = new VariableResolver(parameters.getInstallationPath()); + ResourceManager resourceManager = ResourceManager.getInstance(); + Info info = (Info) readObject(resourceManager, "info"); + out.println(info.getAppName()+" Version "+info.getAppVersion()); + List<Pack> availablePacks = getAvailablePacks(resourceManager); + for (Pack pack : availablePacks) + { + if (parameters.getPackageName().equals(pack.name)) + { + out.println("Extract package '" + pack.name + "' (" + pack.nbytes + " bytes)"); + extractPackage(pack, info, resourceManager, variableResolver, out); + break; + } + } + } + + private static void extractPackage(Pack pack, Info info, ResourceManager resourceManager, + VariableResolver variableResolver, ConsoleOutput out) throws Exception + { + ObjectInputStream objectInputStream = + new ObjectInputStream(getPackAsStream(resourceManager, pack.id, info)); + try + { + + int numberOfFiles = objectInputStream.readInt(); + for (int j = 0; j < numberOfFiles; j++) + { + PackFile packFile = (PackFile) objectInputStream.readObject(); + String targetPath = variableResolver.resolve(packFile.getTargetPath()); + out.println(targetPath); + File target = new File(targetPath); + if (packFile.isDirectory()) + { + target.mkdirs(); + continue; + } + target.getParentFile().mkdirs(); + extractFile(packFile, objectInputStream, target, resourceManager); + } + } finally + { + objectInputStream.close(); + } + } + + private static void extractFile(PackFile packFile, ObjectInputStream objectInputStream, + File target, ResourceManager resourceManager) throws Exception + { + OutputStream outputStream = null; + try + { + outputStream = new FileOutputStream(target); + if (packFile.isPack200Jar()) + { + int key = objectInputStream.readInt(); + Pack200.Unpacker unpacker = Pack200.newUnpacker(); + InputStream pack200Input = resourceManager.getInputStream("/packs/pack200-" + key); + java.util.jar.JarOutputStream jarOutputStream = null; + try + { + jarOutputStream = new java.util.jar.JarOutputStream(outputStream); + unpacker.unpack(pack200Input, jarOutputStream); + } finally + { + if (jarOutputStream != null) + { + jarOutputStream.close(); + } + } + } else + { + byte[] buffer = new byte[5120]; + long numberOfBytesAlreadyRead = 0; + while (numberOfBytesAlreadyRead < packFile.length()) + { + numberOfBytesAlreadyRead = + writeBuffer(packFile, buffer, outputStream, objectInputStream, + numberOfBytesAlreadyRead); + } + } + } finally + { + if (outputStream != null) + { + outputStream.close(); + } + } + } + + private static List<Pack> getAvailablePacks(ResourceManager resourceManager) throws Exception + { + InputStream in = resourceManager.getInputStream("packs.info"); + ObjectInputStream objectInputStream = null; + try + { + objectInputStream = new ObjectInputStream(in); + int size = objectInputStream.readInt(); + List<Pack> availablePacks = new ArrayList<Pack>(); + for (int i = 0; i < size; i++) + { + Pack pack = (Pack) objectInputStream.readObject(); + if (OsConstraintHelper.oneMatchesCurrentSystem(pack.osConstraints)) + { + availablePacks.add(pack); + } + } + return availablePacks; + } finally + { + if (objectInputStream != null) + { + objectInputStream.close(); + } + } + } + + private static long writeBuffer(PackFile packFile, byte[] buffer, OutputStream out, + InputStream inputStream, long numberOfBytesAlreadyRead) throws IOException + { + int maxBytes = (int) Math.min(packFile.length() - numberOfBytesAlreadyRead, buffer.length); + int numberOfBytesRead = inputStream.read(buffer, 0, maxBytes); + if (numberOfBytesRead == -1) + { + throw new IOException("Unexpected end of input stream."); + } + out.write(buffer, 0, numberOfBytesRead); + return numberOfBytesAlreadyRead + numberOfBytesRead; + } + + private static InputStream getPackAsStream(ResourceManager resourceManager, String packid, + Info info) throws Exception + { + InputStream in; + in = resourceManager.getInputStream("packs/pack-" + packid); + if (in == null) + { + throw new IOException("Unkown package '" + packid + "'."); + } + String decoderClassName = info.getPackDecoderClassName(); + if (decoderClassName == null) + { + return in; + } + @SuppressWarnings("unchecked") + Class<Object> decoder = (Class<Object>) Class.forName(decoderClassName); + Class<?>[] paramsClasses = new Class[1]; + paramsClasses[0] = Class.forName("java.io.InputStream"); + Constructor<Object> constructor = decoder.getDeclaredConstructor(paramsClasses); + InputStream buffer = new BufferedInputStream(in); + Object[] params = + { buffer }; + Object instance = null; + instance = constructor.newInstance(params); + if (!InputStream.class.isInstance(instance)) + { + throw new InstallerException("'" + decoderClassName + "' must be derived from " + + InputStream.class.toString()); + } + return (InputStream) instance; + } + + private static Object readObject(ResourceManager resourceManager, String resourceId) + throws Exception + { + InputStream inputStream = resourceManager.getInputStream(resourceId); + ObjectInputStream objectInputStream = null; + try + { + objectInputStream = new ObjectInputStream(inputStream); + Object model = objectInputStream.readObject(); + return model; + } finally + { + if (objectInputStream != null) + { + objectInputStream.close(); + } + } + } + +}