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