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.rpmfactory.core;
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  import org.argeo.slc.rpmfactory.RpmFactory;
33  
34  /** Build an RPM in mock. */
35  public class BuildInMock implements Runnable {
36  	private final static Log log = LogFactory.getLog(BuildInMock.class);
37  	private final static String NOARCH = "noarch";
38  
39  	private String rpmPackage = null;
40  	private String branch = null;
41  	private String arch = NOARCH;
42  
43  	private RpmFactory rpmFactory;
44  	private Executor executor;
45  
46  	private String debuginfoDirName = "debuginfo";
47  	private String mockExecutable = "/usr/bin/mock";
48  
49  	private List<String> preBuildCommands = new ArrayList<String>();
50  
51  	public void run() {
52  		if (!rpmFactory.isDeveloperInstance()) {
53  			// clean/init
54  			SystemCall mockClean = createBaseMockCall();
55  			mockClean.arg("--init");
56  			mockClean.run();
57  		}
58  
59  		// pre build commands
60  		for (String preBuildCmd : preBuildCommands) {
61  			SystemCall mockClean = createBaseMockCall();
62  			mockClean.arg("--chroot").arg(preBuildCmd);
63  			mockClean.run();
64  		}
65  
66  		// actual build
67  		SystemCall mockBuild = createBaseMockCall();
68  		mockBuild.arg("--scm-enable");
69  		mockBuild.arg("--scm-option").arg("package=" + rpmPackage);
70  		mockBuild.arg("--no-clean");
71  		//
72  		//
73  		mockBuild.run();
74  		//
75  
76  		// copy RPMs to target directories
77  		File stagingDir = rpmFactory.getWorkspaceDir(rpmFactory
78  				.getStagingWorkspace());
79  		File srpmDir = new File(stagingDir, "SRPMS");
80  		srpmDir.mkdirs();
81  		File archDir = null;
82  		File debuginfoDir = null;
83  		if (!arch.equals(NOARCH)) {
84  			archDir = new File(stagingDir, arch);
85  			debuginfoDir = new File(archDir, debuginfoDirName);
86  			debuginfoDir.mkdirs();
87  		}
88  
89  		Set<File> reposToRecreate = new HashSet<File>();
90  		File resultDir = rpmFactory.getResultDir(arch);
91  		if (resultDir.exists())
92  			rpms: for (File file : resultDir.listFiles()) {
93  				if (file.isDirectory())
94  					continue rpms;
95  
96  				File[] targetDirs;
97  				if (file.getName().contains(".src.rpm"))
98  					targetDirs = new File[] { srpmDir };
99  				else if (file.getName().contains("-debuginfo-"))
100 					targetDirs = new File[] { debuginfoDir };
101 				else if (!arch.equals(NOARCH)
102 						&& file.getName().contains("." + arch + ".rpm"))
103 					targetDirs = new File[] { archDir };
104 				else if (file.getName().contains(".noarch.rpm")) {
105 					List<File> dirs = new ArrayList<File>();
106 					for (String arch : rpmFactory.getArchs())
107 						dirs.add(new File(stagingDir, arch));
108 					targetDirs = dirs.toArray(new File[dirs.size()]);
109 				} else if (file.getName().contains(".rpm"))
110 					throw new SlcException("Don't know where to copy " + file);
111 				else {
112 					if (log.isTraceEnabled())
113 						log.trace("Skip " + file);
114 					continue rpms;
115 				}
116 
117 				reposToRecreate.addAll(Arrays.asList(targetDirs));
118 				copyToDirs(file, targetDirs);
119 			}
120 
121 		// recreate changed repos
122 		for (File repoToRecreate : reposToRecreate) {
123 			SystemCall createrepo = new SystemCall();
124 			createrepo.arg("createrepo");
125 			// sqllite db
126 			createrepo.arg("-d");
127 			// debuginfo
128 			if (!repoToRecreate.getName().equals(debuginfoDirName))
129 				createrepo.arg("-x").arg(debuginfoDirName + "/*");
130 			// quiet
131 			createrepo.arg("-q");
132 			createrepo.arg(repoToRecreate.getAbsolutePath());
133 
134 			createrepo.setExecutor(executor);
135 			createrepo.run();
136 			log.info("Updated repo " + repoToRecreate);
137 		}
138 
139 		// index staging workspace
140 		rpmFactory.indexWorkspace(rpmFactory.getStagingWorkspace());
141 	}
142 
143 	/** Creates a mock call with all the common options such as config file etc. */
144 	protected SystemCall createBaseMockCall() {
145 		String mockCfg = rpmFactory.getMockConfig(arch);
146 		File mockConfigFile = rpmFactory.getMockConfigFile(arch, branch);
147 
148 		// prepare mock call
149 		SystemCall mock = new SystemCall();
150 
151 		if (arch != null)
152 			mock.arg("setarch").arg(arch);
153 		mock.arg(mockExecutable);
154 		mock.arg("-v");
155 		mock.arg("--configdir=" + mockConfigFile.getAbsoluteFile().getParent());
156 		if (arch != null)
157 			mock.arg("--arch=" + arch);
158 		mock.arg("-r").arg(mockCfg);
159 
160 		mock.setLogCommand(true);
161 		mock.setExecutor(executor);
162 
163 		return mock;
164 	}
165 
166 	protected void copyToDirs(File file, File[] dirs) {
167 		for (File dir : dirs) {
168 			try {
169 				FileUtils.copyFileToDirectory(file, dir);
170 				if (log.isDebugEnabled())
171 					log.debug(file + " => " + dir);
172 			} catch (IOException e) {
173 				throw new SlcException("Cannot copy " + file + " to " + dir, e);
174 			}
175 		}
176 	}
177 
178 	public void setArch(String arch) {
179 		this.arch = arch;
180 	}
181 
182 	public void setRpmPackage(String rpmPackage) {
183 		this.rpmPackage = rpmPackage;
184 	}
185 
186 	public void setBranch(String branch) {
187 		this.branch = branch;
188 	}
189 
190 	public void setRpmFactory(RpmFactory env) {
191 		this.rpmFactory = env;
192 	}
193 
194 	public void setExecutor(Executor executor) {
195 		this.executor = executor;
196 	}
197 
198 	public void setMockExecutable(String mockExecutable) {
199 		this.mockExecutable = mockExecutable;
200 	}
201 
202 	public void setPreBuildCommands(List<String> preBuildCommands) {
203 		this.preBuildCommands = preBuildCommands;
204 	}
205 
206 }