Search in sources :

Example 26 with GitRepositoryHelper

use of org.craftercms.studio.api.v2.utils.GitRepositoryHelper in project studio by craftercms.

the class GitContentRepository method listRemote.

@Override
public List<RemoteRepositoryInfoTO> listRemote(String siteId, String sandboxBranch) throws ServiceLayerException, CryptoException {
    List<RemoteRepositoryInfoTO> res = new ArrayList<RemoteRepositoryInfoTO>();
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    try (Repository repo = helper.getRepository(siteId, SANDBOX)) {
        try (Git git = new Git(repo)) {
            List<RemoteConfig> resultRemotes = git.remoteList().call();
            if (CollectionUtils.isNotEmpty(resultRemotes)) {
                for (RemoteConfig conf : resultRemotes) {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("siteId", siteId);
                    params.put("remoteName", conf.getName());
                    RemoteRepository remoteRepository = remoteRepositoryDAO.getRemoteRepository(params);
                    if (remoteRepository != null) {
                        switch(remoteRepository.getAuthenticationType()) {
                            case NONE:
                                logger.debug("No authentication");
                                git.fetch().setRemote(conf.getName()).call();
                                break;
                            case BASIC:
                                logger.debug("Basic authentication");
                                String hashedPassword = remoteRepository.getRemotePassword();
                                String password = encryptor.decrypt(hashedPassword);
                                git.fetch().setRemote(conf.getName()).setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteRepository.getRemoteUsername(), password)).call();
                                break;
                            case TOKEN:
                                logger.debug("Token based authentication");
                                String hashedToken = remoteRepository.getRemoteToken();
                                String remoteToken = encryptor.decrypt(hashedToken);
                                git.fetch().setRemote(conf.getName()).setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteToken, EMPTY)).call();
                                break;
                            case PRIVATE_KEY:
                                logger.debug("Private key authentication");
                                final Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
                                String hashedPrivateKey = remoteRepository.getRemotePrivateKey();
                                String privateKey = encryptor.decrypt(hashedPrivateKey);
                                tempKey.toFile().deleteOnExit();
                                git.fetch().setRemote(conf.getName()).setTransportConfigCallback(new TransportConfigCallback() {

                                    @Override
                                    public void configure(Transport transport) {
                                        SshTransport sshTransport = (SshTransport) transport;
                                        sshTransport.setSshSessionFactory(getSshSessionFactory(privateKey, tempKey));
                                    }
                                }).call();
                                Files.delete(tempKey);
                                break;
                            default:
                                throw new ServiceLayerException("Unsupported authentication type " + remoteRepository.getAuthenticationType());
                        }
                    }
                }
                List<Ref> resultRemoteBranches = git.branchList().setListMode(REMOTE).call();
                Map<String, List<String>> remoteBranches = new HashMap<String, List<String>>();
                for (Ref remoteBranchRef : resultRemoteBranches) {
                    String branchFullName = remoteBranchRef.getName().replace(R_REMOTES, "");
                    String remotePart = EMPTY;
                    String branchNamePart = EMPTY;
                    int slashIndex = branchFullName.indexOf("/");
                    if (slashIndex > 0) {
                        remotePart = branchFullName.substring(0, slashIndex);
                        branchNamePart = branchFullName.substring(slashIndex + 1);
                    }
                    if (!remoteBranches.containsKey(remotePart)) {
                        remoteBranches.put(remotePart, new ArrayList<String>());
                    }
                    remoteBranches.get(remotePart).add(branchNamePart);
                }
                String sandboxBranchName = sandboxBranch;
                if (StringUtils.isEmpty(sandboxBranchName)) {
                    sandboxBranchName = studioConfiguration.getProperty(REPO_SANDBOX_BRANCH);
                }
                for (RemoteConfig conf : resultRemotes) {
                    RemoteRepositoryInfoTO rri = new RemoteRepositoryInfoTO();
                    rri.setName(conf.getName());
                    List<String> branches = remoteBranches.get(rri.getName());
                    if (CollectionUtils.isEmpty(branches)) {
                        branches = new ArrayList<String>();
                        branches.add(sandboxBranchName);
                    }
                    rri.setBranches(branches);
                    StringBuilder sbUrl = new StringBuilder();
                    if (CollectionUtils.isNotEmpty(conf.getURIs())) {
                        for (int i = 0; i < conf.getURIs().size(); i++) {
                            sbUrl.append(conf.getURIs().get(i).toString());
                            if (i < conf.getURIs().size() - 1) {
                                sbUrl.append(":");
                            }
                        }
                    }
                    rri.setUrl(sbUrl.toString());
                    StringBuilder sbFetch = new StringBuilder();
                    if (CollectionUtils.isNotEmpty(conf.getFetchRefSpecs())) {
                        for (int i = 0; i < conf.getFetchRefSpecs().size(); i++) {
                            sbFetch.append(conf.getFetchRefSpecs().get(i).toString());
                            if (i < conf.getFetchRefSpecs().size() - 1) {
                                sbFetch.append(":");
                            }
                        }
                    }
                    rri.setFetch(sbFetch.toString());
                    StringBuilder sbPushUrl = new StringBuilder();
                    if (CollectionUtils.isNotEmpty(conf.getPushURIs())) {
                        for (int i = 0; i < conf.getPushURIs().size(); i++) {
                            sbPushUrl.append(conf.getPushURIs().get(i).toString());
                            if (i < conf.getPushURIs().size() - 1) {
                                sbPushUrl.append(":");
                            }
                        }
                    } else {
                        sbPushUrl.append(rri.getUrl());
                    }
                    rri.setPush_url(sbPushUrl.toString());
                    res.add(rri);
                }
            }
        } catch (GitAPIException | CryptoException | IOException e) {
            logger.error("Error getting remote repositories for site " + siteId, e);
        }
    }
    return res;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) TransportConfigCallback(org.eclipse.jgit.api.TransportConfigCallback) ArrayList(java.util.ArrayList) List(java.util.List) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) RemoteConfig(org.eclipse.jgit.transport.RemoteConfig) Path(java.nio.file.Path) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) IOException(java.io.IOException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) Ref(org.eclipse.jgit.lib.Ref) Git(org.eclipse.jgit.api.Git) RemoteRepositoryInfoTO(org.craftercms.studio.api.v1.to.RemoteRepositoryInfoTO) SshTransport(org.eclipse.jgit.transport.SshTransport) Transport(org.eclipse.jgit.transport.Transport) CryptoException(org.craftercms.commons.crypto.CryptoException) SshTransport(org.eclipse.jgit.transport.SshTransport)

Example 27 with GitRepositoryHelper

use of org.craftercms.studio.api.v2.utils.GitRepositoryHelper in project studio by craftercms.

the class GitContentRepository method lockItem.

@Override
public void lockItem(String site, String path) {
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        Repository repo = helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX);
        synchronized (helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX)) {
            try (TreeWalk tw = new TreeWalk(repo)) {
                RevTree tree = helper.getTreeForLastCommit(repo);
                // tree ‘0’
                tw.addTree(tree);
                tw.setRecursive(false);
                tw.setFilter(PathFilter.create(path));
                if (!tw.next()) {
                    return;
                }
                File repoRoot = repo.getWorkTree();
                Paths.get(repoRoot.getPath(), tw.getPathString());
                File file = new File(tw.getPathString());
                LockFile lock = new LockFile(file);
                lock.lock();
            }
        }
    } catch (IOException | CryptoException e) {
        logger.error("Error while locking file for site: " + site + " path: " + path, e);
    }
}
Also used : RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) LockFile(org.eclipse.jgit.internal.storage.file.LockFile) IOException(java.io.IOException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) CryptoException(org.craftercms.commons.crypto.CryptoException) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) File(java.io.File) LockFile(org.eclipse.jgit.internal.storage.file.LockFile) RevTree(org.eclipse.jgit.revwalk.RevTree)

Example 28 with GitRepositoryHelper

use of org.craftercms.studio.api.v2.utils.GitRepositoryHelper in project studio by craftercms.

the class GitContentRepository method resetStagingRepository.

@Override
public void resetStagingRepository(String siteId) throws ServiceLayerException, CryptoException {
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    Repository repo = helper.getRepository(siteId, PUBLISHED);
    String stagingName = servicesConfig.getStagingEnvironment(siteId);
    String liveName = servicesConfig.getLiveEnvironment(siteId);
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, siteId);
    generalLockService.lock(gitLockKey);
    synchronized (repo) {
        try (Git git = new Git(repo)) {
            logger.debug("Checkout live first becuase it is not allowed to delete checkedout branch");
            CheckoutCommand checkoutCommand = git.checkout().setName(liveName);
            retryingRepositoryOperationFacade.call(checkoutCommand);
            logger.debug("Delete staging branch in order to reset it for site: " + siteId);
            DeleteBranchCommand deleteBranchCommand = git.branchDelete().setBranchNames(stagingName).setForce(true);
            retryingRepositoryOperationFacade.call(deleteBranchCommand);
            logger.debug("Create new branch for staging with live HEAD as starting point");
            CreateBranchCommand createBranchCommand = git.branchCreate().setName(stagingName).setStartPoint(liveName);
            retryingRepositoryOperationFacade.call(createBranchCommand);
        } catch (GitAPIException e) {
            logger.error("Error while reseting staging environment for site: " + siteId);
            throw new ServiceLayerException(e);
        } finally {
            generalLockService.unlock(gitLockKey);
        }
    }
}
Also used : CreateBranchCommand(org.eclipse.jgit.api.CreateBranchCommand) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) CheckoutCommand(org.eclipse.jgit.api.CheckoutCommand) DeleteBranchCommand(org.eclipse.jgit.api.DeleteBranchCommand) Git(org.eclipse.jgit.api.Git) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper)

Example 29 with GitRepositoryHelper

use of org.craftercms.studio.api.v2.utils.GitRepositoryHelper in project studio by craftercms.

the class GitContentRepository method unLockItemForPublishing.

@Override
public void unLockItemForPublishing(String site, String path) {
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        Repository repo = helper.getRepository(site, PUBLISHED);
        synchronized (repo) {
            try (TreeWalk tw = new TreeWalk(repo)) {
                RevTree tree = helper.getTreeForLastCommit(repo);
                // tree ‘0’
                tw.addTree(tree);
                tw.setRecursive(false);
                tw.setFilter(PathFilter.create(path));
                if (!tw.next()) {
                    return;
                }
                File repoRoot = repo.getWorkTree();
                Paths.get(repoRoot.getPath(), tw.getPathString());
                File file = new File(tw.getPathString());
                LockFile lock = new LockFile(file);
                lock.unlock();
            }
        }
    } catch (IOException | CryptoException e) {
        logger.error("Error while unlocking file for site: " + site + " path: " + path, e);
    }
}
Also used : RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) LockFile(org.eclipse.jgit.internal.storage.file.LockFile) IOException(java.io.IOException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) CryptoException(org.craftercms.commons.crypto.CryptoException) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) File(java.io.File) LockFile(org.eclipse.jgit.internal.storage.file.LockFile) RevTree(org.eclipse.jgit.revwalk.RevTree)

Example 30 with GitRepositoryHelper

use of org.craftercms.studio.api.v2.utils.GitRepositoryHelper in project studio by craftercms.

the class GitContentRepository method bootstrap.

/**
 * bootstrap the repository
 */
public void bootstrap() throws Exception {
    logger.debug("Bootstrap global repository.");
    boolean bootstrapRepo = Boolean.parseBoolean(studioConfiguration.getProperty(BOOTSTRAP_REPO));
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    boolean isCreated = false;
    HierarchicalConfiguration<ImmutableNode> registrationData = studioClusterUtils.getClusterConfiguration();
    if (bootstrapRepo && registrationData != null && !registrationData.isEmpty()) {
        String firstCommitId = getRepoFirstCommitId(StringUtils.EMPTY);
        String localAddress = studioClusterUtils.getClusterNodeLocalAddress();
        List<ClusterMember> clusterNodes = studioClusterUtils.getClusterNodes(localAddress);
        if (StringUtils.isEmpty(firstCommitId)) {
            logger.debug("Creating global repository as cluster clone");
            isCreated = studioClusterUtils.cloneGlobalRepository(clusterNodes);
        } else {
            logger.debug("Global repository exists syncing with cluster siblings");
            isCreated = true;
            Repository repo = helper.getRepository(EMPTY, GLOBAL);
            try (Git git = new Git(repo)) {
                for (ClusterMember remoteNode : clusterNodes) {
                    if (remoteNode.getState().equals(ClusterMember.State.ACTIVE)) {
                        syncFromRemote(git, remoteNode);
                    }
                }
            }
        }
    }
    if (bootstrapRepo && !isCreated && helper.createGlobalRepo()) {
        // Copy the global config defaults to the global site
        // Build a path to the bootstrap repo (the repo that ships with Studio)
        String bootstrapFolderPath = this.ctx.getRealPath(FILE_SEPARATOR + BOOTSTRAP_REPO_PATH + FILE_SEPARATOR + BOOTSTRAP_REPO_GLOBAL_PATH);
        Path source = java.nio.file.FileSystems.getDefault().getPath(bootstrapFolderPath);
        logger.info("Bootstrapping with baseline @ " + source.toFile().toString());
        // Copy the bootstrap repo to the global repo
        Path globalConfigPath = helper.buildRepoPath(GLOBAL);
        TreeCopier tc = new TreeCopier(source, globalConfigPath);
        EnumSet<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
        Files.walkFileTree(source, opts, MAX_VALUE, tc);
        String studioManifestLocation = this.ctx.getRealPath(STUDIO_MANIFEST_LOCATION);
        if (Files.exists(Paths.get(studioManifestLocation))) {
            FileUtils.copyFile(Paths.get(studioManifestLocation).toFile(), Paths.get(globalConfigPath.toAbsolutePath().toString(), studioConfiguration.getProperty(BLUE_PRINTS_PATH), "BLUEPRINTS.MF").toFile());
        }
        Repository globalConfigRepo = helper.getRepository(EMPTY, GLOBAL);
        try (Git git = new Git(globalConfigRepo)) {
            Status status = git.status().call();
            if (status.hasUncommittedChanges() || !status.isClean()) {
                // Commit everything
                // TODO: Consider what to do with the commitId in the future
                AddCommand addCommand = git.add().addFilepattern(GIT_COMMIT_ALL_ITEMS);
                retryingRepositoryOperationFacade.call(addCommand);
                CommitCommand commitCommand = git.commit().setMessage(helper.getCommitMessage(REPO_INITIAL_COMMIT_COMMIT_MESSAGE));
                retryingRepositoryOperationFacade.call(commitCommand);
            }
        } catch (GitAPIException err) {
            logger.error("error creating initial commit for global configuration", err);
        }
    }
    // Create global repository object
    if (!helper.buildGlobalRepo()) {
        logger.error("Failed to create global repository!");
    }
}
Also used : Path(java.nio.file.Path) Status(org.eclipse.jgit.api.Status) ImmutableNode(org.apache.commons.configuration2.tree.ImmutableNode) FileVisitOption(java.nio.file.FileVisitOption) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ClusterMember(org.craftercms.studio.api.v2.dal.ClusterMember) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) Git(org.eclipse.jgit.api.Git) CommitCommand(org.eclipse.jgit.api.CommitCommand) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) RemoteAddCommand(org.eclipse.jgit.api.RemoteAddCommand) AddCommand(org.eclipse.jgit.api.AddCommand)

Aggregations

GitRepositoryHelper (org.craftercms.studio.api.v2.utils.GitRepositoryHelper)65 Repository (org.eclipse.jgit.lib.Repository)59 RemoteRepository (org.craftercms.studio.api.v2.dal.RemoteRepository)58 CryptoException (org.craftercms.commons.crypto.CryptoException)53 IOException (java.io.IOException)47 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)43 ContentRepository (org.craftercms.studio.api.v1.repository.ContentRepository)42 Git (org.eclipse.jgit.api.Git)41 ServiceLayerException (org.craftercms.studio.api.v1.exception.ServiceLayerException)30 Path (java.nio.file.Path)20 ArrayList (java.util.ArrayList)19 ObjectId (org.eclipse.jgit.lib.ObjectId)19 UserNotFoundException (org.craftercms.studio.api.v1.exception.security.UserNotFoundException)17 RevCommit (org.eclipse.jgit.revwalk.RevCommit)17 RevTree (org.eclipse.jgit.revwalk.RevTree)17 ContentRepository (org.craftercms.studio.api.v2.repository.ContentRepository)15 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)13 File (java.io.File)12 InvalidRemoteUrlException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException)11 InvalidRemoteException (org.eclipse.jgit.api.errors.InvalidRemoteException)10