Search in sources :

Example 16 with PatchData

use of io.fabric8.patch.management.PatchData in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceIT method installNonRollupPatch.

@Test
public void installNonRollupPatch() throws IOException, GitAPIException {
    freshKarafStandaloneDistro();
    GitPatchRepository repository = patchManagement();
    PatchManagement management = (PatchManagement) pm;
    Git fork = repository.cloneRepository(repository.findOrCreateMainGitRepository(), true);
    // no changes, but commit
    ((GitPatchManagementServiceImpl) pm).applyUserChanges(fork);
    repository.prepareCommit(fork, "artificial change, not treated as user change (could be a patch)").call();
    repository.push(fork);
    FileUtils.write(new File(karafHome, "bin/shutdown"), "#!/bin/bash\nexit 42");
    ((GitPatchManagementServiceImpl) pm).applyUserChanges(fork);
    repository.closeRepository(fork, true);
    preparePatchZip("src/test/resources/content/patch1", "target/karaf/patches/source/patch-1.zip", false);
    List<PatchData> patches = management.fetchPatches(new File("target/karaf/patches/source/patch-1.zip").toURI().toURL());
    Patch patch = management.trackPatch(patches.get(0));
    String tx = management.beginInstallation(PatchKind.NON_ROLLUP);
    management.install(tx, patch, null);
    @SuppressWarnings("unchecked") Map<String, Git> transactions = (Map<String, Git>) getField(management, "pendingTransactions");
    assertThat(transactions.size(), equalTo(1));
    fork = transactions.values().iterator().next();
    ObjectId since = fork.getRepository().resolve("baseline-6.2.0^{commit}");
    ObjectId to = fork.getRepository().resolve(tx);
    Iterable<RevCommit> commits = fork.log().addRange(since, to).call();
    List<String> commitList = Arrays.asList("[PATCH] Installing patch my-patch-1", "[PATCH] Apply user changes", "artificial change, not treated as user change (could be a patch)", "[PATCH] Apply user changes");
    int n = 0;
    for (RevCommit c : commits) {
        String msg = c.getShortMessage();
        assertThat(msg, equalTo(commitList.get(n++)));
    }
    assertThat(n, equalTo(commitList.size()));
    assertThat(fork.tagList().call().size(), equalTo(3));
    assertTrue(repository.containsTag(fork, "patch-management"));
    assertTrue(repository.containsTag(fork, "baseline-6.2.0"));
    assertTrue(repository.containsTag(fork, "patch-my-patch-1"));
    assertThat("The conflict should be resolved in special way", FileUtils.readFileToString(new File(karafHome, "bin/setenv")), equalTo("JAVA_MIN_MEM=2G # Minimum memory for the JVM\n"));
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) GitPatchRepository(io.fabric8.patch.management.impl.GitPatchRepository) Git(org.eclipse.jgit.api.Git) GitPatchManagementServiceImpl(io.fabric8.patch.management.impl.GitPatchManagementServiceImpl) File(java.io.File) Map(java.util.Map) RevCommit(org.eclipse.jgit.revwalk.RevCommit) Test(org.junit.Test)

Example 17 with PatchData

use of io.fabric8.patch.management.PatchData in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceIT method addPatch1.

/**
 * Patch 1 is non-rollup patch
 * @throws IOException
 * @throws GitAPIException
 */
@Test
public void addPatch1() throws IOException, GitAPIException {
    initializationPerformedBaselineDistributionFoundInSystem();
    // prepare some ZIP patches
    preparePatchZip("src/test/resources/content/patch1", "target/karaf/patches/source/patch-1.zip", false);
    PatchManagement service = (PatchManagement) pm;
    PatchData patchData = service.fetchPatches(new File("target/karaf/patches/source/patch-1.zip").toURI().toURL()).get(0);
    assertThat(patchData.getId(), equalTo("my-patch-1"));
    Patch patch = service.trackPatch(patchData);
    GitPatchRepository repository = ((GitPatchManagementServiceImpl) pm).getGitPatchRepository();
    Git fork = repository.cloneRepository(repository.findOrCreateMainGitRepository(), true);
    // we should see remote branch for the patch, but without checking it out, it won't be available in the clone's local branches
    List<Ref> branches = fork.branchList().setListMode(ListBranchCommand.ListMode.REMOTE).call();
    Ref patchBranch = null;
    for (Ref remoteBranch : branches) {
        if (String.format("refs/remotes/origin/patch-%s", patchData.getId()).equals(remoteBranch.getName())) {
            patchBranch = remoteBranch;
            break;
        }
    }
    assertNotNull("Should find remote branch for the added patch", patchBranch);
    assertThat(patch.getManagedPatch().getCommitId(), equalTo(patchBranch.getObjectId().getName()));
    RevCommit patchCommit = new RevWalk(fork.getRepository()).parseCommit(patchBranch.getObjectId());
    // patch commit should be child of baseline commit
    RevCommit baselineCommit = new RevWalk(fork.getRepository()).parseCommit(patchCommit.getParent(0));
    // this baseline commit should be tagged "baseline-VERSION"
    Ref tag = fork.tagList().call().get(0);
    assertThat(tag.getName(), equalTo("refs/tags/baseline-6.2.0"));
    RevCommit baselineCommitFromTag = new RevWalk(fork.getRepository()).parseCommit(tag.getTarget().getObjectId());
    assertThat(baselineCommit.getId(), equalTo(baselineCommitFromTag.getId()));
    // let's see the patch applied to baseline-6.2.0
    fork.checkout().setName("my-patch-1").setStartPoint("origin/patch-my-patch-1").setCreateBranch(true).call();
    String myProperties = FileUtils.readFileToString(new File(fork.getRepository().getWorkTree(), "etc/my.properties"));
    assertTrue(myProperties.contains("p1 = v1"));
    repository.closeRepository(fork, true);
}
Also used : Ref(org.eclipse.jgit.lib.Ref) GitPatchManagementServiceImpl(io.fabric8.patch.management.impl.GitPatchManagementServiceImpl) Git(org.eclipse.jgit.api.Git) GitPatchRepository(io.fabric8.patch.management.impl.GitPatchRepository) RevWalk(org.eclipse.jgit.revwalk.RevWalk) File(java.io.File) RevCommit(org.eclipse.jgit.revwalk.RevCommit) Test(org.junit.Test)

Example 18 with PatchData

use of io.fabric8.patch.management.PatchData in project fabric8 by jboss-fuse.

the class Offline method applyPatch.

protected void applyPatch(PatchData patch, ZipFile zipFile, File storage) throws IOException {
    log(DEBUG, "Applying patch: " + patch.getId() + " / " + patch.getDescription());
    File startupFile = new File(karafBase, "etc/startup.properties");
    File overridesFile = new File(karafBase, "etc/overrides.properties");
    List<String> startup = readLines(new File(karafBase, "etc/startup.properties"));
    List<String> overrides = readLines(overridesFile);
    List<Artifact> toExtract = new ArrayList<Artifact>();
    List<Artifact> toDelete = new ArrayList<Artifact>();
    for (String bundle : patch.getBundles()) {
        Artifact artifact = mvnurlToArtifact(bundle, true);
        if (artifact == null) {
            continue;
        }
        // Compute patch bundle version and range
        VersionRange range;
        Version oVer = VersionTable.getVersion(artifact.getVersion());
        String vr = patch.getVersionRange(bundle);
        String override;
        if (vr != null && !vr.isEmpty()) {
            override = bundle + OVERRIDE_RANGE + vr;
            range = VersionRange.parseVersionRange(vr);
        } else {
            override = bundle;
            Version v1 = new Version(oVer.getMajor(), oVer.getMinor(), 0);
            Version v2 = new Version(oVer.getMajor(), oVer.getMinor() + 1, 0);
            range = new VersionRange(false, v1, v2, true);
        }
        // Process overrides.properties
        boolean matching = false;
        boolean added = false;
        for (int i = 0; i < overrides.size(); i++) {
            String line = overrides.get(i).trim();
            if (!line.isEmpty() && !line.startsWith("#")) {
                Artifact overrideArtifact = mvnurlToArtifact(line, true);
                if (overrideArtifact != null) {
                    Version ver = VersionTable.getVersion(overrideArtifact.getVersion());
                    if (isSameButVersion(artifact, overrideArtifact) && range.contains(ver)) {
                        matching = true;
                        if (ver.compareTo(oVer) < 0) {
                            // Replace old override with the new one
                            overrides.set(i, override);
                            if (!added) {
                                log(DEBUG, "Replacing with artifact: " + override);
                                added = true;
                            }
                            // Remove old file
                            toDelete.add(overrideArtifact);
                            toExtract.remove(overrideArtifact);
                        }
                    }
                } else {
                    log(WARN, "Unable to convert to artifact: " + line);
                }
            }
        }
        // If there was not matching bundles, add it
        if (!matching) {
            overrides.add(override);
            log(DEBUG, "Adding artifact: " + override);
        }
        // Process startup.properties
        for (int i = 0; i < startup.size(); i++) {
            String line = startup.get(i).trim();
            if (!line.isEmpty() && !line.startsWith("#")) {
                int index = line.indexOf('=');
                String mvnUrl = Utils.pathToMvnurl(line.substring(0, index));
                if (mvnUrl != null) {
                    Artifact startupArtifact = mvnurlToArtifact(mvnUrl, true);
                    if (startupArtifact != null) {
                        Version ver = VersionTable.getVersion(startupArtifact.getVersion());
                        if (isSameButVersion(artifact, startupArtifact) && range.contains(ver)) {
                            matching = true;
                            // Now check versions
                            if (ver.compareTo(oVer) < 0) {
                                line = artifact.getPath() + line.substring(index);
                                startup.set(i, line);
                                log(DEBUG, "Overwriting startup.properties with: " + artifact);
                                added = true;
                            }
                        }
                    }
                }
            }
        }
        // Extract artifact
        if (!matching || added) {
            toExtract.add(artifact);
        }
    }
    // Extract / delete artifacts if needed
    if (zipFile != null) {
        for (Artifact artifact : toExtract) {
            log(DEBUG, "Extracting artifact: " + artifact);
            ZipEntry entry = zipFile.getEntry("repository/" + artifact.getPath());
            if (entry == null) {
                log(ERROR, "Could not find artifact in patch zip: " + artifact);
                continue;
            }
            File f = new File(karafBase, "system/" + artifact.getPath());
            if (!f.isFile()) {
                f.getParentFile().mkdirs();
                InputStream fis = zipFile.getInputStream(entry);
                FileOutputStream fos = new FileOutputStream(f);
                try {
                    IOUtils.copy(fis, fos);
                } finally {
                    IOUtils.closeQuietly(fis);
                    IOUtils.closeQuietly(fos);
                }
            }
        }
        for (Artifact artifact : toDelete) {
            String fileName = artifact.getPath();
            File file = new File(karafBase, "system/" + fileName);
            if (file.exists()) {
                log(DEBUG, "Removing old artifact " + artifact);
                file.delete();
            } else {
                log(WARN, "Could not find: " + file);
            }
        }
    }
    overrides = new ArrayList<String>(new HashSet<String>(overrides));
    Collections.sort(overrides);
    writeLines(overridesFile, overrides);
    writeLines(startupFile, startup);
    // update the remaining patch files (using either the patch ZIP file or the patch storage location)
    if (zipFile != null) {
        patchFiles(patch, zipFile);
    } else if (storage != null) {
        patchFiles(patch, storage);
    } else {
        throw new PatchException("Unable to update patch files: no access to patch ZIP file or patch storage location");
    }
    if (patch.getMigratorBundle() != null) {
        Artifact artifact = mvnurlToArtifact(patch.getMigratorBundle(), true);
        if (artifact != null) {
            // Copy it to the deploy dir
            File src = new File(karafBase, "system/" + artifact.getPath());
            File target = new File(new File(karafBase, "deploy"), artifact.getArtifactId() + ".jar");
            copy(src, target);
        }
    }
}
Also used : FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList) VersionRange(org.apache.felix.utils.version.VersionRange) Utils.mvnurlToArtifact(io.fabric8.patch.management.Utils.mvnurlToArtifact) Artifact(io.fabric8.patch.management.Artifact) Artifact.isSameButVersion(io.fabric8.patch.management.Artifact.isSameButVersion) Version(org.osgi.framework.Version) FileOutputStream(java.io.FileOutputStream) PatchException(io.fabric8.patch.management.PatchException) ZipFile(java.util.zip.ZipFile) File(java.io.File) HashSet(java.util.HashSet)

Example 19 with PatchData

use of io.fabric8.patch.management.PatchData in project fabric8 by jboss-fuse.

the class Offline method extractPatch.

protected List<PatchData> extractPatch(ZipFile zipFile) throws IOException {
    List<PatchData> patches = new ArrayList<PatchData>();
    Enumeration<? extends ZipEntry> entries = zipFile.entries();
    while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        if (!entry.isDirectory()) {
            String entryName = entry.getName();
            if (entryName.endsWith(".patch") && !entryName.contains("/")) {
                InputStream fis = zipFile.getInputStream(entry);
                try {
                    PatchData patch = PatchData.load(fis);
                    patches.add(patch);
                } finally {
                    IOUtils.closeQuietly(fis);
                }
            }
        }
    }
    return patches;
}
Also used : PatchData(io.fabric8.patch.management.PatchData) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList)

Example 20 with PatchData

use of io.fabric8.patch.management.PatchData in project fabric8 by jboss-fuse.

the class GitPatchManagementServiceImpl method loadPatchData.

/**
 * Reads content of patch descriptor into non-(yet)-managed patch data structure
 * @param patchDescriptor
 * @return
 */
private PatchData loadPatchData(File patchDescriptor) throws IOException {
    Properties properties = new Properties();
    FileInputStream inputStream = null;
    try {
        inputStream = new FileInputStream(patchDescriptor);
        properties.load(inputStream);
        boolean ok = properties.containsKey("id") && properties.containsKey("bundle.count");
        if (!ok) {
            throw new PatchException("Patch descriptor is not valid");
        }
        return PatchData.load(properties);
    } finally {
        IOUtils.closeQuietly(inputStream);
    }
}
Also used : PatchException(io.fabric8.patch.management.PatchException) Properties(java.util.Properties) FileInputStream(java.io.FileInputStream)

Aggregations

File (java.io.File)32 Test (org.junit.Test)25 Git (org.eclipse.jgit.api.Git)23 GitPatchRepository (io.fabric8.patch.management.impl.GitPatchRepository)21 GitPatchManagementServiceImpl (io.fabric8.patch.management.impl.GitPatchManagementServiceImpl)18 ObjectId (org.eclipse.jgit.lib.ObjectId)15 PatchData (io.fabric8.patch.management.PatchData)12 PatchException (io.fabric8.patch.management.PatchException)10 RevCommit (org.eclipse.jgit.revwalk.RevCommit)10 FileInputStream (java.io.FileInputStream)9 IOException (java.io.IOException)9 Patch (io.fabric8.patch.management.Patch)8 ZipFile (org.apache.commons.compress.archivers.zip.ZipFile)8 LinkedList (java.util.LinkedList)7 Map (java.util.Map)6 RevWalk (org.eclipse.jgit.revwalk.RevWalk)6 ArrayList (java.util.ArrayList)5 Properties (java.util.Properties)5 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)5 Artifact (io.fabric8.patch.management.Artifact)4