add rest api updateAllPlugins

This commit is contained in:
Eduard Heimbuch
2019-09-27 15:30:21 +02:00
parent 32cb67f92e
commit 281d812065
11 changed files with 99 additions and 2 deletions

View File

@@ -94,5 +94,13 @@ public interface PluginManager {
*/ */
void executePendingAndRestart(); void executePendingAndRestart();
/**
* Cancel all pending plugins.
*/
void cancelPending(); void cancelPending();
/**
* Update all installed plugins.
*/
void updateAll(boolean restartAfterInstallation);
} }

View File

@@ -30,6 +30,8 @@
"availableNavLink": "Verfügbar" "availableNavLink": "Verfügbar"
}, },
"executePending": "Ausstehende Plugin-Änderungen ausführen", "executePending": "Ausstehende Plugin-Änderungen ausführen",
"updateAll": "Alle Plugins aktualisieren",
"cancelPending": "Ausstehende Plugin-Änderungen abbrechen",
"noPlugins": "Keine Plugins gefunden.", "noPlugins": "Keine Plugins gefunden.",
"modal": { "modal": {
"title": { "title": {

View File

@@ -30,6 +30,8 @@
"availableNavLink": "Available" "availableNavLink": "Available"
}, },
"executePending": "Execute pending plugin changes", "executePending": "Execute pending plugin changes",
"updateAll": "Update all plugins",
"cancelPending": "Cancel pending plugin changes",
"noPlugins": "No plugins found.", "noPlugins": "No plugins found.",
"modal": { "modal": {
"title": { "title": {

View File

@@ -30,6 +30,8 @@
"availableNavLink": "Disponibles" "availableNavLink": "Disponibles"
}, },
"executePending": "Ejecutar los complementos pendientes", "executePending": "Ejecutar los complementos pendientes",
"updateAll": "Actualizar todos los complementos",
"cancelPending": "Cancelar los complementos pendientes",
"noPlugins": "No se han encontrado complementos.", "noPlugins": "No se han encontrado complementos.",
"modal": { "modal": {
"title": { "title": {

View File

@@ -155,13 +155,14 @@ class MultiPluginActionModal extends React.Component<Props, State> {
}; };
renderUpdatable = () => { renderUpdatable = () => {
const { installedPlugins } = this.props; const {installedPlugins, t} = this.props;
return ( return (
<> <>
{installedPlugins && {installedPlugins &&
installedPlugins._embedded && installedPlugins._embedded &&
installedPlugins._embedded.plugins && ( installedPlugins._embedded.plugins && (
<> <>
<strong>{t("plugins.modal.updateQueue")}</strong>
<ul> <ul>
{installedPlugins._embedded.plugins {installedPlugins._embedded.plugins
.filter(plugin => plugin._links && plugin._links.update) .filter(plugin => plugin._links && plugin._links.update)

View File

@@ -56,6 +56,21 @@ public class InstalledPluginResource {
return Response.ok(collectionMapper.mapInstalled(plugins, available)).build(); return Response.ok(collectionMapper.mapInstalled(plugins, available)).build();
} }
/**
* Updates all installed plugins.
*/
@POST
@Path("/update")
@StatusCodes({
@ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(CollectionDto.class)
public Response updateAll(@QueryParam("restart") boolean restartAfterInstallation) {
pluginManager.updateAll(restartAfterInstallation);
return Response.ok().build();
}
/** /**
* Returns the installed plugin with the given id. * Returns the installed plugin with the given id.
* *

View File

@@ -12,6 +12,7 @@ import sonia.scm.plugin.PluginPermissions;
import java.util.List; import java.util.List;
import static de.otto.edison.hal.Embedded.embeddedBuilder; import static de.otto.edison.hal.Embedded.embeddedBuilder;
import static de.otto.edison.hal.Link.*;
import static de.otto.edison.hal.Links.linkingTo; import static de.otto.edison.hal.Links.linkingTo;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
@@ -44,6 +45,9 @@ public class PluginDtoCollectionMapper {
Links.Builder linksBuilder = linkingTo() Links.Builder linksBuilder = linkingTo()
.with(Links.linkingTo().self(baseUrl).build()); .with(Links.linkingTo().self(baseUrl).build());
linksBuilder.single(link("update", resourceLinks.installedPluginCollection().update()));
return linksBuilder.build(); return linksBuilder.build();
} }

View File

@@ -686,6 +686,10 @@ class ResourceLinks {
String self() { String self() {
return installedPluginCollectionLinkBuilder.method("installedPlugins").parameters().method("getInstalledPlugins").parameters().href(); return installedPluginCollectionLinkBuilder.method("installedPlugins").parameters().method("getInstalledPlugins").parameters().href();
} }
String update() {
return installedPluginCollectionLinkBuilder.method("installedPlugins").parameters().method("updateAll").parameters().href();
}
} }
public AvailablePluginLinks availablePlugin() { public AvailablePluginLinks availablePlugin() {

View File

@@ -193,7 +193,6 @@ public class DefaultPluginManager implements PluginManager {
.orElseThrow(() -> NotFoundException.notFound(entity(InstalledPlugin.class, name))); .orElseThrow(() -> NotFoundException.notFound(entity(InstalledPlugin.class, name)));
doThrow().violation("plugin is a core plugin and cannot be uninstalled").when(installed.isCore()); doThrow().violation("plugin is a core plugin and cannot be uninstalled").when(installed.isCore());
markForUninstall(installed); markForUninstall(installed);
if (restartAfterInstallation) { if (restartAfterInstallation) {
@@ -279,4 +278,19 @@ public class DefaultPluginManager implements PluginManager {
pendingUninstallQueue.forEach(PendingPluginUninstallation::cancel); pendingUninstallQueue.forEach(PendingPluginUninstallation::cancel);
pendingInstallQueue.forEach(PendingPluginInstallation::cancel); pendingInstallQueue.forEach(PendingPluginInstallation::cancel);
} }
@Override
public void updateAll(boolean restartAfterInstallation) {
PluginPermissions.manage().check();
for (InstalledPlugin installedPlugin : getInstalled()) {
String pluginName = installedPlugin.getDescriptor().getInformation().getName();
if (isUpdatable(pluginName)) {
install(pluginName, false);
}
if (restartAfterInstallation) {
restart("update all plugin");
}
}
}
} }

View File

@@ -474,6 +474,39 @@ class DefaultPluginManagerTest {
Boolean lasUninstallMarkerSet = uninstallCaptor.getAllValues().get(uninstallCaptor.getAllValues().size() - 1); Boolean lasUninstallMarkerSet = uninstallCaptor.getAllValues().get(uninstallCaptor.getAllValues().size() - 1);
assertThat(lasUninstallMarkerSet).isFalse(); assertThat(lasUninstallMarkerSet).isFalse();
} }
@Test
void shouldUpdateAllPlugins() {
InstalledPlugin mailPlugin = createInstalled("scm-mail-plugin");
InstalledPlugin reviewPlugin = createInstalled("scm-review-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(mailPlugin, reviewPlugin));
AvailablePlugin newMailPlugin = createAvailable("scm-mail-plugin", "2.0.0");
AvailablePlugin newReviewPlugin = createAvailable("scm-review-plugin", "2.0.0");
when(center.getAvailable()).thenReturn(ImmutableSet.of(newMailPlugin, newReviewPlugin));
manager.updateAll(false);
verify(installer).install(newMailPlugin);
verify(installer).install(newReviewPlugin);
}
@Test
void shouldNotUpdateToOldPluginVersions() {
InstalledPlugin scriptPlugin = createInstalled("scm-script-plugin");
when(loader.getInstalledPlugins()).thenReturn(ImmutableList.of(scriptPlugin));
AvailablePlugin oldScriptPlugin = createAvailable("scm-script-plugin", "0.9");
when(center.getAvailable()).thenReturn(ImmutableSet.of(oldScriptPlugin));
manager.updateAll(false);
verify(installer, never()).install(oldScriptPlugin);
}
} }
@Nested @Nested
@@ -533,5 +566,10 @@ class DefaultPluginManagerTest {
void shouldThrowAuthorizationExceptionsForCancelPending() { void shouldThrowAuthorizationExceptionsForCancelPending() {
assertThrows(AuthorizationException.class, () -> manager.cancelPending()); assertThrows(AuthorizationException.class, () -> manager.cancelPending());
} }
@Test
void shouldThrowAuthorizationExceptionsForUpdateAll() {
assertThrows(AuthorizationException.class, () -> manager.updateAll(false));
}
} }
} }

View File

@@ -14,6 +14,13 @@ public class PluginTestHelper {
return createAvailable(information); return createAvailable(information);
} }
public static AvailablePlugin createAvailable(String name, String version) {
PluginInformation information = new PluginInformation();
information.setName(name);
information.setVersion(version);
return createAvailable(information);
}
public static InstalledPlugin createInstalled(String name) { public static InstalledPlugin createInstalled(String name) {
PluginInformation information = new PluginInformation(); PluginInformation information = new PluginInformation();
information.setName(name); information.setName(name);