X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.rpmfactory%2Fsrc%2Forg%2Fargeo%2Fslc%2Frpmfactory%2Fcore%2FRpmFactoryImpl.java;fp=org.argeo.slc.rpmfactory%2Fsrc%2Forg%2Fargeo%2Fslc%2Frpmfactory%2Fcore%2FRpmFactoryImpl.java;h=47ca4daff64bed92fb660d9d0231b1e5ae1a726b;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.slc.rpmfactory/src/org/argeo/slc/rpmfactory/core/RpmFactoryImpl.java b/org.argeo.slc.rpmfactory/src/org/argeo/slc/rpmfactory/core/RpmFactoryImpl.java new file mode 100644 index 0000000..47ca4da --- /dev/null +++ b/org.argeo.slc.rpmfactory/src/org/argeo/slc/rpmfactory/core/RpmFactoryImpl.java @@ -0,0 +1,456 @@ +package org.argeo.slc.rpmfactory.core; + +import java.io.File; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.commons.io.FileUtils; +import org.argeo.api.cms.CmsLog; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcConstants; +import org.argeo.slc.SlcException; +import org.argeo.slc.repo.NodeIndexerVisitor; +import org.argeo.slc.rpmfactory.RpmFactory; +import org.argeo.slc.rpmfactory.RpmRepository; +import org.argeo.slc.runtime.tasks.SystemCall; + +/** + * Defines a build environment. This information is typically used by other + * components performing the various actions related to RPM build. + */ +public class RpmFactoryImpl implements RpmFactory { + private CmsLog log = CmsLog.getLog(RpmFactoryImpl.class); + + private Repository rpmRepository; + private Repository distRepository; + + private String id; + private List repositories = new ArrayList(); + private List archs = new ArrayList(); + + private String rpmBase = "/mnt/slc/repos/rpm"; + private String distBase = "/mnt/slc/repos/dist"; + private String mockVar = "/var/lib/mock"; + private String mockEtc = "/etc/mock"; + + private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm"); + + private String gitWorkspace = "git"; + + private String localUrlBase = "http://localhost:7070/"; + /** If not null or empty, this is a developer instance. */ + private String gitDevBaseUrl = null; + + private Boolean withTestingRepository = false; + + private String yumConfigMainSection = "cachedir=/var/cache/yum\n" + + "debuglevel=1\n" + "reposdir=/dev/null\n" + + "logfile=/var/log/yum.log\n" + "retries=20\n" + "obsoletes=1\n" + + "gpgcheck=0\n" + "assumeyes=1\n" + "syslog_ident=mock\n" + + "syslog_device=\n" + "http_caching=none\n"; + + private String defaultMacroFiles = "/usr/lib/rpm/macros:" + + "/usr/lib/rpm/ia32e-linux/macros:" + + "/usr/lib/rpm/redhat/macros:" + "/etc/rpm/macros.*:" + + "/etc/rpm/macros:" + "/etc/rpm/ia32e-linux/macros:" + + "~/.rpmmacros"; + private Map rpmmacros = new HashMap(); + + // set by init + private String proxiedReposBase; + private String managedReposBase; + + private String stagingWorkspace; + private String testingWorkspace; + private String stableWorkspace; + + private File rpmFactoryBaseDir; + private File mockConfDir; + private File yumConfDir; + + public void init() { + // local URL bases + proxiedReposBase = localUrlBase + "repo/rpm/"; + managedReposBase = localUrlBase + "data/public/rpm/"; + + // local directories + rpmFactoryBaseDir.mkdirs(); + mockConfDir = new File(rpmFactoryBaseDir.getPath() + "/conf/mock"); + mockConfDir.mkdirs(); + yumConfDir = new File(rpmFactoryBaseDir.getPath() + "/conf/yum"); + yumConfDir.mkdirs(); + + // managed repositories + stagingWorkspace = id + "-staging"; + if (withTestingRepository) + testingWorkspace = id + "-testing"; + stableWorkspace = id; + + initDistWorkspace(stableWorkspace); + initGitWorkspace(); + initRpmWorkspace(stagingWorkspace); + if (withTestingRepository) + initRpmWorkspace(testingWorkspace); + initRpmWorkspace(stableWorkspace); + } + + protected void initRpmWorkspace(String workspace) { + Session session = null; + try { + session = JcrUtils.loginOrCreateWorkspace(rpmRepository, workspace); + JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read"); + JcrUtils.addPrivilege(session, "/", SlcConstants.ROLE_SLC, + "jcr:all"); + + for (String arch : archs) { + Node archFolder = JcrUtils.mkfolders(session, "/" + arch); + session.save(); + File workspaceDir = getWorkspaceDir(workspace); + try { + if (!archFolder.hasNode("repodata")) { + // touch a file in order to make sure this is properly + // mounted. + File touch = new File(workspaceDir, ".touch"); + touch.createNewFile(); + touch.delete(); + + SystemCall createrepo = new SystemCall(); + createrepo.arg("createrepo"); + createrepo.arg("-q"); + File archDir = new File(workspaceDir, arch); + createrepo.arg(archDir.getAbsolutePath()); + createrepo.run(); + } + } catch (IOException e) { + log.error(workspaceDir + " not properly mounted.", e); + } + } + } catch (Exception e) { + throw new SlcException("Cannot initialize workspace " + workspace, + e); + } finally { + JcrUtils.logoutQuietly(session); + } + } + + /** Caller must logout the underlying session. */ + public Node newDistribution(String distributionId) { + Session session = null; + try { + session = JcrUtils.loginOrCreateWorkspace(rpmRepository, + distributionId); + JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read"); + JcrUtils.addPrivilege(session, "/", SlcConstants.ROLE_SLC, + "jcr:all"); + + Calendar now = new GregorianCalendar(); + String folderName = dateFormat.format(now.getTime()); + return JcrUtils.mkfolders(session, "/" + folderName); + } catch (Exception e) { + JcrUtils.logoutQuietly(session); + throw new SlcException("Cannot initialize distribution workspace " + + distributionId, e); + } + } + + protected void initGitWorkspace() { + Session session = null; + try { + session = JcrUtils.loginOrCreateWorkspace(rpmRepository, + gitWorkspace); + JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read"); + JcrUtils.addPrivilege(session, "/", SlcConstants.ROLE_SLC, + "jcr:all"); + } catch (Exception e) { + throw new SlcException("Cannot initialize workspace " + + gitWorkspace, e); + } finally { + JcrUtils.logoutQuietly(session); + } + } + + protected void initDistWorkspace(String workspace) { + Session session = null; + try { + session = JcrUtils + .loginOrCreateWorkspace(distRepository, workspace); + JcrUtils.addPrivilege(session, "/", "anonymous", "jcr:read"); + } catch (RepositoryException e) { + throw new SlcException("Cannot initialize workspace " + workspace, + e); + } finally { + JcrUtils.logoutQuietly(session); + } + } + + public void destroy() { + + } + + public String generateMockConfigFile(String arch, String branch) { + StringBuffer buf = new StringBuffer(); + + buf.append("config_opts['root'] = '" + getIdWithArch(arch) + "'\n"); + buf.append("config_opts['target_arch'] = '" + arch + "'\n"); + buf.append("config_opts['legal_host_arches'] = ('" + arch + "',)\n"); + buf.append("config_opts['chroot_setup_cmd'] = 'groupinstall buildsys-build'\n"); + // buf.append("config_opts['dist'] = 'el6'\n"); + buf.append("config_opts['plugin_conf']['yum_cache_enable'] = False\n"); + + buf.append("config_opts['scm'] = False\n"); + buf.append("config_opts['scm_opts']['method'] = 'git'\n"); + buf.append("config_opts['scm_opts']['spec'] = 'SCM_PKG.spec'\n"); + buf.append("config_opts['scm_opts']['ext_src_dir'] = '" + + getSourcesDir().getAbsolutePath() + "'\n"); + buf.append("config_opts['scm_opts']['git_timestamps'] = True\n"); + + // development + if (gitDevBaseUrl != null && !gitDevBaseUrl.trim().equals("")) + buf.append("config_opts['scm_opts']['git_get'] = 'git clone " + + (branch != null ? "-b " + branch : "") + " " + + gitDevBaseUrl + "/SCM_PKG SCM_PKG'\n"); + else + buf.append("config_opts['scm_opts']['git_get'] = 'git clone " + + (branch != null ? "-b " + branch : "") + " " + + getGitBaseUrl() + "/SCM_PKG.git SCM_PKG'\n"); + + buf.append("\nconfig_opts['yum.conf'] = \"\"\"\n"); + buf.append(generateYumConfigFile(arch)).append('\n'); + buf.append("\"\"\"\n"); + return buf.toString(); + } + + public String generateYumConfigFile(String arch) { + StringBuffer buf = new StringBuffer(); + buf.append("[main]\n"); + buf.append(yumConfigMainSection).append('\n'); + + for (RpmRepository repository : repositories) { + buf.append('[').append(repository.getId()).append("]\n"); + buf.append("name=").append(repository.getId()).append('\n'); + if (repository instanceof ThirdPartyRpmRepository) { + buf.append("#baseurl=").append(repository.getUrl()) + .append(arch).append('/').append("\n"); + buf.append("baseurl=").append(proxiedReposBase) + .append(repository.getId()).append('/').append(arch) + .append('/').append("\n"); + if (((ThirdPartyRpmRepository) repository).getYumConf() != null) + buf.append( + ((ThirdPartyRpmRepository) repository).getYumConf() + .trim()).append('\n'); + } + } + + // managed repos + addManagedRepository(buf, stagingWorkspace, arch); + if (withTestingRepository) + addManagedRepository(buf, testingWorkspace, arch); + addManagedRepository(buf, stableWorkspace, arch); + return buf.toString(); + } + + protected void addManagedRepository(StringBuffer buf, String workspace, + String arch) { + buf.append('[').append(workspace).append("]\n"); + buf.append("baseurl=").append(managedReposBase).append(workspace) + .append('/').append(arch).append('/').append("\n"); + buf.append("gpgcheck=0").append("\n"); + } + + /** Creates a mock config file. */ + public File getMockConfigFile(String arch, String branch) { + File mockSiteDefaultsFile = new File(mockConfDir, "site-defaults.cfg"); + File mockLoggingFile = new File(mockConfDir, "logging.ini"); + File mockConfigFile = new File(mockConfDir, getIdWithArch(arch) + + ".cfg"); + try { + if (!mockSiteDefaultsFile.exists()) + mockSiteDefaultsFile.createNewFile(); + if (!mockLoggingFile.exists()) + FileUtils.copyFile(new File(mockEtc + "/logging.ini"), + mockLoggingFile); + + FileUtils.writeStringToFile(mockConfigFile, + generateMockConfigFile(arch, branch)); + return mockConfigFile; + } catch (IOException e) { + throw new SlcException("Cannot write mock config file to " + + mockConfigFile, e); + } + } + + /** Creates a yum config file. */ + public File getYumRepoFile(String arch) { + File yumConfigFile = new File(yumConfDir, getIdWithArch(arch) + ".repo"); + try { + FileUtils.writeStringToFile(yumConfigFile, + generateYumConfigFile(arch)); + return yumConfigFile; + } catch (IOException e) { + throw new SlcException("Cannot write yum config file to " + + yumConfigFile, e); + } + } + + public File getResultDir(String arch) { + return new File(mockVar + "/" + getIdWithArch(arch) + "/result"); + } + + public File getWorkspaceDir(String workspace) { + return new File(rpmBase + "/" + workspace); + } + + public File getSourcesDir() { + return new File(distBase + "/" + stableWorkspace); + } + + public String getMockConfig(String arch) { + return getIdWithArch(arch); + } + + public String getIdWithArch(String arch) { + return id + "-" + arch; + } + + public String getGitBaseUrl() { + return managedReposBase + gitWorkspace; + } + + public void indexWorkspace(String workspace) { + Session session = null; + try { + session = rpmRepository.login(workspace); + session.getRootNode().accept( + new NodeIndexerVisitor(new RpmIndexer())); + if (log.isDebugEnabled()) + log.debug("Indexed workspace " + workspace); + } catch (RepositoryException e) { + throw new SlcException("Cannot index workspace " + workspace, e); + } finally { + JcrUtils.logoutQuietly(session); + } + } + + public Boolean isDeveloperInstance() { + return gitDevBaseUrl != null; + } + + /** Write (topdir)/rpmmacros and (topdir)/rpmrc */ + public void writeRpmbuildConfigFiles(File topdir) { + writeRpmbuildConfigFiles(topdir, new File(topdir, "rpmmacros"), + new File(topdir, "rpmrc")); + } + + public void writeRpmbuildConfigFiles(File topdir, File rpmmacroFile, + File rpmrcFile) { + try { + List macroLines = new ArrayList(); + macroLines.add("%_topdir " + topdir.getCanonicalPath()); + for (String macroKey : rpmmacros.keySet()) { + macroLines.add(macroKey + " " + rpmmacros.get(macroKey)); + } + FileUtils.writeLines(rpmmacroFile, macroLines); + + List rpmrcLines = new ArrayList(); + rpmrcLines.add("include: /usr/lib/rpm/rpmrc"); + rpmrcLines.add("macrofiles: " + defaultMacroFiles + ":" + + rpmmacroFile.getCanonicalPath()); + FileUtils.writeLines(rpmrcFile, rpmrcLines); + } catch (IOException e) { + throw new SlcException("Cannot write rpmbuild config files", e); + } + + } + + public Map getRpmmacros() { + return rpmmacros; + } + + public void setRpmmacros(Map rpmmacros) { + this.rpmmacros = rpmmacros; + } + + public String getDefaultMacroFiles() { + return defaultMacroFiles; + } + + public void setDefaultMacroFiles(String defaultMacroFiles) { + this.defaultMacroFiles = defaultMacroFiles; + } + + public void setArchs(List archs) { + this.archs = archs; + } + + public List getArchs() { + return archs; + } + + public void setRpmBase(String stagingBase) { + this.rpmBase = stagingBase; + } + + public void setId(String id) { + this.id = id; + } + + public void setMockVar(String mockVar) { + this.mockVar = mockVar; + } + + public void setRpmRepository(Repository rpmRepository) { + this.rpmRepository = rpmRepository; + } + + public void setDistRepository(Repository distRepository) { + this.distRepository = distRepository; + } + + public void setLocalUrlBase(String localUrlBase) { + this.localUrlBase = localUrlBase; + } + + public void setYumConfigMainSection(String yumConfigMainSection) { + this.yumConfigMainSection = yumConfigMainSection; + } + + public void setRepositories(List repositories) { + this.repositories = repositories; + } + + public void setRpmFactoryBaseDir(File rpmFactoryBaseDir) { + this.rpmFactoryBaseDir = rpmFactoryBaseDir; + } + + public String getStagingWorkspace() { + return stagingWorkspace; + } + + public String getTestingWorkspace() { + return testingWorkspace; + } + + public String getStableWorkspace() { + return stableWorkspace; + } + + public void setWithTestingRepository(Boolean withTestingRepository) { + this.withTestingRepository = withTestingRepository; + } + + public void setGitDevBaseUrl(String gitBaseUrl) { + this.gitDevBaseUrl = gitBaseUrl; + } +}