mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-25 11:45:49 +01:00
Add console commands to manage add-ons (#4057)
* Add console commands to manage add-ons Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
parent
4905805ea8
commit
718839052a
@ -20,6 +20,11 @@
|
|||||||
<artifactId>org.openhab.core</artifactId>
|
<artifactId>org.openhab.core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.core.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.core.addon</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2024 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.core.io.console.internal.extension;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.addon.Addon;
|
||||||
|
import org.openhab.core.addon.AddonService;
|
||||||
|
import org.openhab.core.io.console.Console;
|
||||||
|
import org.openhab.core.io.console.ConsoleCommandCompleter;
|
||||||
|
import org.openhab.core.io.console.StringsCompleter;
|
||||||
|
import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension;
|
||||||
|
import org.openhab.core.io.console.extensions.ConsoleCommandExtension;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Console command extension to manage add-ons
|
||||||
|
*
|
||||||
|
* @author Jan N. Klug - Initial contribution
|
||||||
|
*/
|
||||||
|
@Component(service = ConsoleCommandExtension.class)
|
||||||
|
@NonNullByDefault
|
||||||
|
public class AddonConsoleCommandExtension extends AbstractConsoleCommandExtension {
|
||||||
|
|
||||||
|
private static final String SUBCMD_LIST = "list";
|
||||||
|
private static final String SUBCMD_SERVICES = "services";
|
||||||
|
private static final String SUBCMD_INSTALL = "install";
|
||||||
|
private static final String SUBCMD_UNINSTALL = "uninstall";
|
||||||
|
private static final StringsCompleter SUBCMD_COMPLETER = new StringsCompleter(
|
||||||
|
List.of(SUBCMD_LIST, SUBCMD_SERVICES, SUBCMD_INSTALL, SUBCMD_UNINSTALL), false);
|
||||||
|
|
||||||
|
private class AddonConsoleCommandCompleter implements ConsoleCommandCompleter {
|
||||||
|
@Override
|
||||||
|
public boolean complete(String[] args, int cursorArgumentIndex, int cursorPosition, List<String> candidates) {
|
||||||
|
if (cursorArgumentIndex <= 0) {
|
||||||
|
return SUBCMD_COMPLETER.complete(args, cursorArgumentIndex, cursorPosition, candidates);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<String, AddonService> addonServices = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Activate
|
||||||
|
public AddonConsoleCommandExtension() {
|
||||||
|
super("addons", "Manage add-ons.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Reference(cardinality = ReferenceCardinality.MULTIPLE)
|
||||||
|
public void bindAddonService(AddonService addonService) {
|
||||||
|
addonServices.put(addonService.getId(), addonService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unbindAddonService(AddonService addonService) {
|
||||||
|
addonServices.remove(addonService.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getUsages() {
|
||||||
|
return List.of(buildCommandUsage(SUBCMD_SERVICES, "list all available add-on services"),
|
||||||
|
buildCommandUsage(SUBCMD_LIST + " [<serviceId>]",
|
||||||
|
"lists names of all add-ons (from the named service, if given)"),
|
||||||
|
buildCommandUsage(SUBCMD_INSTALL + " <addonUid>", "installs the given add-on"),
|
||||||
|
buildCommandUsage(SUBCMD_UNINSTALL + " <addonUid>", "uninstalls the given add-on"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(String[] args, Console console) {
|
||||||
|
if (args.length > 0) {
|
||||||
|
String subCommand = args[0];
|
||||||
|
switch (subCommand) {
|
||||||
|
case SUBCMD_SERVICES:
|
||||||
|
listServices(console);
|
||||||
|
break;
|
||||||
|
case SUBCMD_LIST:
|
||||||
|
listAddons(console, (args.length < 2) ? "" : args[1]);
|
||||||
|
break;
|
||||||
|
case SUBCMD_INSTALL:
|
||||||
|
if (args.length == 2) {
|
||||||
|
installAddon(console, args[1]);
|
||||||
|
} else {
|
||||||
|
console.println("Specify the UID of the add-on to install: " + getCommand() + " "
|
||||||
|
+ SUBCMD_INSTALL + " <addonUid>");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SUBCMD_UNINSTALL:
|
||||||
|
if (args.length == 2) {
|
||||||
|
uninstallAddon(console, args[1]);
|
||||||
|
} else {
|
||||||
|
console.println("Specify the UID of the add-on to uninstall: " + getCommand() + " "
|
||||||
|
+ SUBCMD_UNINSTALL + " <addonUid>");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.println("Unknown command '" + subCommand + "'");
|
||||||
|
printUsage(console);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printUsage(console);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ConsoleCommandCompleter getCompleter() {
|
||||||
|
return new AddonConsoleCommandCompleter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void listServices(Console console) {
|
||||||
|
addonServices.values().forEach(s -> console.println(String.format("%-20s %s", s.getId(), s.getName())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void listAddons(Console console, String serviceId) {
|
||||||
|
List<Addon> addons;
|
||||||
|
if (serviceId.isBlank()) {
|
||||||
|
addons = addonServices.values().stream().map(s -> s.getAddons(null)).flatMap(List::stream).toList();
|
||||||
|
} else {
|
||||||
|
AddonService service = addonServices.get(serviceId);
|
||||||
|
if (service == null) {
|
||||||
|
console.println("Add-on service '" + serviceId + "' is not known.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addons = service.getAddons(null);
|
||||||
|
}
|
||||||
|
addons.forEach(addon -> console.println(String.format("%s %-45s %-20s %s", addon.isInstalled() ? "i" : " ",
|
||||||
|
addon.getUid(), addon.getVersion().isBlank() ? "not set" : addon.getVersion(), addon.getLabel())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installAddon(Console console, String addonUid) {
|
||||||
|
String[] parts = addonUid.split(":");
|
||||||
|
String serviceId = parts.length == 2 ? parts[0] : "karaf";
|
||||||
|
String addonId = parts.length == 2 ? parts[1] : parts[0];
|
||||||
|
AddonService service = addonServices.get(serviceId);
|
||||||
|
if (service == null) {
|
||||||
|
console.println("Could not find requested add-on service. Add-on " + addonUid + " not installed.");
|
||||||
|
} else {
|
||||||
|
Addon addon = service.getAddon(addonId, null);
|
||||||
|
if (addon == null) {
|
||||||
|
console.println("Could not find add-on in add-on service. Add-on " + addonUid + " not installed.");
|
||||||
|
} else if (addon.isInstalled()) {
|
||||||
|
console.println("Add-on " + addonUid + " is already installed.");
|
||||||
|
} else {
|
||||||
|
service.install(addonId);
|
||||||
|
console.println("Installed " + addonUid + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uninstallAddon(Console console, String addonUid) {
|
||||||
|
String[] parts = addonUid.split(":");
|
||||||
|
String serviceId = parts.length == 2 ? parts[0] : "karaf";
|
||||||
|
String addonId = parts.length == 2 ? parts[1] : parts[0];
|
||||||
|
AddonService service = addonServices.get(serviceId);
|
||||||
|
if (service == null) {
|
||||||
|
console.println("Could not find requested add-on service. Add-on " + addonUid + " not uninstalled.");
|
||||||
|
} else {
|
||||||
|
Addon addon = service.getAddon(addonId, null);
|
||||||
|
if (addon == null) {
|
||||||
|
console.println("Could not find add-on in add-on service. Add-on " + addonUid + " not uninstalled.");
|
||||||
|
} else if (!addon.isInstalled()) {
|
||||||
|
console.println("Add-on " + addonUid + " is not installed.");
|
||||||
|
} else {
|
||||||
|
service.uninstall(addonId);
|
||||||
|
console.println("Uninstalled " + addonUid + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user