Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2014-11-07 21:24:15 +0000
committerPascal Rapicault2014-11-07 21:24:15 +0000
commit0d0b5f889057bc6d111fd7b08396cc3c3c595576 (patch)
tree91b7894812235975cdff7632a0f797c418804ee8
parentfe481d16792024cddc65527f1e40b3b159f0d968 (diff)
downloadrt.equinox.p2-0d0b5f889057bc6d111fd7b08396cc3c3c595576.tar.gz
rt.equinox.p2-0d0b5f889057bc6d111fd7b08396cc3c3c595576.tar.xz
rt.equinox.p2-0d0b5f889057bc6d111fd7b08396cc3c3c595576.zip
Add application to collect native packages from an installation
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF5
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/plugin.xml12
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativePackageExtractionApplication.java304
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties4
5 files changed, 328 insertions, 1 deletions
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
index c7b9b0e70..3ecd5aacf 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
@@ -8,7 +8,8 @@ Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.equinox.internal.p2.touchpoint.natives;x-internal:=true,
org.eclipse.equinox.internal.p2.touchpoint.natives.actions;x-internal:=true
-Require-Bundle: org.eclipse.equinox.common
+Require-Bundle: org.eclipse.equinox.common,
+ org.eclipse.equinox.app;bundle-version="1.3.0";resolution:=optional
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
@@ -17,6 +18,8 @@ Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.p2.engine;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.engine.spi;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.metadata;version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.p2.metadata.expression;version="2.0.0";resolution:=optional,
+ org.eclipse.equinox.p2.query;version="2.0.0";resolution:=optional,
org.eclipse.equinox.p2.repository;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository.artifact;version="[2.0.0,3.0.0)",
org.eclipse.osgi.util;version="1.0.0",
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/plugin.xml b/bundles/org.eclipse.equinox.p2.touchpoint.natives/plugin.xml
index 3c7a78146..527fe1f4c 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/plugin.xml
@@ -121,4 +121,16 @@
version="1.0.0">
</action>
</extension>
+ <extension
+ id="nativePackageExtractor"
+ point="org.eclipse.core.runtime.applications">
+ <application
+ cardinality="singleton-global"
+ thread="main"
+ visible="true">
+ <run
+ class="org.eclipse.equinox.internal.p2.touchpoint.natives.NativePackageExtractionApplication">
+ </run>
+ </application>
+ </extension>
</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java
index d2bf16ae3..3655d9856 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java
@@ -58,6 +58,10 @@ public class Messages extends NLS {
public static String Incorrect_Command;
public static String link_failed;
public static String mkdir_failed;
+ public static String NativePackageExtractionApplication_FolderNotFound;
+ public static String NativePackageExtractionApplication_MissingParameters;
+ public static String NativePackageExtractionApplication_PersistencePb;
+ public static String NativePackageExtractionApplication_MissingValue;
public static String PromptForNative_InstallText;
public static String PromptForNative_IntroText;
public static String PromptForNative_Version;
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativePackageExtractionApplication.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativePackageExtractionApplication.java
new file mode 100644
index 000000000..c27b0f44f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativePackageExtractionApplication.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Rapicorp, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Rapicorp, Inc - application to collect native packages from an existing install
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.touchpoint.natives;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.internal.p2.touchpoint.natives.actions.ActionConstants;
+import org.eclipse.equinox.internal.p2.touchpoint.natives.actions.CheckAndPromptNativePackage;
+import org.eclipse.equinox.p2.core.*;
+import org.eclipse.equinox.p2.engine.IProfile;
+import org.eclipse.equinox.p2.engine.IProfileRegistry;
+import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.query.QueryUtil;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.ServiceReference;
+
+public class NativePackageExtractionApplication implements IApplication {
+ //Keys used in the file created by the application
+ private static final String PROP_LAUNCHER_NAME = "launcherName"; //$NON-NLS-1$
+ private static final String PROP_ARCH = "arch"; //$NON-NLS-1$
+ private static final String PROP_DEPENDS = "depends"; //$NON-NLS-1$
+
+ //Internal constants
+ private static final String DEFAULT_VERSION_CONSTRAINT = ">="; //$NON-NLS-1$
+ private static final String _ACTION_ID = "_action_id_"; //$NON-NLS-1$
+ private static final String PROP_P2_PROFILE = "eclipse.p2.profile"; //$NON-NLS-1$
+ private static final Integer EXIT_ERROR = new Integer(13);
+
+ //Constants for arguments
+ private static final String OPTION_TO_ANALYZE = "-toAnalyze"; //$NON-NLS-1$
+ private static final String OPTION_RESULT_FILE = "-output"; //$NON-NLS-1$
+
+ //Values provided as a parameter to the application
+ private File installation;
+ private File resultFile;
+
+ //Values derived
+ private IProvisioningAgent targetAgent;
+ private String profileId;
+
+ //Data collected by the application
+ private Properties extractedData = new Properties();
+
+ private boolean stackTrace = false;
+
+ public Object start(IApplicationContext context) throws Exception {
+ try {
+ processArguments((String[]) context.getArguments().get("application.args")); //$NON-NLS-1$
+ initializeServices();
+ collectData();
+ persistInformation();
+ } catch (CoreException e) {
+ deeplyPrint(e.getStatus(), System.err, 0);
+ return EXIT_ERROR;
+ }
+ return IApplication.EXIT_OK;
+ }
+
+ private void processArguments(String[] args) throws CoreException {
+ if (args == null || args.length == 0) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.NativePackageExtractionApplication_MissingParameters, OPTION_TO_ANALYZE, OPTION_RESULT_FILE)));
+ }
+ for (int i = 0; i < args.length; i++) {
+ // check for args without parameters (i.e., a flag arg)
+ String opt = args[i];
+
+ if (OPTION_TO_ANALYZE.equals(opt)) {
+ installation = new File(getRequiredArgument(args, ++i));
+ if (!installation.exists())
+ throw new CoreException(new Status(IStatus.ERROR, Activator.ID, Messages.NativePackageExtractionApplication_FolderNotFound + installation.getAbsolutePath()));
+ continue;
+ }
+
+ if (OPTION_RESULT_FILE.equals(opt)) {
+ resultFile = new File(getRequiredArgument(args, ++i));
+ continue;
+ }
+ }
+ }
+
+ private static String getRequiredArgument(String[] args, int argIdx) throws CoreException {
+ if (argIdx < args.length) {
+ String arg = args[argIdx];
+ if (!arg.startsWith("-")) //$NON-NLS-1$
+ return arg;
+ }
+ throw new ProvisionException(NLS.bind(Messages.NativePackageExtractionApplication_MissingValue, args[argIdx - 1]));
+ }
+
+ private void collectData() {
+ IProfileRegistry registry = (IProfileRegistry) targetAgent.getService(IProfileRegistry.SERVICE_NAME);
+ IProfile p = registry.getProfile(profileId);
+ collectArchitecture(p);
+ collectLauncherName(p);
+ collectDebianDependencies(p);
+ }
+
+ private void persistInformation() throws CoreException {
+ try {
+ BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(resultFile));
+ try {
+ extractedData.store(os, "Data extracted from eclipse located at " + installation); //$NON-NLS-1$
+ } finally {
+ if (os != null)
+ os.close();
+ }
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.ID, Messages.NativePackageExtractionApplication_PersistencePb + resultFile.getAbsolutePath(), e));
+ }
+ }
+
+ private void collectLauncherName(IProfile p) {
+ extractedData.put(PROP_LAUNCHER_NAME, p.getProperty("eclipse.touchpoint.launcherName")); //$NON-NLS-1$
+ }
+
+ private void collectArchitecture(IProfile p) {
+ String environments = p.getProperty(IProfile.PROP_ENVIRONMENTS);
+ if (environments == null)
+ return;
+
+ for (StringTokenizer tokenizer = new StringTokenizer(environments, ","); tokenizer.hasMoreElements();) { //$NON-NLS-1$
+ String entry = tokenizer.nextToken();
+ int i = entry.indexOf('=');
+ String key = entry.substring(0, i).trim();
+ String value = entry.substring(i + 1).trim();
+ if (!key.equals("osgi.arch")) //$NON-NLS-1$
+ continue;
+
+ if ("x86_64".equals(value)) { //$NON-NLS-1$
+ extractedData.put(PROP_ARCH, "amd64"); //$NON-NLS-1$
+ return;
+ }
+ if ("x86".equals(value)) { //$NON-NLS-1$
+ extractedData.put(PROP_ARCH, "x86"); //$NON-NLS-1$
+ return;
+ }
+ }
+
+ }
+
+ private void collectDebianDependencies(IProfile p) {
+ String depends = ""; //$NON-NLS-1$
+ IQueryResult<IInstallableUnit> allIUs = p.available(QueryUtil.ALL_UNITS, new NullProgressMonitor());
+ Iterator<IInstallableUnit> a = allIUs.iterator();
+ while (a.hasNext()) {
+ IInstallableUnit iu = a.next();
+ Collection<ITouchpointData> tpdata = iu.getTouchpointData();
+ for (ITouchpointData data : tpdata) {
+ Map<String, ITouchpointInstruction> allInstructions = data.getInstructions();
+ for (ITouchpointInstruction instruction : allInstructions.values()) {
+ StringTokenizer tokenizer = new StringTokenizer(instruction.getBody(), ";"); //$NON-NLS-1$
+ while (tokenizer.hasMoreTokens()) {
+ Map<String, String> parsedInstructions = parseInstruction(tokenizer.nextToken());
+ if (parsedInstructions != null && parsedInstructions.get(_ACTION_ID).endsWith(CheckAndPromptNativePackage.ID)) {
+ if ("debian".equals(parsedInstructions.get(ActionConstants.PARM_LINUX_DISTRO))) { //$NON-NLS-1$
+ depends += formatAsDependsEntry(parsedInstructions.get(ActionConstants.PARM_LINUX_PACKAGE_NAME), parsedInstructions.get(ActionConstants.PARM_LINUX_PACKAGE_VERSION), parsedInstructions.get(ActionConstants.PACKAGE_VERSION_CONSTRAINT)) + ';';
+ }
+ }
+ }
+ }
+ }
+ }
+ extractedData.put(PROP_DEPENDS, depends);
+ }
+
+ private String formatAsDependsEntry(String packageId, String version, String versionConstraint) {
+ String result = packageId;
+ if (versionConstraint == null)
+ versionConstraint = DEFAULT_VERSION_CONSTRAINT;
+ if (version != null) {
+ result += '(' + versionConstraint + ' ' + version + ')';
+ }
+ return result;
+ }
+
+ //Code copied from the InstructionParser class
+ private Map<String, String> parseInstruction(String statement) {
+ Map<String, String> instructions = new HashMap<String, String>();
+
+ int openBracket = statement.indexOf('(');
+ int closeBracket = statement.lastIndexOf(')');
+ if (openBracket == -1 || closeBracket == -1 || openBracket > closeBracket)
+ return null;
+ instructions.put(_ACTION_ID, statement.substring(0, openBracket).trim());
+
+ String nameValuePairs = statement.substring(openBracket + 1, closeBracket);
+ if (nameValuePairs.length() == 0)
+ return instructions;
+
+ StringTokenizer tokenizer = new StringTokenizer(nameValuePairs, ","); //$NON-NLS-1$
+ while (tokenizer.hasMoreTokens()) {
+ String nameValuePair = tokenizer.nextToken();
+ int colonIndex = nameValuePair.indexOf(":"); //$NON-NLS-1$
+ if (colonIndex == -1)
+ return null;
+ String name = nameValuePair.substring(0, colonIndex).trim();
+ String value = nameValuePair.substring(colonIndex + 1).trim();
+ instructions.put(name, value);
+ }
+ return instructions;
+ }
+
+ private void initializeServices() throws ProvisionException {
+ ServiceReference<IProvisioningAgentProvider> agentProviderRef = Activator.getContext().getServiceReference(IProvisioningAgentProvider.class);
+ IProvisioningAgentProvider provider = Activator.getContext().getService(agentProviderRef);
+
+ URI p2DataArea = new File(installation, "p2").toURI(); //$NON-NLS-1$
+ targetAgent = provider.createAgent(p2DataArea);
+ targetAgent.registerService(IProvisioningAgent.INSTALLER_AGENT, provider.createAgent(null));
+
+ Activator.getContext().ungetService(agentProviderRef);
+ if (profileId == null) {
+ if (installation != null) {
+ File configIni = new File(installation, "configuration/config.ini"); //$NON-NLS-1$
+ InputStream in = null;
+ try {
+ Properties ciProps = new Properties();
+ in = new BufferedInputStream(new FileInputStream(configIni));
+ ciProps.load(in);
+ profileId = ciProps.getProperty(PROP_P2_PROFILE);
+ } catch (IOException e) {
+ // Ignore
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ // Ignore;
+ }
+ }
+ if (profileId == null)
+ profileId = installation.toString();
+ }
+ }
+ if (profileId != null)
+ targetAgent.registerService(PROP_P2_PROFILE, profileId);
+ }
+
+ private static void appendLevelPrefix(PrintStream strm, int level) {
+ for (int idx = 0; idx < level; ++idx)
+ strm.print(' ');
+ }
+
+ private void deeplyPrint(CoreException ce, PrintStream strm, int level) {
+ appendLevelPrefix(strm, level);
+ if (stackTrace)
+ ce.printStackTrace(strm);
+ deeplyPrint(ce.getStatus(), strm, level);
+ }
+
+ private void deeplyPrint(IStatus status, PrintStream strm, int level) {
+ appendLevelPrefix(strm, level);
+ String msg = status.getMessage();
+ strm.println(msg);
+ Throwable cause = status.getException();
+ if (cause != null) {
+ strm.print("Caused by: "); //$NON-NLS-1$
+ if (stackTrace || !(msg.equals(cause.getMessage()) || msg.equals(cause.toString())))
+ deeplyPrint(cause, strm, level);
+ }
+
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++)
+ deeplyPrint(children[i], strm, level + 1);
+ }
+ }
+
+ private void deeplyPrint(Throwable t, PrintStream strm, int level) {
+ if (t instanceof CoreException)
+ deeplyPrint((CoreException) t, strm, level);
+ else {
+ appendLevelPrefix(strm, level);
+ if (stackTrace)
+ t.printStackTrace(strm);
+ else {
+ strm.println(t.toString());
+ Throwable cause = t.getCause();
+ if (cause != null) {
+ strm.print("Caused by: "); //$NON-NLS-1$
+ deeplyPrint(cause, strm, level);
+ }
+ }
+ }
+ }
+
+ public void stop() {
+ //We don't handle application stopping
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
index ca7227fc3..913f2a648 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
@@ -48,6 +48,10 @@ Error_list_children_0=Error while retrieving children of directory: {0}
Incorrect_Command=Incorrect use of the command. One of the parameter is missing.
link_failed=Could not create link {0}.
mkdir_failed=Could not create directory {0}.
+NativePackageExtractionApplication_FolderNotFound=The folder to analyze could not be found:
+NativePackageExtractionApplication_MissingParameters=Missing arguments, please specify {0} and {1}.
+NativePackageExtractionApplication_MissingValue=The value is missing for argument {0}.
+NativePackageExtractionApplication_PersistencePb=error while persisting results in
PromptForNative_InstallText=\n You can install those by executing the following command: \n\t
PromptForNative_IntroText=The software you installed requires the following OS packages to be installed :
PromptForNative_Version=\ version

Back to the top