]> git.argeo.org Git - gpl/argeo-slc.git/blob - legacy/org.argeo.slc.support/src/org/argeo/slc/lib/linux/rpmfactory/CreateSrpm.java
Massive Argeo APIs refactoring
[gpl/argeo-slc.git] / legacy / org.argeo.slc.support / src / org / argeo / slc / lib / linux / rpmfactory / CreateSrpm.java
1 package org.argeo.slc.lib.linux.rpmfactory;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.apache.commons.exec.Executor;
11 import org.apache.commons.io.FileUtils;
12 import org.apache.commons.io.IOUtils;
13 import org.argeo.api.cms.CmsLog;
14 import org.argeo.slc.SlcException;
15 import org.argeo.slc.core.execution.tasks.SystemCall;
16 import org.springframework.core.io.Resource;
17 import org.springframework.core.io.UrlResource;
18
19 /** Generates an SRPM from a spec file */
20 public class CreateSrpm implements Runnable {
21 private final static CmsLog log = CmsLog.getLog(CreateSrpm.class);
22
23 private File topdir;
24
25 /** Directory where to cache downloaded distributions. */
26 private File distributionCache;
27
28 private Resource specFile;
29
30 private RpmBuildEnvironment rpmBuildEnvironment;
31
32 private Boolean overwriteSources = false;
33
34 private File srpmFile;
35
36 private Executor executor;
37
38 public void run() {
39 File sourcesDir = new File(topdir, "SOURCES");
40 sourcesDir.mkdirs();
41 File specsDir = new File(topdir, "SPECS");
42 File srpmsDir = new File(topdir, "SRPMS");
43
44 try {
45 // Parse spec file and copy required resources
46 RpmSpecFile spec = new RpmSpecFile(specFile);
47 copyToSources(spec, sourcesDir);
48
49 // Copy spec file
50 File targetFile = new File(specsDir, specFile.getFilename())
51 .getCanonicalFile();
52 copyResourceToFile(specFile, targetFile);
53
54 // Generate rpmbuild config files
55 rpmBuildEnvironment.writeRpmbuildConfigFiles(topdir);
56
57 // Build SRPM
58 srpmsDir.mkdirs();
59 SystemCall packageSrpm = new SystemCall();
60 packageSrpm.arg("rpmbuild");
61 packageSrpm.arg("-bs").arg("--nodeps");
62 packageSrpm.arg("--rcfile=rpmrc");
63 packageSrpm.arg("--macros=" + RpmBuildEnvironment.defaultMacroFiles
64 + ":rpmmacros");
65 // buildSrpm.arg("-D", "_topdir " + topdir.getCanonicalPath() + "");
66 packageSrpm.arg("SPECS/" + specFile.getFilename());
67 packageSrpm.setExecDir(topdir.getCanonicalPath());
68 packageSrpm.setLogCommand(true);
69
70 // Execute
71 packageSrpm.setExecutor(executor);
72 String answer = packageSrpm.function();
73
74 // Extract generated SRPM path
75 // TODO: make it safer
76 String srpmPath = answer.split(":")[1].trim();
77 srpmFile = new File(srpmPath);
78 } catch (IOException e) {
79 throw new SlcException("Cannot generate SRPM from " + specFile, e);
80 }
81
82 }
83
84 protected void copyToSources(RpmSpecFile spec, File sourcesDir) {
85 try {
86 List<Resource> toCopyToSources = new ArrayList<Resource>();
87 List<Resource> toDownload = new ArrayList<Resource>();
88 for (String file : spec.getSources().values()) {
89 try {
90 Resource res;
91 try {
92 res = specFile.createRelative("../SOURCES/" + file);
93 if (!res.exists())
94 res = new UrlResource(file);
95
96 } catch (Exception e) {
97 res = new UrlResource(file);
98 toDownload.add(res);
99 }
100 toCopyToSources.add(res);
101 } catch (Exception e) {
102 log.error("Cannot interpret " + file, e);
103 }
104 }
105 for (String file : spec.getPatches().values()) {
106 try {
107 Resource res;
108 try {
109 res = specFile.createRelative("../SOURCES/" + file);
110 if (!res.exists()) {
111 res = new UrlResource(file);
112 }
113 } catch (Exception e) {
114 res = new UrlResource(file);
115 toDownload.add(res);
116 }
117 toCopyToSources.add(res);
118 } catch (Exception e) {
119 log.error("Cannot interpret " + file, e);
120 }
121 }
122
123 // FIXME: we may have missed some files here
124 for (Resource res : toCopyToSources) {
125 File targetDir;
126 if (distributionCache != null && toDownload.contains(res)) {
127 if (!distributionCache.exists())
128 distributionCache.mkdirs();
129 targetDir = distributionCache;
130 if (log.isDebugEnabled())
131 log.debug("Cache " + res + " in " + targetDir);
132 } else
133 targetDir = sourcesDir;
134 File targetFile = new File(targetDir, res.getFilename())
135 .getCanonicalFile();
136 if (!targetFile.exists() || overwriteSources)
137 copyResourceToFile(res, targetFile);
138 if (!targetDir.equals(sourcesDir)) {
139 File fileInSourcesDir = new File(sourcesDir,
140 targetFile.getName());
141 if (!fileInSourcesDir.exists()
142 || !(fileInSourcesDir.length() == targetFile
143 .length()))
144 FileUtils.copyFile(targetFile, fileInSourcesDir);
145 }
146 }
147 } catch (Exception e) {
148 throw new SlcException("Cannot copy to " + sourcesDir, e);
149 }
150 }
151
152 private static void copyResourceToFile(Resource res, File targetFile) {
153 try {
154 if (targetFile.equals(res.getFile())) {
155 if (log.isDebugEnabled())
156 log.debug("Target identical to source, skipping... "
157 + targetFile + " <=> " + res);
158 return;
159 }
160 } catch (IOException e1) {
161 // silent
162 }
163
164 OutputStream out = null;
165 InputStream in = null;
166 try {
167 out = FileUtils.openOutputStream(targetFile);
168 in = res.getInputStream();
169 IOUtils.copy(in, out);
170 if (log.isDebugEnabled())
171 log.debug("Copied " + targetFile + " from " + res);
172 } catch (Exception e) {
173 throw new SlcException("Cannot copy " + res + " to " + targetFile,
174 e);
175 } finally {
176 IOUtils.closeQuietly(in);
177 IOUtils.closeQuietly(out);
178 }
179
180 }
181
182 public void setSpecFile(Resource specFile) {
183 this.specFile = specFile;
184 }
185
186 public void setTopdir(File topdir) {
187 this.topdir = topdir;
188 }
189
190 public void setOverwriteSources(Boolean overwriteSources) {
191 this.overwriteSources = overwriteSources;
192 }
193
194 public File getSrpmFile() {
195 return srpmFile;
196 }
197
198 public void setRpmBuildEnvironment(RpmBuildEnvironment rpmBuildEnvironment) {
199 this.rpmBuildEnvironment = rpmBuildEnvironment;
200 }
201
202 public void setDistributionCache(File distributionCache) {
203 this.distributionCache = distributionCache;
204 }
205
206 public void setExecutor(Executor executor) {
207 this.executor = executor;
208 }
209
210 }