]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/linux/rpmfactory/CreateSrpm.java
e48df91433127d8921c98348b24aadf81be7c8a1
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.simple / src / main / java / 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.io.FileUtils;
11 import org.apache.commons.io.IOUtils;
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
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 Log log = LogFactory.getLog(CreateSrpm.class);
22
23 private File topdir;
24
25 private Resource specFile;
26
27 private RpmBuildEnvironment rpmBuildEnvironment;
28
29 private Boolean overwriteSources = false;
30
31 private File srpmFile;
32
33 public void run() {
34 File sourcesDir = new File(topdir, "SOURCES");
35 sourcesDir.mkdirs();
36 File specsDir = new File(topdir, "SPECS");
37 File srpmsDir = new File(topdir, "SRPMS");
38
39 try {
40 // Parse spec file and copy required resources
41 RpmSpecFile spec = new RpmSpecFile(specFile);
42 copyToSources(spec, sourcesDir);
43
44 // Copy spec file
45 File targetFile = new File(specsDir, specFile.getFilename())
46 .getCanonicalFile();
47 copyResourceToFile(specFile, targetFile);
48
49 // Generate rpmbuild config files
50 File rpmmacroFile = new File(topdir, "rpmmacros");
51 File rpmrcFile = new File(topdir, "rpmrc");
52 rpmBuildEnvironment.writeRpmbuildConfigFiles(topdir, rpmmacroFile,
53 rpmrcFile);
54
55 // Build SRPM
56 srpmsDir.mkdirs();
57 SystemCall packageSrpm = new SystemCall();
58 packageSrpm.arg("rpmbuild");
59 packageSrpm.arg("-bs").arg("--nodeps");
60 packageSrpm.arg("--rcfile=" + rpmrcFile.getName());
61 // buildSrpm.arg("-D", "_topdir " + topdir.getCanonicalPath() + "");
62 packageSrpm.arg("SPECS/" + specFile.getFilename());
63 packageSrpm.setExecDir(topdir.getCanonicalPath());
64 packageSrpm.setLogCommand(true);
65
66 // Execute
67 String answer = packageSrpm.function();
68
69 // Extract generated SRPM path
70 // TODO: make it safer
71 String srpmPath = answer.split(":")[1].trim();
72 srpmFile = new File(srpmPath);
73 } catch (IOException e) {
74 throw new SlcException("Cannot generate SRPM from " + specFile, e);
75 }
76
77 }
78
79 protected void copyToSources(RpmSpecFile spec, File sourcesDir) {
80 try {
81 List<Resource> toCopyToSources = new ArrayList<Resource>();
82 for (String file : spec.getSources().values()) {
83 try {
84 Resource res;
85 try {
86 res = specFile.createRelative("../SOURCES/" + file);
87 if (!res.exists())
88 res = new UrlResource(file);
89
90 } catch (Exception e) {
91 res = new UrlResource(file);
92 }
93 toCopyToSources.add(res);
94 } catch (Exception e) {
95 log.error("Cannot interpret " + file, e);
96 }
97 }
98 for (String file : spec.getPatches().values()) {
99 try {
100 Resource res;
101 try {
102 res = specFile.createRelative("../SOURCES/" + file);
103 if (!res.exists()) {
104 res = new UrlResource(file);
105 }
106 } catch (Exception e) {
107 res = new UrlResource(file);
108 }
109 toCopyToSources.add(res);
110 } catch (Exception e) {
111 log.error("Cannot interpret " + file, e);
112 }
113 }
114
115 // FIXME: we may have missed some files here
116 copySources: for (Resource res : toCopyToSources) {
117 File targetFile = new File(sourcesDir, res.getFilename())
118 .getCanonicalFile();
119 if (targetFile.exists() && !overwriteSources)
120 continue copySources;
121 copyResourceToFile(res, targetFile);
122 }
123 } catch (Exception e) {
124 throw new SlcException("Cannot copy to " + sourcesDir, e);
125 }
126 }
127
128 private static void copyResourceToFile(Resource res, File targetFile) {
129 try {
130 if (targetFile.equals(res.getFile())) {
131 if (log.isDebugEnabled())
132 log.debug("Target identical to source, skipping... "
133 + targetFile + " <=> " + res);
134 return;
135 }
136 } catch (IOException e1) {
137 // silent
138 }
139
140 OutputStream out = null;
141 InputStream in = null;
142 try {
143 out = FileUtils.openOutputStream(targetFile);
144 in = res.getInputStream();
145 IOUtils.copy(in, out);
146 if (log.isDebugEnabled())
147 log.debug("Copied " + targetFile + " from " + res);
148 } catch (Exception e) {
149 throw new SlcException("Cannot copy " + res + " to " + targetFile,
150 e);
151 } finally {
152 IOUtils.closeQuietly(in);
153 IOUtils.closeQuietly(out);
154 }
155
156 }
157
158 public void setSpecFile(Resource specFile) {
159 this.specFile = specFile;
160 }
161
162 public void setTopdir(File topdir) {
163 this.topdir = topdir;
164 }
165
166 public void setOverwriteSources(Boolean overwriteSources) {
167 this.overwriteSources = overwriteSources;
168 }
169
170 public File getSrpmFile() {
171 return srpmFile;
172 }
173
174 public void setRpmBuildEnvironment(RpmBuildEnvironment rpmBuildEnvironment) {
175 this.rpmBuildEnvironment = rpmBuildEnvironment;
176 }
177
178 }