]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.launcher/src/org/argeo/slc/cli/SlcMain.java
Merge branch 'master' of https://github.com/argeo/argeo-slc.git
[gpl/argeo-slc.git] / org.argeo.slc.launcher / src / org / argeo / slc / cli / SlcMain.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.cli;
17
18 import java.io.File;
19 import java.io.FileOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.lang.reflect.Method;
23 import java.security.AccessController;
24 import java.security.PrivilegedAction;
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.ServiceLoader;
31 import java.util.UUID;
32
33 import javax.security.auth.Subject;
34 import javax.security.auth.login.LoginContext;
35
36 import org.argeo.osgi.boot.OsgiBoot;
37 import org.osgi.framework.BundleContext;
38 import org.osgi.framework.ServiceReference;
39 import org.osgi.framework.launch.Framework;
40 import org.osgi.framework.launch.FrameworkFactory;
41
42 /** Configures an SLC runtime and runs a process. */
43 public class SlcMain implements PrivilegedAction<String> {
44 public final static String NIX = "NIX";
45 public final static String WINDOWS = "WINDOWS";
46 public final static String SOLARIS = "SOLARIS";
47
48 public final static String os;
49 public final static String slcDirName = ".slc";
50 final static File homeDir = new File(System.getProperty("user.home"));
51
52 static {
53 String osName = System.getProperty("os.name");
54 if (osName.startsWith("Win"))
55 os = WINDOWS;
56 else if (osName.startsWith("Solaris"))
57 os = SOLARIS;
58 else
59 os = NIX;
60 }
61
62 private Long timeout = 30 * 1000l;
63 private final String[] args;
64 private final File confDir;
65 private final File dataDir;
66 private final File modulesDir;
67
68 private final List<String> bundlesToStart = new ArrayList<String>();
69
70 public SlcMain(String[] args, File confDir, File dataDir, File modulesDir) {
71 this.args = args;
72 this.confDir = confDir;
73 this.dataDir = dataDir;
74 this.modulesDir = modulesDir;
75
76 bundlesToStart.add("org.eclipse.equinox.cm");
77 bundlesToStart.add("org.argeo.cms");
78 bundlesToStart.add("org.eclipse.gemini.blueprint.extender");
79 bundlesToStart.add("org.argeo.slc.agent");
80 bundlesToStart.add("org.argeo.slc.agent.jcr");
81
82 // bundlesToStart.add("org.springframework.osgi.extender");
83 // bundlesToStart.add("org.argeo.node.repo.jackrabbit");
84 // bundlesToStart.add("org.argeo.security.dao.os");
85 // bundlesToStart.add("org.argeo.slc.node.jackrabbit");
86 // bundlesToStart.add("org.argeo.slc.agent");
87 // bundlesToStart.add("org.argeo.slc.agent.jcr");
88 // if (args.length == 0)
89 // bundlesToStart.add("org.argeo.slc.support.equinox");
90 // bundlesToStart.add("org.argeo.slc.agent.cli");
91 }
92
93 public String run() {
94 long begin = System.currentTimeMillis();
95
96 Framework framework = null;
97 try {
98 info("## Date : " + new Date());
99 info("## Data : " + dataDir.getCanonicalPath());
100
101 // Start Equinox
102 ServiceLoader<FrameworkFactory> ff = ServiceLoader.load(FrameworkFactory.class);
103 FrameworkFactory frameworkFactory = ff.iterator().next();
104 Map<String, String> configuration = new HashMap<String, String>();
105 configuration.put("osgi.configuration.area", confDir.getCanonicalPath());
106 configuration.put("osgi.instance.area", dataDir.getCanonicalPath());
107 // Do clean
108 configuration.put("osgi.clean", "true");
109 if (args.length == 0) {
110 configuration.put("osgi.console", "");
111 }
112
113 // Spring configs currently require System properties
114 System.getProperties().putAll(configuration);
115
116 framework = frameworkFactory.newFramework(configuration);
117 framework.start();
118 BundleContext bundleContext = framework.getBundleContext();
119
120 // OSGi bootstrap
121 OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
122
123 // working copy modules
124 if (modulesDir.exists())
125 osgiBoot.installUrls(osgiBoot.getBundlesUrls(modulesDir.getCanonicalPath() + ";in=*;ex=.gitignore"));
126
127 // system modules
128 if (System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BUNDLES) != null)
129 osgiBoot.installUrls(osgiBoot.getBundlesUrls(System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BUNDLES)));
130 else
131 osgiBoot.installUrls(osgiBoot.getBundlesUrls(System.getProperty("user.home") + "/.slc/modules/;in=**"));
132
133 // Start runtime
134 osgiBoot.startBundles(bundlesToStart);
135
136 // Find SLC Agent
137 ServiceReference sr = null;
138 while (sr == null) {
139 sr = bundleContext.getServiceReference("org.argeo.slc.execution.SlcAgentCli");
140 if (System.currentTimeMillis() - begin > timeout)
141 throw new RuntimeException("Cannot find SLC agent CLI");
142 Thread.sleep(100);
143 }
144 Object agentCli = bundleContext.getService(sr);
145
146 // Initialization completed
147 long duration = System.currentTimeMillis() - begin;
148 info("[[ Initialized in " + (duration / 1000) + "s " + (duration % 1000) + "ms ]]");
149
150 if (args.length == 0)
151 return null;// console mode
152
153 // Subject.doAs(Subject.getSubject(AccessController.getContext()),
154 // new AgentCliCall(agentCli));
155 Class<?>[] parameterTypes = { String[].class };
156 Method method = agentCli.getClass().getMethod("process", parameterTypes);
157 Object[] methodArgs = { args };
158 Object ret = method.invoke(agentCli, methodArgs);
159
160 // Shutdown OSGi runtime
161 framework.stop();
162 framework.waitForStop(60 * 1000);
163
164 return ret.toString();
165 } catch (Exception e) {
166 // Shutdown OSGi runtime
167 if (framework != null)
168 try {
169 framework.stop();
170 framework.waitForStop(15 * 1000);
171 } catch (Exception silent) {
172 }
173 throw new RuntimeException("Cannot run SLC command line", e);
174 } finally {
175
176 }
177 }
178
179 public static void main(String[] args) {
180 try {
181 // Prepare directories
182 File executionDir = new File(System.getProperty("user.dir"));
183 File slcDir;
184 Boolean isTransient = false;
185 if (isTransient) {
186 File tempDir = new File(System.getProperty("java.io.tmpdir") + "/" + System.getProperty("user.name"));
187 slcDir = new File(tempDir, "slc-" + UUID.randomUUID().toString());
188 slcDir.mkdirs();
189 System.setProperty("argeo.node.repo.configuration", "osgibundle:repository-memory.xml");
190 } else {
191 slcDir = findSlcDir(executionDir);
192 if (slcDir == null) {
193 slcDir = new File(executionDir, slcDirName);
194 slcDir.mkdirs();
195 info("## Creating an SLC node at " + slcDir + " ...");
196 }
197 }
198
199 File dataDir = new File(slcDir, "data");
200 if (!dataDir.exists())
201 dataDir.mkdirs();
202
203 File confDir = new File(slcDir, "conf");
204 if (!confDir.exists())
205 confDir.mkdirs();
206
207 File modulesDir = new File(slcDir, "modules");
208
209 // JAAS
210 // File jaasFile = new File(confDir, "jaas.config");
211 // if (!jaasFile.exists())
212 // copyResource("/org/argeo/slc/cli/jaas.config", jaasFile);
213 // System.setProperty("java.security.auth.login.config",
214 // jaasFile.getCanonicalPath());
215
216 // log4j
217 File log4jFile = new File(confDir, "log4j.properties");
218 if (!log4jFile.exists())
219 copyResource("/org/argeo/slc/cli/log4j.properties", log4jFile);
220 System.setProperty("log4j.configuration", "file://" + log4jFile.getCanonicalPath());
221 // Run as a privileged action
222 // LoginContext lc = new LoginContext(os);
223 // lc.login();
224 //
225 // Subject subject =
226 // Subject.getSubject(AccessController.getContext());
227 // Subject.doAs(subject, new SlcMain(args, confDir, dataDir,
228 // modulesDir));
229 SlcMain slcMain = new SlcMain(args, confDir, dataDir, modulesDir);
230 slcMain.run();
231 if (args.length != 0)
232 System.exit(0);
233 } catch (Exception e) {
234 e.printStackTrace();
235 System.exit(1);
236 }
237 }
238
239 /**
240 * Recursively look in parent directories for a directory named
241 * {@link #slcDirName}
242 */
243 protected static File findSlcDir(File currentDir) {
244 File slcDir = new File(currentDir, slcDirName);
245 // covers the use case of running from the home directory
246 if (slcDir.exists() && slcDir.isDirectory())
247 return slcDir;
248 File parentDir = currentDir.getParentFile();
249 if (parentDir == null)
250 return null;
251 try {
252 // ~/.slc reserved for agent
253 if (parentDir.getCanonicalPath().equals(homeDir.getCanonicalPath()))
254 return null;
255 } catch (IOException e) {
256 throw new RuntimeException("Cannot check home directory", e);
257 }
258 return findSlcDir(parentDir);
259 }
260
261 protected static void copyResource(String resource, File targetFile) {
262 InputStream input = null;
263 FileOutputStream output = null;
264 try {
265 input = SlcMain.class.getResourceAsStream(resource);
266 output = new FileOutputStream(targetFile);
267 byte[] buf = new byte[8192];
268 while (true) {
269 int length = input.read(buf);
270 if (length < 0)
271 break;
272 output.write(buf, 0, length);
273 }
274 } catch (Exception e) {
275 throw new RuntimeException("Cannot write " + resource + " file to " + targetFile, e);
276 } finally {
277 try {
278 input.close();
279 } catch (Exception ignore) {
280 }
281 try {
282 output.close();
283 } catch (Exception ignore) {
284 }
285 }
286
287 }
288
289 protected static void info(Object msg) {
290 System.out.println(msg);
291 }
292
293 protected static void err(Object msg) {
294 System.err.println(msg);
295 }
296
297 protected static void debug(Object msg) {
298 System.out.println(msg);
299 }
300
301 }
302
303 // private String bundlesToInstall = System.getProperty("user.home")
304 // +
305 // "/dev/src/slc/dep/org.argeo.slc.dep.minimal/target/dependency;in=*.jar,"
306 // + System.getProperty("user.home")
307 // + "/dev/src/slc/demo/modules;in=*;ex=pom.xml;ex=.svn";
308
309 // ServiceTracker agentTracker = new ServiceTracker(bundleContext,
310 // "org.argeo.slc.execution.SlcAgentCli", null);
311 // agentTracker.open();
312 // final Object agentCli = agentTracker.waitForService(30 * 1000);
313 // if (agentCli == null)
314 // throw new RuntimeException("Cannot find SLC agent CLI");
315
316 // protected class AgentCliCall implements PrivilegedAction<String> {
317 // private final Object agentCli;
318 //
319 // public AgentCliCall(Object agentCli) {
320 // super();
321 // this.agentCli = agentCli;
322 // }
323 //
324 // public String run() {
325 // try {
326 // Class<?>[] parameterTypes = { String[].class };
327 // Method method = agentCli.getClass().getMethod("process",
328 // parameterTypes);
329 // Object[] methodArgs = { args };
330 // Object ret = method.invoke(agentCli, methodArgs);
331 // return ret.toString();
332 // } catch (Exception e) {
333 // throw new RuntimeException("Cannot run "
334 // + Arrays.toString(args) + " on " + agentCli, e);
335 // }
336 // }
337 //
338 // }