1 package org
.argeo
.slc
.rpmfactory
.core
;
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
;
14 import javax
.jcr
.Node
;
15 import javax
.jcr
.Repository
;
16 import javax
.jcr
.RepositoryException
;
17 import javax
.jcr
.Session
;
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
.repo
.RpmIndexer
;
27 import org
.argeo
.slc
.rpmfactory
.RpmFactory
;
28 import org
.argeo
.slc
.rpmfactory
.RpmRepository
;
29 import org
.argeo
.slc
.runtime
.tasks
.SystemCall
;
32 * Defines a build environment. This information is typically used by other
33 * components performing the various actions related to RPM build.
35 public class RpmFactoryImpl
implements RpmFactory
{
36 private Log log
= LogFactory
.getLog(RpmFactoryImpl
.class);
38 private Repository rpmRepository
;
39 private Repository distRepository
;
42 private List
<RpmRepository
> repositories
= new ArrayList
<RpmRepository
>();
43 private List
<String
> archs
= new ArrayList
<String
>();
45 private String rpmBase
= "/mnt/slc/repos/rpm";
46 private String distBase
= "/mnt/slc/repos/dist";
47 private String mockVar
= "/var/lib/mock";
48 private String mockEtc
= "/etc/mock";
50 private DateFormat dateFormat
= new SimpleDateFormat("yyyyMMdd_HHmm");
52 private String gitWorkspace
= "git";
54 private String localUrlBase
= "http://localhost:7070/";
55 /** If not null or empty, this is a developer instance. */
56 private String gitDevBaseUrl
= null;
58 private Boolean withTestingRepository
= false;
60 private String yumConfigMainSection
= "cachedir=/var/cache/yum\n"
61 + "debuglevel=1\n" + "reposdir=/dev/null\n"
62 + "logfile=/var/log/yum.log\n" + "retries=20\n" + "obsoletes=1\n"
63 + "gpgcheck=0\n" + "assumeyes=1\n" + "syslog_ident=mock\n"
64 + "syslog_device=\n" + "http_caching=none\n";
66 private String defaultMacroFiles
= "/usr/lib/rpm/macros:"
67 + "/usr/lib/rpm/ia32e-linux/macros:"
68 + "/usr/lib/rpm/redhat/macros:" + "/etc/rpm/macros.*:"
69 + "/etc/rpm/macros:" + "/etc/rpm/ia32e-linux/macros:"
71 private Map
<String
, String
> rpmmacros
= new HashMap
<String
, String
>();
74 private String proxiedReposBase
;
75 private String managedReposBase
;
77 private String stagingWorkspace
;
78 private String testingWorkspace
;
79 private String stableWorkspace
;
81 private File rpmFactoryBaseDir
;
82 private File mockConfDir
;
83 private File yumConfDir
;
87 proxiedReposBase
= localUrlBase
+ "repo/rpm/";
88 managedReposBase
= localUrlBase
+ "data/public/rpm/";
91 rpmFactoryBaseDir
.mkdirs();
92 mockConfDir
= new File(rpmFactoryBaseDir
.getPath() + "/conf/mock");
94 yumConfDir
= new File(rpmFactoryBaseDir
.getPath() + "/conf/yum");
97 // managed repositories
98 stagingWorkspace
= id
+ "-staging";
99 if (withTestingRepository
)
100 testingWorkspace
= id
+ "-testing";
101 stableWorkspace
= id
;
103 initDistWorkspace(stableWorkspace
);
105 initRpmWorkspace(stagingWorkspace
);
106 if (withTestingRepository
)
107 initRpmWorkspace(testingWorkspace
);
108 initRpmWorkspace(stableWorkspace
);
111 protected void initRpmWorkspace(String workspace
) {
112 Session session
= null;
114 session
= JcrUtils
.loginOrCreateWorkspace(rpmRepository
, workspace
);
115 JcrUtils
.addPrivilege(session
, "/", "anonymous", "jcr:read");
116 JcrUtils
.addPrivilege(session
, "/", SlcConstants
.ROLE_SLC
,
119 for (String arch
: archs
) {
120 Node archFolder
= JcrUtils
.mkfolders(session
, "/" + arch
);
122 File workspaceDir
= getWorkspaceDir(workspace
);
124 if (!archFolder
.hasNode("repodata")) {
125 // touch a file in order to make sure this is properly
127 File touch
= new File(workspaceDir
, ".touch");
128 touch
.createNewFile();
131 SystemCall createrepo
= new SystemCall();
132 createrepo
.arg("createrepo");
133 createrepo
.arg("-q");
134 File archDir
= new File(workspaceDir
, arch
);
135 createrepo
.arg(archDir
.getAbsolutePath());
138 } catch (IOException e
) {
139 log
.error(workspaceDir
+ " not properly mounted.", e
);
142 } catch (Exception e
) {
143 throw new SlcException("Cannot initialize workspace " + workspace
,
146 JcrUtils
.logoutQuietly(session
);
150 /** Caller must logout the underlying session. */
151 public Node
newDistribution(String distributionId
) {
152 Session session
= null;
154 session
= JcrUtils
.loginOrCreateWorkspace(rpmRepository
,
156 JcrUtils
.addPrivilege(session
, "/", "anonymous", "jcr:read");
157 JcrUtils
.addPrivilege(session
, "/", SlcConstants
.ROLE_SLC
,
160 Calendar now
= new GregorianCalendar();
161 String folderName
= dateFormat
.format(now
.getTime());
162 return JcrUtils
.mkfolders(session
, "/" + folderName
);
163 } catch (Exception e
) {
164 JcrUtils
.logoutQuietly(session
);
165 throw new SlcException("Cannot initialize distribution workspace "
166 + distributionId
, e
);
170 protected void initGitWorkspace() {
171 Session session
= null;
173 session
= JcrUtils
.loginOrCreateWorkspace(rpmRepository
,
175 JcrUtils
.addPrivilege(session
, "/", "anonymous", "jcr:read");
176 JcrUtils
.addPrivilege(session
, "/", SlcConstants
.ROLE_SLC
,
178 } catch (Exception e
) {
179 throw new SlcException("Cannot initialize workspace "
182 JcrUtils
.logoutQuietly(session
);
186 protected void initDistWorkspace(String workspace
) {
187 Session session
= null;
190 .loginOrCreateWorkspace(distRepository
, workspace
);
191 JcrUtils
.addPrivilege(session
, "/", "anonymous", "jcr:read");
192 } catch (RepositoryException e
) {
193 throw new SlcException("Cannot initialize workspace " + workspace
,
196 JcrUtils
.logoutQuietly(session
);
200 public void destroy() {
204 public String
generateMockConfigFile(String arch
, String branch
) {
205 StringBuffer buf
= new StringBuffer();
207 buf
.append("config_opts['root'] = '" + getIdWithArch(arch
) + "'\n");
208 buf
.append("config_opts['target_arch'] = '" + arch
+ "'\n");
209 buf
.append("config_opts['legal_host_arches'] = ('" + arch
+ "',)\n");
210 buf
.append("config_opts['chroot_setup_cmd'] = 'groupinstall buildsys-build'\n");
211 // buf.append("config_opts['dist'] = 'el6'\n");
212 buf
.append("config_opts['plugin_conf']['yum_cache_enable'] = False\n");
214 buf
.append("config_opts['scm'] = False\n");
215 buf
.append("config_opts['scm_opts']['method'] = 'git'\n");
216 buf
.append("config_opts['scm_opts']['spec'] = 'SCM_PKG.spec'\n");
217 buf
.append("config_opts['scm_opts']['ext_src_dir'] = '"
218 + getSourcesDir().getAbsolutePath() + "'\n");
219 buf
.append("config_opts['scm_opts']['git_timestamps'] = True\n");
222 if (gitDevBaseUrl
!= null && !gitDevBaseUrl
.trim().equals(""))
223 buf
.append("config_opts['scm_opts']['git_get'] = 'git clone "
224 + (branch
!= null ?
"-b " + branch
: "") + " "
225 + gitDevBaseUrl
+ "/SCM_PKG SCM_PKG'\n");
227 buf
.append("config_opts['scm_opts']['git_get'] = 'git clone "
228 + (branch
!= null ?
"-b " + branch
: "") + " "
229 + getGitBaseUrl() + "/SCM_PKG.git SCM_PKG'\n");
231 buf
.append("\nconfig_opts['yum.conf'] = \"\"\"\n");
232 buf
.append(generateYumConfigFile(arch
)).append('\n');
233 buf
.append("\"\"\"\n");
234 return buf
.toString();
237 public String
generateYumConfigFile(String arch
) {
238 StringBuffer buf
= new StringBuffer();
239 buf
.append("[main]\n");
240 buf
.append(yumConfigMainSection
).append('\n');
242 for (RpmRepository repository
: repositories
) {
243 buf
.append('[').append(repository
.getId()).append("]\n");
244 buf
.append("name=").append(repository
.getId()).append('\n');
245 if (repository
instanceof ThirdPartyRpmRepository
) {
246 buf
.append("#baseurl=").append(repository
.getUrl())
247 .append(arch
).append('/').append("\n");
248 buf
.append("baseurl=").append(proxiedReposBase
)
249 .append(repository
.getId()).append('/').append(arch
)
250 .append('/').append("\n");
251 if (((ThirdPartyRpmRepository
) repository
).getYumConf() != null)
253 ((ThirdPartyRpmRepository
) repository
).getYumConf()
254 .trim()).append('\n');
259 addManagedRepository(buf
, stagingWorkspace
, arch
);
260 if (withTestingRepository
)
261 addManagedRepository(buf
, testingWorkspace
, arch
);
262 addManagedRepository(buf
, stableWorkspace
, arch
);
263 return buf
.toString();
266 protected void addManagedRepository(StringBuffer buf
, String workspace
,
268 buf
.append('[').append(workspace
).append("]\n");
269 buf
.append("baseurl=").append(managedReposBase
).append(workspace
)
270 .append('/').append(arch
).append('/').append("\n");
271 buf
.append("gpgcheck=0").append("\n");
274 /** Creates a mock config file. */
275 public File
getMockConfigFile(String arch
, String branch
) {
276 File mockSiteDefaultsFile
= new File(mockConfDir
, "site-defaults.cfg");
277 File mockLoggingFile
= new File(mockConfDir
, "logging.ini");
278 File mockConfigFile
= new File(mockConfDir
, getIdWithArch(arch
)
281 if (!mockSiteDefaultsFile
.exists())
282 mockSiteDefaultsFile
.createNewFile();
283 if (!mockLoggingFile
.exists())
284 FileUtils
.copyFile(new File(mockEtc
+ "/logging.ini"),
287 FileUtils
.writeStringToFile(mockConfigFile
,
288 generateMockConfigFile(arch
, branch
));
289 return mockConfigFile
;
290 } catch (IOException e
) {
291 throw new SlcException("Cannot write mock config file to "
292 + mockConfigFile
, e
);
296 /** Creates a yum config file. */
297 public File
getYumRepoFile(String arch
) {
298 File yumConfigFile
= new File(yumConfDir
, getIdWithArch(arch
) + ".repo");
300 FileUtils
.writeStringToFile(yumConfigFile
,
301 generateYumConfigFile(arch
));
302 return yumConfigFile
;
303 } catch (IOException e
) {
304 throw new SlcException("Cannot write yum config file to "
309 public File
getResultDir(String arch
) {
310 return new File(mockVar
+ "/" + getIdWithArch(arch
) + "/result");
313 public File
getWorkspaceDir(String workspace
) {
314 return new File(rpmBase
+ "/" + workspace
);
317 public File
getSourcesDir() {
318 return new File(distBase
+ "/" + stableWorkspace
);
321 public String
getMockConfig(String arch
) {
322 return getIdWithArch(arch
);
325 public String
getIdWithArch(String arch
) {
326 return id
+ "-" + arch
;
329 public String
getGitBaseUrl() {
330 return managedReposBase
+ gitWorkspace
;
333 public void indexWorkspace(String workspace
) {
334 Session session
= null;
336 session
= rpmRepository
.login(workspace
);
337 session
.getRootNode().accept(
338 new NodeIndexerVisitor(new RpmIndexer()));
339 if (log
.isDebugEnabled())
340 log
.debug("Indexed workspace " + workspace
);
341 } catch (RepositoryException e
) {
342 throw new SlcException("Cannot index workspace " + workspace
, e
);
344 JcrUtils
.logoutQuietly(session
);
348 public Boolean
isDeveloperInstance() {
349 return gitDevBaseUrl
!= null;
352 /** Write (topdir)/rpmmacros and (topdir)/rpmrc */
353 public void writeRpmbuildConfigFiles(File topdir
) {
354 writeRpmbuildConfigFiles(topdir
, new File(topdir
, "rpmmacros"),
355 new File(topdir
, "rpmrc"));
358 public void writeRpmbuildConfigFiles(File topdir
, File rpmmacroFile
,
361 List
<String
> macroLines
= new ArrayList
<String
>();
362 macroLines
.add("%_topdir " + topdir
.getCanonicalPath());
363 for (String macroKey
: rpmmacros
.keySet()) {
364 macroLines
.add(macroKey
+ " " + rpmmacros
.get(macroKey
));
366 FileUtils
.writeLines(rpmmacroFile
, macroLines
);
368 List
<String
> rpmrcLines
= new ArrayList
<String
>();
369 rpmrcLines
.add("include: /usr/lib/rpm/rpmrc");
370 rpmrcLines
.add("macrofiles: " + defaultMacroFiles
+ ":"
371 + rpmmacroFile
.getCanonicalPath());
372 FileUtils
.writeLines(rpmrcFile
, rpmrcLines
);
373 } catch (IOException e
) {
374 throw new SlcException("Cannot write rpmbuild config files", e
);
379 public Map
<String
, String
> getRpmmacros() {
383 public void setRpmmacros(Map
<String
, String
> rpmmacros
) {
384 this.rpmmacros
= rpmmacros
;
387 public String
getDefaultMacroFiles() {
388 return defaultMacroFiles
;
391 public void setDefaultMacroFiles(String defaultMacroFiles
) {
392 this.defaultMacroFiles
= defaultMacroFiles
;
395 public void setArchs(List
<String
> archs
) {
399 public List
<String
> getArchs() {
403 public void setRpmBase(String stagingBase
) {
404 this.rpmBase
= stagingBase
;
407 public void setId(String id
) {
411 public void setMockVar(String mockVar
) {
412 this.mockVar
= mockVar
;
415 public void setRpmRepository(Repository rpmRepository
) {
416 this.rpmRepository
= rpmRepository
;
419 public void setDistRepository(Repository distRepository
) {
420 this.distRepository
= distRepository
;
423 public void setLocalUrlBase(String localUrlBase
) {
424 this.localUrlBase
= localUrlBase
;
427 public void setYumConfigMainSection(String yumConfigMainSection
) {
428 this.yumConfigMainSection
= yumConfigMainSection
;
431 public void setRepositories(List
<RpmRepository
> repositories
) {
432 this.repositories
= repositories
;
435 public void setRpmFactoryBaseDir(File rpmFactoryBaseDir
) {
436 this.rpmFactoryBaseDir
= rpmFactoryBaseDir
;
439 public String
getStagingWorkspace() {
440 return stagingWorkspace
;
443 public String
getTestingWorkspace() {
444 return testingWorkspace
;
447 public String
getStableWorkspace() {
448 return stableWorkspace
;
451 public void setWithTestingRepository(Boolean withTestingRepository
) {
452 this.withTestingRepository
= withTestingRepository
;
455 public void setGitDevBaseUrl(String gitBaseUrl
) {
456 this.gitDevBaseUrl
= gitBaseUrl
;