/java/com/google/gerrit/pgm/Init.java
Java | 257 lines | 204 code | 37 blank | 16 comment | 20 complexity | 97eaa49100719ccc930a3075f58b8389 MD5 | raw file
1// Copyright (C) 2009 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gerrit.pgm;
16
17import com.google.common.base.Joiner;
18import com.google.common.collect.Sets;
19import com.google.gerrit.common.IoUtil;
20import com.google.gerrit.common.PageLinks;
21import com.google.gerrit.common.PluginData;
22import com.google.gerrit.pgm.init.BaseInit;
23import com.google.gerrit.pgm.init.Browser;
24import com.google.gerrit.pgm.init.InitPlugins;
25import com.google.gerrit.pgm.init.api.ConsoleUI;
26import com.google.gerrit.pgm.util.ErrorLogFile;
27import com.google.gerrit.server.config.GerritServerConfigModule;
28import com.google.gerrit.server.config.SitePath;
29import com.google.gerrit.server.securestore.SecureStoreClassName;
30import com.google.gerrit.server.util.HostPlatform;
31import com.google.inject.AbstractModule;
32import com.google.inject.Guice;
33import com.google.inject.Inject;
34import com.google.inject.Module;
35import com.google.inject.util.Providers;
36import java.io.IOException;
37import java.nio.file.Path;
38import java.util.ArrayList;
39import java.util.Collections;
40import java.util.List;
41import java.util.Set;
42import org.kohsuke.args4j.Option;
43
44/** Initialize a new Gerrit installation. */
45public class Init extends BaseInit {
46 @Option(
47 name = "--batch",
48 aliases = {"-b"},
49 usage = "Batch mode; skip interactive prompting"
50 )
51 private boolean batchMode;
52
53 @Option(name = "--delete-caches", usage = "Delete all persistent caches without asking")
54 private boolean deleteCaches;
55
56 @Option(name = "--no-auto-start", usage = "Don't automatically start daemon after init")
57 private boolean noAutoStart;
58
59 @Option(name = "--skip-plugins", usage = "Don't install plugins")
60 private boolean skipPlugins;
61
62 @Option(name = "--list-plugins", usage = "List available plugins")
63 private boolean listPlugins;
64
65 @Option(name = "--install-plugin", usage = "Install given plugin without asking")
66 private List<String> installPlugins;
67
68 @Option(name = "--install-all-plugins", usage = "Install all plugins from war without asking")
69 private boolean installAllPlugins;
70
71 @Option(
72 name = "--secure-store-lib",
73 usage = "Path to jar providing SecureStore implementation class"
74 )
75 private String secureStoreLib;
76
77 @Option(name = "--dev", usage = "Setup site with default options suitable for developers")
78 private boolean dev;
79
80 @Option(name = "--skip-all-downloads", usage = "Don't download libraries")
81 private boolean skipAllDownloads;
82
83 @Option(name = "--skip-download", usage = "Don't download given library")
84 private List<String> skippedDownloads;
85
86 @Inject Browser browser;
87
88 public Init() {
89 super(new WarDistribution(), null);
90 }
91
92 public Init(Path sitePath) {
93 super(sitePath, true, true, new WarDistribution(), null);
94 batchMode = true;
95 noAutoStart = true;
96 }
97
98 @Override
99 protected boolean beforeInit(SiteInit init) throws Exception {
100 ErrorLogFile.errorOnlyConsole();
101
102 if (!skipPlugins) {
103 final List<PluginData> plugins =
104 InitPlugins.listPluginsAndRemoveTempFiles(init.site, pluginsDistribution);
105 ConsoleUI ui = ConsoleUI.getInstance(false);
106 if (installAllPlugins && !nullOrEmpty(installPlugins)) {
107 ui.message("Cannot use --install-plugin together with --install-all-plugins.\n");
108 return true;
109 }
110 verifyInstallPluginList(ui, plugins);
111 if (listPlugins) {
112 if (!plugins.isEmpty()) {
113 ui.message("Available plugins:\n");
114 for (PluginData plugin : plugins) {
115 ui.message(" * %s version %s\n", plugin.name, plugin.version);
116 }
117 } else {
118 ui.message("No plugins found.\n");
119 }
120 return true;
121 }
122 }
123 return false;
124 }
125
126 @Override
127 protected void afterInit(SiteRun run) throws Exception {
128 List<Module> modules = new ArrayList<>();
129 modules.add(
130 new AbstractModule() {
131 @Override
132 protected void configure() {
133 bind(Path.class).annotatedWith(SitePath.class).toInstance(getSitePath());
134 bind(Browser.class);
135 bind(String.class)
136 .annotatedWith(SecureStoreClassName.class)
137 .toProvider(Providers.of(getConfiguredSecureStoreClass()));
138 }
139 });
140 modules.add(new GerritServerConfigModule());
141 Guice.createInjector(modules).injectMembers(this);
142 start(run);
143 }
144
145 @Override
146 protected List<String> getInstallPlugins() {
147 return installPlugins;
148 }
149
150 @Override
151 protected boolean installAllPlugins() {
152 return installAllPlugins;
153 }
154
155 @Override
156 protected ConsoleUI getConsoleUI() {
157 return ConsoleUI.getInstance(batchMode);
158 }
159
160 @Override
161 protected boolean getAutoStart() {
162 return !noAutoStart;
163 }
164
165 @Override
166 protected boolean getDeleteCaches() {
167 return deleteCaches;
168 }
169
170 @Override
171 protected boolean skipPlugins() {
172 return skipPlugins;
173 }
174
175 @Override
176 protected boolean isDev() {
177 return dev;
178 }
179
180 @Override
181 protected boolean skipAllDownloads() {
182 return skipAllDownloads;
183 }
184
185 @Override
186 protected List<String> getSkippedDownloads() {
187 return skippedDownloads != null ? skippedDownloads : Collections.<String>emptyList();
188 }
189
190 @Override
191 protected String getSecureStoreLib() {
192 return secureStoreLib;
193 }
194
195 void start(SiteRun run) throws Exception {
196 if (run.flags.autoStart) {
197 if (HostPlatform.isWin32()) {
198 System.err.println("Automatic startup not supported on Win32.");
199
200 } else {
201 startDaemon(run);
202 if (!run.ui.isBatch()) {
203 browser.open(PageLinks.ADMIN_PROJECTS);
204 }
205 }
206 }
207 }
208
209 void startDaemon(SiteRun run) {
210 String[] argv = {run.site.gerrit_sh.toAbsolutePath().toString(), "start"};
211 Process proc;
212 try {
213 System.err.println("Executing " + argv[0] + " " + argv[1]);
214 proc = Runtime.getRuntime().exec(argv);
215 } catch (IOException e) {
216 System.err.println("error: cannot start Gerrit: " + e.getMessage());
217 return;
218 }
219
220 try {
221 proc.getOutputStream().close();
222 } catch (IOException e) {
223 // Ignored
224 }
225
226 IoUtil.copyWithThread(proc.getInputStream(), System.err);
227 IoUtil.copyWithThread(proc.getErrorStream(), System.err);
228
229 for (; ; ) {
230 try {
231 int rc = proc.waitFor();
232 if (rc != 0) {
233 System.err.println("error: cannot start Gerrit: exit status " + rc);
234 }
235 break;
236 } catch (InterruptedException e) {
237 // retry
238 }
239 }
240 }
241
242 private void verifyInstallPluginList(ConsoleUI ui, List<PluginData> plugins) {
243 if (nullOrEmpty(installPlugins) || nullOrEmpty(plugins)) {
244 return;
245 }
246 Set<String> missing = Sets.newHashSet(installPlugins);
247 plugins.stream().forEach(p -> missing.remove(p.name));
248 if (!missing.isEmpty()) {
249 ui.message("Cannot find plugin(s): %s\n", Joiner.on(", ").join(missing));
250 listPlugins = true;
251 }
252 }
253
254 private static boolean nullOrEmpty(List<?> list) {
255 return list == null || list.isEmpty();
256 }
257}