Search in sources :

Example 11 with PATTERN_SITE

use of org.craftercms.studio.api.v1.constant.StudioConstants.PATTERN_SITE in project studio by craftercms.

the class GitContentRepository method initialPublish.

@Override
public void initialPublish(String site, String sandboxBranch, String environment, String author, String comment) throws DeploymentException, CryptoException {
    String gitLockKey = SITE_PUBLISHED_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, site);
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    Repository repo = helper.getRepository(site, PUBLISHED);
    String commitId = EMPTY;
    String sandboxBranchName = sandboxBranch;
    if (StringUtils.isEmpty(sandboxBranchName)) {
        sandboxBranchName = studioConfiguration.getProperty(REPO_SANDBOX_BRANCH);
    }
    generalLockService.lock(gitLockKey);
    synchronized (repo) {
        try (Git git = new Git(repo)) {
            // fetch "origin/master"
            logger.debug("Fetch from sandbox for site " + site);
            git.fetch().call();
            // checkout master and pull from sandbox
            logger.debug("Checkout published/master branch for site " + site);
            try {
                CheckoutCommand checkoutCommand = git.checkout().setName(sandboxBranchName);
                retryingRepositoryOperationFacade.call(checkoutCommand);
                PullCommand pullCommand = git.pull().setRemote(DEFAULT_REMOTE_NAME).setRemoteBranchName(sandboxBranchName).setStrategy(THEIRS);
                retryingRepositoryOperationFacade.call(pullCommand);
            } catch (RefNotFoundException e) {
                logger.error("Failed to checkout published master and to pull content from sandbox for site " + site, e);
                throw new DeploymentException("Failed to checkout published master and to pull content from " + "sandbox for site " + site);
            }
            // checkout environment branch
            logger.debug("Checkout environment branch " + environment + " for site " + site);
            try {
                CheckoutCommand checkoutCommand = git.checkout().setCreateBranch(true).setForce(true).setStartPoint(sandboxBranchName).setUpstreamMode(TRACK).setName(environment);
                retryingRepositoryOperationFacade.call(checkoutCommand);
            } catch (RefNotFoundException e) {
                logger.info("Not able to find branch " + environment + " for site " + site + ". Creating new branch");
            }
            // tag
            PersonIdent authorIdent = helper.getAuthorIdent(author);
            ZonedDateTime publishDate = ZonedDateTime.now(UTC);
            String tagName = publishDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HHmmssSSSX")) + "_published_on_" + publishDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HHmmssSSSX"));
            TagCommand tagCommand = git.tag().setTagger(authorIdent).setName(tagName).setMessage(comment);
            retryingRepositoryOperationFacade.call(tagCommand);
        } catch (Exception e) {
            logger.error("Error when publishing site " + site + " to environment " + environment, e);
            throw new DeploymentException("Error when publishing site " + site + " to environment " + environment + " [commit ID = " + commitId + "]");
        } finally {
            generalLockService.unlock(gitLockKey);
        }
    }
}
Also used : 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) PullCommand(org.eclipse.jgit.api.PullCommand) Git(org.eclipse.jgit.api.Git) RefNotFoundException(org.eclipse.jgit.api.errors.RefNotFoundException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) ZonedDateTime(java.time.ZonedDateTime) DeploymentException(org.craftercms.studio.api.v1.service.deployment.DeploymentException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) JSchException(com.jcraft.jsch.JSchException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) RefNotFoundException(org.eclipse.jgit.api.errors.RefNotFoundException) RemoteRepositoryNotFoundException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException) URISyntaxException(java.net.URISyntaxException) UserNotFoundException(org.craftercms.studio.api.v1.exception.security.UserNotFoundException) InvalidRemoteUrlException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException) ContentNotFoundException(org.craftercms.studio.api.v1.exception.ContentNotFoundException) RemoteAlreadyExistsException(org.craftercms.studio.api.v1.exception.repository.RemoteAlreadyExistsException) DeploymentException(org.craftercms.studio.api.v1.service.deployment.DeploymentException) CryptoException(org.craftercms.commons.crypto.CryptoException) TransportException(org.eclipse.jgit.api.errors.TransportException) RemoteRepositoryNotBareException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotBareException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) InvalidRemoteRepositoryCredentialsException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException) InvalidRemoteRepositoryException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException) TagCommand(org.eclipse.jgit.api.TagCommand)

Example 12 with PATTERN_SITE

use of org.craftercms.studio.api.v1.constant.StudioConstants.PATTERN_SITE in project studio by craftercms.

the class GitContentRepository method createSitePushToRemote.

@Override
public boolean createSitePushToRemote(String siteId, String remoteName, String remoteUrl, String authenticationType, String remoteUsername, String remotePassword, String remoteToken, String remotePrivateKey, boolean createAsOrphan) throws InvalidRemoteRepositoryException, InvalidRemoteRepositoryCredentialsException, RemoteRepositoryNotFoundException, RemoteRepositoryNotBareException, ServiceLayerException {
    boolean toRet = true;
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, siteId);
    generalLockService.lock(gitLockKey);
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        try (Repository repo = helper.getRepository(siteId, SANDBOX)) {
            try (Git git = new Git(repo)) {
                boolean pkauth = false;
                final Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
                PushCommand pushCommand = git.push();
                switch(authenticationType) {
                    case NONE:
                        logger.debug("No authentication");
                        break;
                    case BASIC:
                        logger.debug("Basic authentication");
                        pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteUsername, remotePassword));
                        break;
                    case TOKEN:
                        logger.debug("Token based authentication");
                        pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteToken, EMPTY));
                        break;
                    case PRIVATE_KEY:
                        logger.debug("Private key authentication");
                        tempKey.toFile().deleteOnExit();
                        pushCommand.setTransportConfigCallback(new TransportConfigCallback() {

                            @Override
                            public void configure(Transport transport) {
                                SshTransport sshTransport = (SshTransport) transport;
                                sshTransport.setSshSessionFactory(getSshSessionFactory(remotePrivateKey, tempKey));
                            }
                        });
                        pkauth = true;
                        break;
                    default:
                        throw new ServiceLayerException("Unsupported authentication type " + authenticationType);
                }
                logger.debug("Push site " + siteId + " to remote repository " + remoteName + "(" + remoteUrl + ")");
                pushCommand.setPushAll().setRemote(remoteName);
                Iterable<PushResult> result = retryingRepositoryOperationFacade.call(pushCommand);
                if (pkauth)
                    Files.delete(tempKey);
                logger.debug("Check push result to verify it was success");
                Iterator<PushResult> resultIter = result.iterator();
                if (resultIter.hasNext()) {
                    PushResult pushResult = resultIter.next();
                    Iterator<RemoteRefUpdate> remoteRefUpdateIterator = pushResult.getRemoteUpdates().iterator();
                    if (remoteRefUpdateIterator.hasNext()) {
                        RemoteRefUpdate update = remoteRefUpdateIterator.next();
                        if (update.getStatus().equals(REJECTED_NONFASTFORWARD)) {
                            logger.error("Remote repository: " + remoteName + " (" + remoteUrl + ") is not bare repository");
                            throw new RemoteRepositoryNotBareException("Remote repository: " + remoteName + " (" + remoteUrl + ") is not bare repository");
                        }
                    }
                }
            } catch (InvalidRemoteException e) {
                logger.error("Invalid remote repository: " + remoteName + " (" + remoteUrl + ")", e);
                throw new InvalidRemoteRepositoryException("Invalid remote repository: " + remoteName + " (" + remoteUrl + ")");
            } catch (TransportException e) {
                if (StringUtils.endsWithIgnoreCase(e.getMessage(), "not authorized")) {
                    logger.error("Bad credentials or read only repository: " + remoteName + " (" + remoteUrl + ")", e);
                    throw new InvalidRemoteRepositoryCredentialsException("Bad credentials or read only repository: " + remoteName + " (" + remoteUrl + ") for username " + remoteUsername, e);
                } else {
                    logger.error("Remote repository not found: " + remoteName + " (" + remoteUrl + ")", e);
                    throw new RemoteRepositoryNotFoundException("Remote repository not found: " + remoteName + " (" + remoteUrl + ")");
                }
            } catch (ClassCastException e) {
                logger.error("Wrong protocol used to access repository: " + remoteName + " (" + remoteUrl + ")", e);
                throw new InvalidRemoteRepositoryCredentialsException("Wrong protocol used to access repository: " + remoteName + " (" + remoteUrl + ")", e);
            } catch (ServiceLayerException | IOException e) {
                logger.error("Failed to push newly created site " + siteId + " to remote repository " + remoteUrl, e);
                throw new ServiceLayerException(e);
            }
        }
    } catch (GitAPIException | CryptoException e) {
        logger.error("Failed to push newly created site " + siteId + " to remote repository " + remoteUrl, e);
        toRet = false;
    } finally {
        generalLockService.unlock(gitLockKey);
    }
    return toRet;
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) TransportConfigCallback(org.eclipse.jgit.api.TransportConfigCallback) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) RemoteRepositoryNotBareException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotBareException) Path(java.nio.file.Path) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) InvalidRemoteRepositoryCredentialsException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) InvalidRemoteRepositoryException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException) PushResult(org.eclipse.jgit.transport.PushResult) IOException(java.io.IOException) TransportException(org.eclipse.jgit.api.errors.TransportException) PushCommand(org.eclipse.jgit.api.PushCommand) 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) RemoteRepositoryNotFoundException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) 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 13 with PATTERN_SITE

use of org.craftercms.studio.api.v1.constant.StudioConstants.PATTERN_SITE in project studio by craftercms.

the class GitContentRepository method revertContent.

@Override
public String revertContent(String site, String path, String version, boolean major, String comment) {
    // TODO: SJ: refactor to remove the notion of a major/minor for 3.1+
    String commitId = null;
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, site);
    generalLockService.lock(gitLockKey);
    try {
        InputStream versionContent = getContentVersion(site, path, version);
        commitId = writeContent(site, path, versionContent);
        createVersion(site, path, major);
    } catch (ContentNotFoundException err) {
        logger.error("error reverting content for site:  " + site + " path: " + path, err);
    } finally {
        generalLockService.unlock(gitLockKey);
    }
    return commitId;
}
Also used : ContentNotFoundException(org.craftercms.studio.api.v1.exception.ContentNotFoundException) InputStream(java.io.InputStream)

Example 14 with PATTERN_SITE

use of org.craftercms.studio.api.v1.constant.StudioConstants.PATTERN_SITE in project studio by craftercms.

the class AbstractUpgradeOperation method writeToRepo.

protected void writeToRepo(String site, String path, InputStream content) {
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, site);
    generalLockService.lock(gitLockKey);
    try {
        Path repositoryPath = getRepositoryPath(site);
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repo = builder.setGitDir(repositoryPath.toFile()).readEnvironment().findGitDir().build();
        // Create basic file
        File file = new File(repo.getDirectory().getParent(), path);
        String gitPath = getGitPath(path);
        // Create parent folders
        File folder = file.getParentFile();
        if (folder != null && !folder.exists()) {
            folder.mkdirs();
        }
        // Create the file if it doesn't exist already
        if (!file.exists()) {
            try {
                if (!file.createNewFile()) {
                    logger.error("error creating file: site: " + site + " path: " + path);
                }
            } catch (IOException e) {
                logger.error("error creating file: site: " + site + " path: " + path, e);
            }
        }
        // Write the bits
        try (FileChannel outChannel = new FileOutputStream(file.getPath()).getChannel()) {
            logger.debug("created the file output channel");
            ReadableByteChannel inChannel = Channels.newChannel(content);
            logger.debug("created the file input channel");
            // 1MB at a time
            long amount = 1024 * 1024;
            long count;
            long offset = 0;
            while ((count = outChannel.transferFrom(inChannel, offset, amount)) > 0) {
                logger.debug("writing the bits: offset = " + offset + " count: " + count);
                offset += count;
            }
        }
        // Add the file to git
        try (Git git = new Git(repo)) {
            git.add().addFilepattern(gitPath).call();
            Status status = git.status().addPath(gitPath).call();
            // TODO: SJ: Below needs more thought and refactoring to detect issues with git repo and report them
            if (status.hasUncommittedChanges() || !status.isClean()) {
                RevCommit commit;
                commit = git.commit().setOnly(gitPath).setMessage(getCommitMessage()).call();
                commit.getName();
            }
        } catch (GitAPIException e) {
            logger.error("error adding file to git: site: " + site + " path: " + path, e);
        }
    } catch (IOException e) {
        logger.error("error writing file: site: " + site + " path: " + path, e);
    } finally {
        generalLockService.unlock(gitLockKey);
    }
}
Also used : Path(java.nio.file.Path) Status(org.eclipse.jgit.api.Status) ReadableByteChannel(java.nio.channels.ReadableByteChannel) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) FileRepositoryBuilder(org.eclipse.jgit.storage.file.FileRepositoryBuilder) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) Repository(org.eclipse.jgit.lib.Repository) Git(org.eclipse.jgit.api.Git) FileOutputStream(java.io.FileOutputStream) File(java.io.File) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 15 with PATTERN_SITE

use of org.craftercms.studio.api.v1.constant.StudioConstants.PATTERN_SITE in project studio by craftercms.

the class GitRepositoryHelper method createSiteCloneRemoteGitRepo.

public boolean createSiteCloneRemoteGitRepo(String siteId, String sandboxBranch, String remoteName, String remoteUrl, String remoteBranch, boolean singleBranch, String authenticationType, String remoteUsername, String remotePassword, String remoteToken, String remotePrivateKey, boolean createAsOrphan) throws InvalidRemoteRepositoryException, InvalidRemoteRepositoryCredentialsException, RemoteRepositoryNotFoundException, ServiceLayerException {
    boolean toRet = true;
    // prepare a new folder for the cloned repository
    Path siteSandboxPath = buildRepoPath(SANDBOX, siteId);
    File localPath = siteSandboxPath.toFile();
    localPath.delete();
    logger.debug("Add user credentials if provided");
    // then clone
    logger.debug("Cloning from " + remoteUrl + " to " + localPath);
    CloneCommand cloneCommand = Git.cloneRepository();
    Git cloneResult = null;
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, siteId);
    generalLockService.lock(gitLockKey);
    try {
        final Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
        switch(authenticationType) {
            case RemoteRepository.AuthenticationType.NONE:
                logger.debug("No authentication");
                break;
            case RemoteRepository.AuthenticationType.BASIC:
                logger.debug("Basic authentication");
                cloneCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteUsername, remotePassword));
                break;
            case RemoteRepository.AuthenticationType.TOKEN:
                logger.debug("Token based authentication");
                cloneCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteToken, StringUtils.EMPTY));
                break;
            case RemoteRepository.AuthenticationType.PRIVATE_KEY:
                logger.debug("Private key authentication");
                tempKey.toFile().deleteOnExit();
                cloneCommand.setTransportConfigCallback(new TransportConfigCallback() {

                    @Override
                    public void configure(Transport transport) {
                        SshTransport sshTransport = (SshTransport) transport;
                        sshTransport.setSshSessionFactory(getSshSessionFactory(remotePrivateKey, tempKey));
                    }
                });
                break;
            default:
                throw new ServiceLayerException("Unsupported authentication type " + authenticationType);
        }
        if (StringUtils.isNotEmpty(remoteBranch)) {
            cloneCommand.setBranch(remoteBranch);
        }
        cloneResult = cloneCommand.setURI(remoteUrl).setDirectory(localPath).setRemote(remoteName).setCloneAllBranches(!singleBranch).call();
        Files.deleteIfExists(tempKey);
        Repository sandboxRepo = checkIfCloneWasOk(cloneResult, remoteName, remoteUrl);
        sandboxRepo = optimizeRepository(sandboxRepo);
        // Make repository orphan if needed
        if (createAsOrphan) {
            makeRepoOrphan(sandboxRepo, siteId);
        }
        sandboxes.put(siteId, sandboxRepo);
    } catch (InvalidRemoteException e) {
        logger.error("Invalid remote repository: " + remoteName + " (" + remoteUrl + ")", e);
        throw new InvalidRemoteRepositoryException("Invalid remote repository: " + remoteName + " (" + remoteUrl + ")");
    } catch (TransportException e) {
        if (StringUtils.endsWithIgnoreCase(e.getMessage(), "not authorized")) {
            logger.error("Bad credentials or read only repository: " + remoteName + " (" + remoteUrl + ")", e);
            throw new InvalidRemoteRepositoryCredentialsException("Bad credentials or read only repository: " + remoteName + " (" + remoteUrl + ") for username " + remoteUsername, e);
        } else {
            logger.error("Remote repository not found: " + remoteName + " (" + remoteUrl + ")", e);
            throw new RemoteRepositoryNotFoundException("Remote repository not found: " + remoteName + " (" + remoteUrl + ")");
        }
    } catch (GitAPIException | IOException | UserNotFoundException e) {
        logger.error("Error while creating repository for site with path" + siteSandboxPath.toString(), e);
        toRet = false;
    } finally {
        generalLockService.unlock(gitLockKey);
        if (cloneResult != null) {
            cloneResult.close();
        }
    }
    return toRet;
}
Also used : Path(java.nio.file.Path) CloneCommand(org.eclipse.jgit.api.CloneCommand) UserNotFoundException(org.craftercms.studio.api.v1.exception.security.UserNotFoundException) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) InvalidRemoteRepositoryCredentialsException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) InvalidRemoteRepositoryException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException) IOException(java.io.IOException) TransportException(org.eclipse.jgit.api.errors.TransportException) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) Git(org.eclipse.jgit.api.Git) TransportConfigCallback(org.eclipse.jgit.api.TransportConfigCallback) RemoteRepositoryNotFoundException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) SshTransport(org.eclipse.jgit.transport.SshTransport) Transport(org.eclipse.jgit.transport.Transport) File(java.io.File) SshTransport(org.eclipse.jgit.transport.SshTransport)

Aggregations

Repository (org.eclipse.jgit.lib.Repository)25 Git (org.eclipse.jgit.api.Git)23 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)23 ContentRepository (org.craftercms.studio.api.v1.repository.ContentRepository)21 RemoteRepository (org.craftercms.studio.api.v2.dal.RemoteRepository)21 ServiceLayerException (org.craftercms.studio.api.v1.exception.ServiceLayerException)20 GitRepositoryHelper (org.craftercms.studio.api.v2.utils.GitRepositoryHelper)20 IOException (java.io.IOException)17 CryptoException (org.craftercms.commons.crypto.CryptoException)16 Path (java.nio.file.Path)14 UserNotFoundException (org.craftercms.studio.api.v1.exception.security.UserNotFoundException)12 File (java.io.File)7 CommitCommand (org.eclipse.jgit.api.CommitCommand)6 Status (org.eclipse.jgit.api.Status)6 InvalidRemoteUrlException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException)5 InvalidRemoteException (org.eclipse.jgit.api.errors.InvalidRemoteException)5 InvalidRemoteRepositoryCredentialsException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException)4 InvalidRemoteRepositoryException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException)4 RemoteRepositoryNotFoundException (org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException)4 AddCommand (org.eclipse.jgit.api.AddCommand)4