]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.factory/src/org/argeo/slc/rpmfactory/core/RpmFactoryImpl.java
Adapt to changes in Argeo Commons
[gpl/argeo-slc.git] / org.argeo.slc.factory / src / org / argeo / slc / rpmfactory / core / RpmFactoryImpl.java
1 package org.argeo.slc.rpmfactory.core;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.text.DateFormat;
6 import java.text.SimpleDateFormat;
7 import java.util.ArrayList;
8 import java.util.Calendar;
9 import java.util.GregorianCalendar;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import javax.jcr.Node;
15 import javax.jcr.Repository;
16 import javax.jcr.RepositoryException;
17 import javax.jcr.Session;
18
19 import org.apache.commons.io.FileUtils;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.argeo.jcr.JcrUtils;
23 import org.argeo.slc.SlcConstants;
24 import org.argeo.slc.SlcException;
25 import org.argeo.slc.repo.NodeIndexerVisitor;
26 import org.argeo.slc.rpmfactory.RpmFactory;
27 import org.argeo.slc.rpmfactory.RpmRepository;
28 import org.argeo.slc.runtime.tasks.SystemCall;
29
30 /**
31 * Defines a build environment. This information is typically used by other
32 * components performing the various actions related to RPM build.
33 */
34 public class RpmFactoryImpl implements RpmFactory {
35 private Log log = LogFactory.getLog(RpmFactoryImpl.class);
36
37 private Repository rpmRepository;
38 private Repository distRepository;
39
40 private String id;
41 private List<RpmRepository> repositories = new ArrayList<RpmRepository>();
42 private List<String> archs = new ArrayList<String>();
43
44 private String rpmBase = "/mnt/slc/repos/rpm";
45 private String distBase = "/mnt/slc/repos/dist";
46 private String mockVar = "/var/lib/mock";
47 private String mockEtc = "/etc/mock";
48
49 private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
50
51 private String gitWorkspace = "git";
52
53 private String localUrlBase = "http://localhost:7070/";
54 /** If not null or empty, this is a developer instance. */
55 private String gitDevBaseUrl = null;
56
57 private Boolean withTestingRepository = false;
58
59 private String yumConfigMainSection = "cachedir=/var/cache/yum\n"
60 + "debuglevel=1\n" + "reposdir=/dev/null\n"
61 + "logfile=/var/log/yum.log\n" + "retries=20\n" + "obsoletes=1\n"
62 + "gpgcheck=0\n" + "assumeyes=1\n" + "syslog_ident=mock\n"
63 + "syslog_device=\n" + "http_caching=none\n";
64
65 private String defaultMacroFiles = "/usr/lib/rpm/macros:"
66 + "/usr/lib/rpm/ia32e-linux/macros:"
67 + "/usr/lib/rpm/redhat/macros:" + "/etc/rpm/macros.*:"
68 + "/etc/rpm/macros:" + "/etc/rpm/ia32e-linux/macros:"
69 + "~/.rpmmacros";
70 private Map<String, String> rpmmacros = new HashMap<String, String>();
71
72 // set by init
73 private String proxiedReposBase;
74 private String managedReposBase;
75
76 private String stagingWorkspace;
77 private String testingWorkspace;
78 private String stableWorkspace;
79
80 private File rpmFactoryBaseDir;
81 private File mockConfDir;
82 private File yumConfDir;
83
84 public void init() {
85 // local URL bases
86 proxiedReposBase = localUrlBase + "repo/rpm/";
87 managedReposBase = localUrlBase + "data/public/rpm/";
88
89 // local directories
90 rpmFactoryBaseDir.mkdirs();
91 mockConfDir = new File(rpmFactoryBaseDir.getPath() + "/conf/mock");
92 mockConfDir.mkdirs();
93 yumConfDir = new File(rpmFactoryBaseDir.getPath() + "/conf/yum");
94 yumConfDir.mkdirs();
95
96 // managed repositories
97 stagingWorkspace = id + "-staging";
98 if (withTestingRepository)
99 testingWorkspace = id + "-testing";
100 stableWorkspace = id;
101
102 initDistWorkspace(stableWorkspace);
103 initGitWorkspace();
104 initRpmWorkspace(stagingWorkspace);
105 if (withTestingRepository)
106 initRpmWorkspace(testingWorkspace);
107 initRpmWorkspace(stableWorkspace);
108 }
109
110 protected void initRpmWorkspace(String workspace) {
111 Session session = null;
112 try {
113 session = JcrUtils.loginOrCreateWorkspace(rpmRepository, workspace);
114 JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read");
115 JcrUtils.addPrivilege(session, "/", SlcConstants.ROLE_SLC,
116 "jcr:all");
117
118 for (String arch : archs) {
119 Node archFolder = JcrUtils.mkfolders(session, "/" + arch);
120 session.save();
121 File workspaceDir = getWorkspaceDir(workspace);
122 try {
123 if (!archFolder.hasNode("repodata")) {
124 // touch a file in order to make sure this is properly
125 // mounted.
126 File touch = new File(workspaceDir, ".touch");
127 touch.createNewFile();
128 touch.delete();
129
130 SystemCall createrepo = new SystemCall();
131 createrepo.arg("createrepo");
132 createrepo.arg("-q");
133 File archDir = new File(workspaceDir, arch);
134 createrepo.arg(archDir.getAbsolutePath());
135 createrepo.run();
136 }
137 } catch (IOException e) {
138 log.error(workspaceDir + " not properly mounted.", e);
139 }
140 }
141 } catch (Exception e) {
142 throw new SlcException("Cannot initialize workspace " + workspace,
143 e);
144 } finally {
145 JcrUtils.logoutQuietly(session);
146 }
147 }
148
149 /** Caller must logout the underlying session. */
150 public Node newDistribution(String distributionId) {
151 Session session = null;
152 try {
153 session = JcrUtils.loginOrCreateWorkspace(rpmRepository,
154 distributionId);
155 JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read");
156 JcrUtils.addPrivilege(session, "/", SlcConstants.ROLE_SLC,
157 "jcr:all");
158
159 Calendar now = new GregorianCalendar();
160 String folderName = dateFormat.format(now.getTime());
161 return JcrUtils.mkfolders(session, "/" + folderName);
162 } catch (Exception e) {
163 JcrUtils.logoutQuietly(session);
164 throw new SlcException("Cannot initialize distribution workspace "
165 + distributionId, e);
166 }
167 }
168
169 protected void initGitWorkspace() {
170 Session session = null;
171 try {
172 session = JcrUtils.loginOrCreateWorkspace(rpmRepository,
173 gitWorkspace);
174 JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read");
175 JcrUtils.addPrivilege(session, "/", SlcConstants.ROLE_SLC,
176 "jcr:all");
177 } catch (Exception e) {
178 throw new SlcException("Cannot initialize workspace "
179 + gitWorkspace, e);
180 } finally {
181 JcrUtils.logoutQuietly(session);
182 }
183 }
184
185 protected void initDistWorkspace(String workspace) {
186 Session session = null;
187 try {
188 session = JcrUtils
189 .loginOrCreateWorkspace(distRepository, workspace);
190 JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read");
191 } catch (RepositoryException e) {
192 throw new SlcException("Cannot initialize workspace " + workspace,
193 e);
194 } finally {
195 JcrUtils.logoutQuietly(session);
196 }
197 }
198
199 public void destroy() {
200
201 }
202
203 public String generateMockConfigFile(String arch, String branch) {
204 StringBuffer buf = new StringBuffer();
205
206 buf.append("config_opts['root'] = '" + getIdWithArch(arch) + "'\n");
207 buf.append("config_opts['target_arch'] = '" + arch + "'\n");
208 buf.append("config_opts['legal_host_arches'] = ('" + arch + "',)\n");
209 buf.append("config_opts['chroot_setup_cmd'] = 'groupinstall buildsys-build'\n");
210 // buf.append("config_opts['dist'] = 'el6'\n");
211 buf.append("config_opts['plugin_conf']['yum_cache_enable'] = False\n");
212
213 buf.append("config_opts['scm'] = False\n");
214 buf.append("config_opts['scm_opts']['method'] = 'git'\n");
215 buf.append("config_opts['scm_opts']['spec'] = 'SCM_PKG.spec'\n");
216 buf.append("config_opts['scm_opts']['ext_src_dir'] = '"
217 + getSourcesDir().getAbsolutePath() + "'\n");
218 buf.append("config_opts['scm_opts']['git_timestamps'] = True\n");
219
220 // development
221 if (gitDevBaseUrl != null && !gitDevBaseUrl.trim().equals(""))
222 buf.append("config_opts['scm_opts']['git_get'] = 'git clone "
223 + (branch != null ? "-b " + branch : "") + " "
224 + gitDevBaseUrl + "/SCM_PKG SCM_PKG'\n");
225 else
226 buf.append("config_opts['scm_opts']['git_get'] = 'git clone "
227 + (branch != null ? "-b " + branch : "") + " "
228 + getGitBaseUrl() + "/SCM_PKG.git SCM_PKG'\n");
229
230 buf.append("\nconfig_opts['yum.conf'] = \"\"\"\n");
231 buf.append(generateYumConfigFile(arch)).append('\n');
232 buf.append("\"\"\"\n");
233 return buf.toString();
234 }
235
236 public String generateYumConfigFile(String arch) {
237 StringBuffer buf = new StringBuffer();
238 buf.append("[main]\n");
239 buf.append(yumConfigMainSection).append('\n');
240
241 for (RpmRepository repository : repositories) {
242 buf.append('[').append(repository.getId()).append("]\n");
243 buf.append("name=").append(repository.getId()).append('\n');
244 if (repository instanceof ThirdPartyRpmRepository) {
245 buf.append("#baseurl=").append(repository.getUrl())
246 .append(arch).append('/').append("\n");
247 buf.append("baseurl=").append(proxiedReposBase)
248 .append(repository.getId()).append('/').append(arch)
249 .append('/').append("\n");
250 if (((ThirdPartyRpmRepository) repository).getYumConf() != null)
251 buf.append(
252 ((ThirdPartyRpmRepository) repository).getYumConf()
253 .trim()).append('\n');
254 }
255 }
256
257 // managed repos
258 addManagedRepository(buf, stagingWorkspace, arch);
259 if (withTestingRepository)
260 addManagedRepository(buf, testingWorkspace, arch);
261 addManagedRepository(buf, stableWorkspace, arch);
262 return buf.toString();
263 }
264
265 protected void addManagedRepository(StringBuffer buf, String workspace,
266 String arch) {
267 buf.append('[').append(workspace).append("]\n");
268 buf.append("baseurl=").append(managedReposBase).append(workspace)
269 .append('/').append(arch).append('/').append("\n");
270 buf.append("gpgcheck=0").append("\n");
271 }
272
273 /** Creates a mock config file. */
274 public File getMockConfigFile(String arch, String branch) {
275 File mockSiteDefaultsFile = new File(mockConfDir, "site-defaults.cfg");
276 File mockLoggingFile = new File(mockConfDir, "logging.ini");
277 File mockConfigFile = new File(mockConfDir, getIdWithArch(arch)
278 + ".cfg");
279 try {
280 if (!mockSiteDefaultsFile.exists())
281 mockSiteDefaultsFile.createNewFile();
282 if (!mockLoggingFile.exists())
283 FileUtils.copyFile(new File(mockEtc + "/logging.ini"),
284 mockLoggingFile);
285
286 FileUtils.writeStringToFile(mockConfigFile,
287 generateMockConfigFile(arch, branch));
288 return mockConfigFile;
289 } catch (IOException e) {
290 throw new SlcException("Cannot write mock config file to "
291 + mockConfigFile, e);
292 }
293 }
294
295 /** Creates a yum config file. */
296 public File getYumRepoFile(String arch) {
297 File yumConfigFile = new File(yumConfDir, getIdWithArch(arch) + ".repo");
298 try {
299 FileUtils.writeStringToFile(yumConfigFile,
300 generateYumConfigFile(arch));
301 return yumConfigFile;
302 } catch (IOException e) {
303 throw new SlcException("Cannot write yum config file to "
304 + yumConfigFile, e);
305 }
306 }
307
308 public File getResultDir(String arch) {
309 return new File(mockVar + "/" + getIdWithArch(arch) + "/result");
310 }
311
312 public File getWorkspaceDir(String workspace) {
313 return new File(rpmBase + "/" + workspace);
314 }
315
316 public File getSourcesDir() {
317 return new File(distBase + "/" + stableWorkspace);
318 }
319
320 public String getMockConfig(String arch) {
321 return getIdWithArch(arch);
322 }
323
324 public String getIdWithArch(String arch) {
325 return id + "-" + arch;
326 }
327
328 public String getGitBaseUrl() {
329 return managedReposBase + gitWorkspace;
330 }
331
332 public void indexWorkspace(String workspace) {
333 Session session = null;
334 try {
335 session = rpmRepository.login(workspace);
336 session.getRootNode().accept(
337 new NodeIndexerVisitor(new RpmIndexer()));
338 if (log.isDebugEnabled())
339 log.debug("Indexed workspace " + workspace);
340 } catch (RepositoryException e) {
341 throw new SlcException("Cannot index workspace " + workspace, e);
342 } finally {
343 JcrUtils.logoutQuietly(session);
344 }
345 }
346
347 public Boolean isDeveloperInstance() {
348 return gitDevBaseUrl != null;
349 }
350
351 /** Write (topdir)/rpmmacros and (topdir)/rpmrc */
352 public void writeRpmbuildConfigFiles(File topdir) {
353 writeRpmbuildConfigFiles(topdir, new File(topdir, "rpmmacros"),
354 new File(topdir, "rpmrc"));
355 }
356
357 public void writeRpmbuildConfigFiles(File topdir, File rpmmacroFile,
358 File rpmrcFile) {
359 try {
360 List<String> macroLines = new ArrayList<String>();
361 macroLines.add("%_topdir " + topdir.getCanonicalPath());
362 for (String macroKey : rpmmacros.keySet()) {
363 macroLines.add(macroKey + " " + rpmmacros.get(macroKey));
364 }
365 FileUtils.writeLines(rpmmacroFile, macroLines);
366
367 List<String> rpmrcLines = new ArrayList<String>();
368 rpmrcLines.add("include: /usr/lib/rpm/rpmrc");
369 rpmrcLines.add("macrofiles: " + defaultMacroFiles + ":"
370 + rpmmacroFile.getCanonicalPath());
371 FileUtils.writeLines(rpmrcFile, rpmrcLines);
372 } catch (IOException e) {
373 throw new SlcException("Cannot write rpmbuild config files", e);
374 }
375
376 }
377
378 public Map<String, String> getRpmmacros() {
379 return rpmmacros;
380 }
381
382 public void setRpmmacros(Map<String, String> rpmmacros) {
383 this.rpmmacros = rpmmacros;
384 }
385
386 public String getDefaultMacroFiles() {
387 return defaultMacroFiles;
388 }
389
390 public void setDefaultMacroFiles(String defaultMacroFiles) {
391 this.defaultMacroFiles = defaultMacroFiles;
392 }
393
394 public void setArchs(List<String> archs) {
395 this.archs = archs;
396 }
397
398 public List<String> getArchs() {
399 return archs;
400 }
401
402 public void setRpmBase(String stagingBase) {
403 this.rpmBase = stagingBase;
404 }
405
406 public void setId(String id) {
407 this.id = id;
408 }
409
410 public void setMockVar(String mockVar) {
411 this.mockVar = mockVar;
412 }
413
414 public void setRpmRepository(Repository rpmRepository) {
415 this.rpmRepository = rpmRepository;
416 }
417
418 public void setDistRepository(Repository distRepository) {
419 this.distRepository = distRepository;
420 }
421
422 public void setLocalUrlBase(String localUrlBase) {
423 this.localUrlBase = localUrlBase;
424 }
425
426 public void setYumConfigMainSection(String yumConfigMainSection) {
427 this.yumConfigMainSection = yumConfigMainSection;
428 }
429
430 public void setRepositories(List<RpmRepository> repositories) {
431 this.repositories = repositories;
432 }
433
434 public void setRpmFactoryBaseDir(File rpmFactoryBaseDir) {
435 this.rpmFactoryBaseDir = rpmFactoryBaseDir;
436 }
437
438 public String getStagingWorkspace() {
439 return stagingWorkspace;
440 }
441
442 public String getTestingWorkspace() {
443 return testingWorkspace;
444 }
445
446 public String getStableWorkspace() {
447 return stableWorkspace;
448 }
449
450 public void setWithTestingRepository(Boolean withTestingRepository) {
451 this.withTestingRepository = withTestingRepository;
452 }
453
454 public void setGitDevBaseUrl(String gitBaseUrl) {
455 this.gitDevBaseUrl = gitBaseUrl;
456 }
457 }