refactor: compatibility issues with plugins lacking loadLocation after upgrading (#3873)

#### What type of PR is this?
/kind improvement
/area core
/milestone 2.5.x

#### What this PR does / why we need it:
修复插件缺失路径信息升级后无法使用的兼容性问题

how to test it?
1. 生产模式安装插件
2. 更新插件将插件中的 status.loadLocation 和 metadata.annotations["plugin.halo.run/plugin-path"] 删除
3. 查看插件功能是否正常
#### Does this PR introduce a user-facing change?

```release-note
修复插件缺失路径信息升级后无法使用的兼容性问题
```
pull/3874/head
guqing 2023-04-28 15:40:19 +08:00 committed by GitHub
parent 0794644dbd
commit 6789d4c90f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 21 deletions

View File

@ -61,6 +61,7 @@ import run.halo.app.plugin.HaloPluginManager;
import run.halo.app.plugin.PluginConst;
import run.halo.app.plugin.PluginExtensionLoaderUtils;
import run.halo.app.plugin.PluginStartingError;
import run.halo.app.plugin.PluginUtils;
import run.halo.app.plugin.YamlPluginFinder;
import run.halo.app.plugin.event.PluginCreatedEvent;
import run.halo.app.plugin.resources.BundleResourceUtils;
@ -106,6 +107,7 @@ public class PluginReconciler implements Reconciler<Request> {
})
.orElse(Result.doNotRetry());
} catch (DoNotRetryException e) {
log.error("Failed to reconcile plugin: [{}]", request.name(), e);
persistenceFailureStatus(request.name(), e);
return Result.doNotRetry();
}
@ -117,12 +119,11 @@ public class PluginReconciler implements Reconciler<Request> {
Map<String, String> annotations = nullSafeAnnotations(plugin);
String oldPluginPath = annotations.get(PLUGIN_PATH);
String pluginPath = oldPluginPath;
if (StringUtils.isBlank(oldPluginPath)) {
if (StringUtils.isBlank(pluginPath)) {
URI loadLocation = plugin.statusNonNull().getLoadLocation();
if (loadLocation == null) {
throw new DoNotRetryException("Can not determine plugin path: " + name);
}
pluginPath = loadLocation.getPath();
pluginPath = Optional.ofNullable(loadLocation)
.map(URI::getPath)
.orElseGet(() -> PluginUtils.generateFileName(plugin));
}
annotations.put(PLUGIN_PATH, pluginPath);
if (!StringUtils.equals(pluginPath, oldPluginPath)) {
@ -321,14 +322,18 @@ public class PluginReconciler implements Reconciler<Request> {
client.fetch(Plugin.class, pluginName).ifPresent(plugin -> {
Plugin.PluginStatus status = plugin.statusNonNull();
PluginWrapper pluginWrapper = getPluginWrapper(pluginName);
status.setPhase(pluginWrapper.getPluginState());
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(pluginName);
PluginState pluginState = Optional.ofNullable(pluginWrapper)
.map(PluginWrapper::getPluginState)
.orElse(PluginState.FAILED);
status.setPhase(pluginState);
Plugin.PluginStatus oldStatus = JsonUtils.deepCopy(status);
Condition condition = Condition.builder()
.type(PluginState.FAILED.toString())
.reason("UnexpectedState")
.message(e.getMessage())
.message(StringUtils.defaultString(e.getMessage()))
.status(ConditionStatus.FALSE)
.lastTransitionTime(Instant.now())
.build();

View File

@ -11,7 +11,6 @@ import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.pf4j.PluginWrapper;
import org.springframework.core.io.Resource;
@ -35,6 +34,7 @@ import run.halo.app.infra.utils.VersionUtils;
import run.halo.app.plugin.HaloPluginManager;
import run.halo.app.plugin.PluginConst;
import run.halo.app.plugin.PluginProperties;
import run.halo.app.plugin.PluginUtils;
import run.halo.app.plugin.YamlPluginFinder;
@Slf4j
@ -144,7 +144,7 @@ public class PluginServiceImpl implements PluginService {
private Mono<Path> copyToPluginHome(Plugin plugin) {
return Mono.fromCallable(
() -> {
var fileName = generateFileName(plugin);
var fileName = PluginUtils.generateFileName(plugin);
var pluginRoot = Paths.get(pluginProperties.getPluginsRoot());
try {
Files.createDirectories(pluginRoot);
@ -162,17 +162,6 @@ public class PluginServiceImpl implements PluginService {
.subscribeOn(Schedulers.boundedElastic());
}
static String generateFileName(Plugin plugin) {
Assert.notNull(plugin, "The plugin must not be null.");
Assert.notNull(plugin.getMetadata(), "The plugin metadata must not be null.");
Assert.notNull(plugin.getSpec(), "The plugin spec must not be null.");
String version = plugin.getSpec().getVersion();
if (StringUtils.isBlank(version)) {
throw new ServerWebInputException("The plugin version must not be blank.");
}
return String.format("%s-%s.jar", plugin.getMetadata().getName(), version);
}
private void satisfiesRequiresVersion(Plugin newPlugin) {
Assert.notNull(newPlugin, "The plugin must not be null.");
Version version = systemVersion.get();

View File

@ -0,0 +1,22 @@
package run.halo.app.plugin;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebInputException;
import run.halo.app.core.extension.Plugin;
@UtilityClass
public class PluginUtils {
public static String generateFileName(Plugin plugin) {
Assert.notNull(plugin, "The plugin must not be null.");
Assert.notNull(plugin.getMetadata(), "The plugin metadata must not be null.");
Assert.notNull(plugin.getSpec(), "The plugin spec must not be null.");
String version = plugin.getSpec().getVersion();
if (StringUtils.isBlank(version)) {
throw new ServerWebInputException("The plugin version must not be blank.");
}
return String.format("%s-%s.jar", plugin.getMetadata().getName(), version);
}
}