View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.lib.linux.rpmfactory;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.HashSet;
23  import java.util.List;
24  import java.util.Set;
25  
26  import org.apache.commons.exec.Executor;
27  import org.apache.commons.io.FileUtils;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.argeo.slc.SlcException;
31  import org.argeo.slc.core.execution.tasks.SystemCall;
32  
33  /** Rebuild an SRPM in mock. (Historical) Replaces the build-mock.sh script. */
34  public class BuildInMock implements Runnable {
35  	private final static Log log = LogFactory.getLog(BuildInMock.class);
36  
37  	/** Mock flavour provided by the EPEL repository */
38  	public final static String EPEL = "EPEL";
39  	/** Mock flavour provided by CentOS until v5 */
40  	public final static String CENTOS = "CENTOS";
41  
42  	public final static String NOARCH = "noarch";
43  
44  	private String mockVar = "/var/lib/mock";
45  
46  	private String mockFlavour = EPEL;
47  	private String mockConfig = null;
48  
49  	private String repository;
50  	private String release = null;
51  	private String level = null;
52  	private String arch = NOARCH;
53  
54  	private String rpmPackage = null;
55  
56  	private Boolean mkdirs = true;
57  
58  	private RpmBuildEnvironment buildEnvironment;
59  	private Executor executor;
60  
61  	private String debuginfoDirName = "debuginfo";
62  
63  	public void run() {
64  		// TODO check if caller is in mock group
65  
66  		String cfgId = repository + "-" + release + "-" + arch;
67  		String cfg = mockConfig != null ? mockConfig : "slc/" + cfgId;
68  
69  		// prepare mock call
70  		SystemCall mock = new SystemCall();
71  		if (arch != null)
72  			mock.arg("setarch").arg(arch);
73  		mock.arg("mock");
74  		if (mockFlavour.equals(EPEL))
75  			mock.arg("-v");
76  		else if (mockFlavour.equals(CENTOS))
77  			mock.arg("--debug");
78  		if (arch != null)
79  			mock.arg("--arch=" + arch);
80  		mock.arg("-r").arg(cfg);
81  
82  		mock.arg("--scm-enable");
83  		mock.arg("--scm-option").arg("package=" + rpmPackage);
84  
85  		mock.setLogCommand(true);
86  
87  		// mock command execution
88  		mock.setExecutor(executor);
89  		mock.run();
90  
91  		// File repoDir = new File(buildEnvironment.getStagingBase() + "/"
92  		// + repository + "/" + level + "/" + release);
93  		File repoDir = new File(buildEnvironment.getStagingBase() + "/"
94  				+ repository + "-" + release + "-staging");
95  		File srpmDir = new File(repoDir, "SRPMS");
96  		if (mkdirs)
97  			srpmDir.mkdirs();
98  		File archDir = null;
99  		File debuginfoDir = null;
100 		if (!arch.equals(NOARCH)) {
101 			archDir = new File(repoDir, arch);
102 			debuginfoDir = new File(archDir, debuginfoDirName);
103 			debuginfoDir.mkdirs();
104 		}
105 
106 		// copy RPMs
107 		Set<File> reposToRecreate = new HashSet<File>();
108 		File resultDir = new File(mockVar + "/" + cfgId + "/result");
109 		rpms: for (File file : resultDir.listFiles()) {
110 			if (file.isDirectory())
111 				continue rpms;
112 
113 			File[] targetDirs;
114 			if (file.getName().contains(".src.rpm"))
115 				targetDirs = new File[] { srpmDir };
116 			else if (file.getName().contains("-debuginfo-"))
117 				targetDirs = new File[] { debuginfoDir };
118 			else if (!arch.equals(NOARCH)
119 					&& file.getName().contains("." + arch + ".rpm"))
120 				targetDirs = new File[] { archDir };
121 			else if (file.getName().contains(".noarch.rpm")) {
122 				List<File> dirs = new ArrayList<File>();
123 				for (String arch : buildEnvironment.getArchs())
124 					dirs.add(new File(repoDir, arch));
125 				targetDirs = dirs.toArray(new File[dirs.size()]);
126 			} else if (file.getName().contains(".rpm"))
127 				throw new SlcException("Don't know where to copy " + file);
128 			else {
129 				if (log.isTraceEnabled())
130 					log.trace("Skip " + file);
131 				continue rpms;
132 			}
133 
134 			reposToRecreate.addAll(Arrays.asList(targetDirs));
135 			copyToDirs(file, targetDirs);
136 		}
137 
138 		// recreate changed repos
139 		for (File repoToRecreate : reposToRecreate) {
140 			SystemCall createrepo = new SystemCall();
141 			createrepo.arg("createrepo");
142 			// sqllite db
143 			createrepo.arg("-d");
144 			// debuginfo
145 			if (!repoToRecreate.getName().equals(debuginfoDirName))
146 				createrepo.arg("-x").arg(debuginfoDirName + "/*");
147 			// quiet
148 			createrepo.arg("-q");
149 			createrepo.arg(repoToRecreate.getAbsolutePath());
150 
151 			createrepo.setExecutor(executor);
152 			createrepo.run();
153 			log.info("Updated repo " + repoToRecreate);
154 		}
155 	}
156 
157 	protected void copyToDirs(File file, File[] dirs) {
158 		for (File dir : dirs) {
159 			try {
160 				FileUtils.copyFileToDirectory(file, dir);
161 				if (log.isDebugEnabled())
162 					log.debug(file + " => " + dir);
163 			} catch (IOException e) {
164 				throw new SlcException("Cannot copy " + file + " to " + dir, e);
165 			}
166 		}
167 	}
168 
169 	public void setMockFlavour(String mockFlavour) {
170 		this.mockFlavour = mockFlavour;
171 	}
172 
173 	public void setMockConfig(String mockConfig) {
174 		this.mockConfig = mockConfig;
175 	}
176 
177 	public void setRepository(String repo) {
178 		this.repository = repo;
179 	}
180 
181 	public void setRelease(String release) {
182 		this.release = release;
183 	}
184 
185 	public void setLevel(String level) {
186 		this.level = level;
187 	}
188 
189 	public void setArch(String arch) {
190 		this.arch = arch;
191 	}
192 
193 	public void setRpmPackage(String rpmPackage) {
194 		this.rpmPackage = rpmPackage;
195 	}
196 
197 	public void setMockVar(String mockVar) {
198 		this.mockVar = mockVar;
199 	}
200 
201 	public void setMkdirs(Boolean mkdirs) {
202 		this.mkdirs = mkdirs;
203 	}
204 
205 	public void setBuildEnvironment(RpmBuildEnvironment buildEnvironment) {
206 		this.buildEnvironment = buildEnvironment;
207 	}
208 
209 	public void setExecutor(Executor executor) {
210 		this.executor = executor;
211 	}
212 
213 }