Prepare usage of guest os command.
This commit is contained in:
parent
5ad052ffe4
commit
e291352828
3 changed files with 49 additions and 3 deletions
|
|
@ -20,6 +20,7 @@ package org.jdrupes.vmoperator.runner.qemu;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
@ -28,6 +29,8 @@ import java.net.UnixDomainSocketAddress;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.jdrupes.vmoperator.runner.qemu.commands.QmpCommand;
|
import org.jdrupes.vmoperator.runner.qemu.commands.QmpCommand;
|
||||||
|
|
@ -65,6 +68,8 @@ public class GuestAgentClient extends Component {
|
||||||
|
|
||||||
private EventPipeline rep;
|
private EventPipeline rep;
|
||||||
private Path socketPath;
|
private Path socketPath;
|
||||||
|
private List<Map<String, String>> guestAgentCmds;
|
||||||
|
private String guestAgentCmd;
|
||||||
private SocketIOChannel gaChannel;
|
private SocketIOChannel gaChannel;
|
||||||
private final Queue<QmpCommand> executing = new LinkedList<>();
|
private final Queue<QmpCommand> executing = new LinkedList<>();
|
||||||
|
|
||||||
|
|
@ -72,6 +77,7 @@ public class GuestAgentClient extends Component {
|
||||||
* Instantiates a new guest agent client.
|
* Instantiates a new guest agent client.
|
||||||
*
|
*
|
||||||
* @param componentChannel the component channel
|
* @param componentChannel the component channel
|
||||||
|
* @param guestAgentCmds
|
||||||
* @throws IOException Signals that an I/O exception has occurred.
|
* @throws IOException Signals that an I/O exception has occurred.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "PMD.AssignmentToNonFinalStatic",
|
@SuppressWarnings({ "PMD.AssignmentToNonFinalStatic",
|
||||||
|
|
@ -87,10 +93,20 @@ public class GuestAgentClient extends Component {
|
||||||
* forwarded from the {@link Runner} instead.
|
* forwarded from the {@link Runner} instead.
|
||||||
*
|
*
|
||||||
* @param socketPath the socket path
|
* @param socketPath the socket path
|
||||||
|
* @param guestAgentCmds
|
||||||
* @param powerdownTimeout
|
* @param powerdownTimeout
|
||||||
*/
|
*/
|
||||||
/* default */ void configure(Path socketPath) {
|
@SuppressWarnings("PMD.EmptyCatchBlock")
|
||||||
|
/* default */ void configure(Path socketPath, ArrayNode guestAgentCmds) {
|
||||||
this.socketPath = socketPath;
|
this.socketPath = socketPath;
|
||||||
|
try {
|
||||||
|
this.guestAgentCmds = mapper.convertValue(guestAgentCmds,
|
||||||
|
mapper.constructType(getClass()
|
||||||
|
.getDeclaredField("guestAgentCmds").getGenericType()));
|
||||||
|
} catch (IllegalArgumentException | NoSuchFieldException
|
||||||
|
| SecurityException e) {
|
||||||
|
// Cannot happen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -193,7 +209,7 @@ public class GuestAgentClient extends Component {
|
||||||
() -> String.format("(Previous \"guest agent(in)\" is "
|
() -> String.format("(Previous \"guest agent(in)\" is "
|
||||||
+ "result from executing %s)", executed));
|
+ "result from executing %s)", executed));
|
||||||
if (executed instanceof QmpGuestGetOsinfo) {
|
if (executed instanceof QmpGuestGetOsinfo) {
|
||||||
rep.fire(new OsinfoEvent(response.get("return")));
|
processOsInfo(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
|
|
@ -201,6 +217,25 @@ public class GuestAgentClient extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processOsInfo(ObjectNode response) {
|
||||||
|
var osInfo = new OsinfoEvent(response.get("return"));
|
||||||
|
var osId = osInfo.osinfo().get("id").asText();
|
||||||
|
for (var cmdDef : guestAgentCmds) {
|
||||||
|
if (osId.equals(cmdDef.get("osId"))
|
||||||
|
|| "*".equals(cmdDef.get("osId"))) {
|
||||||
|
guestAgentCmd = cmdDef.get("executable");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (guestAgentCmd == null) {
|
||||||
|
logger.warning(() -> "No guest agent command for OS " + osId);
|
||||||
|
} else {
|
||||||
|
logger.fine(() -> "Guest agent command for OS " + osId
|
||||||
|
+ " is " + guestAgentCmd);
|
||||||
|
}
|
||||||
|
rep.fire(osInfo);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On closed.
|
* On closed.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
|
||||||
import freemarker.core.ParseException;
|
import freemarker.core.ParseException;
|
||||||
|
|
@ -197,6 +198,7 @@ public class Runner extends Component {
|
||||||
private static final String QEMU = "qemu";
|
private static final String QEMU = "qemu";
|
||||||
private static final String SWTPM = "swtpm";
|
private static final String SWTPM = "swtpm";
|
||||||
private static final String CLOUD_INIT_IMG = "cloudInitImg";
|
private static final String CLOUD_INIT_IMG = "cloudInitImg";
|
||||||
|
private static final String GUEST_AGENT_CMDS = "guestAgentCmds";
|
||||||
private static final String TEMPLATE_DIR
|
private static final String TEMPLATE_DIR
|
||||||
= "/opt/" + APP_NAME.replace("-", "") + "/templates";
|
= "/opt/" + APP_NAME.replace("-", "") + "/templates";
|
||||||
private static final String DEFAULT_TEMPLATE
|
private static final String DEFAULT_TEMPLATE
|
||||||
|
|
@ -348,11 +350,16 @@ public class Runner extends Component {
|
||||||
.map(d -> new CommandDefinition(CLOUD_INIT_IMG, d))
|
.map(d -> new CommandDefinition(CLOUD_INIT_IMG, d))
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
logger.finest(() -> cloudInitImgDefinition.toString());
|
logger.finest(() -> cloudInitImgDefinition.toString());
|
||||||
|
var guestAgentCmds = (ArrayNode) tplData.get(GUEST_AGENT_CMDS);
|
||||||
|
if (guestAgentCmds != null) {
|
||||||
|
logger.finest(
|
||||||
|
() -> "GuestAgentCmds: " + guestAgentCmds.toString());
|
||||||
|
}
|
||||||
|
|
||||||
// Forward some values to child components
|
// Forward some values to child components
|
||||||
qemuMonitor.configure(config.monitorSocket,
|
qemuMonitor.configure(config.monitorSocket,
|
||||||
config.vm.powerdownTimeout);
|
config.vm.powerdownTimeout);
|
||||||
guestAgentClient.configure(config.guestAgentSocket);
|
guestAgentClient.configure(config.guestAgentSocket, guestAgentCmds);
|
||||||
} catch (IllegalArgumentException | IOException | TemplateException e) {
|
} catch (IllegalArgumentException | IOException | TemplateException e) {
|
||||||
logger.log(Level.SEVERE, e, () -> "Invalid configuration: "
|
logger.log(Level.SEVERE, e, () -> "Invalid configuration: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
|
|
|
||||||
|
|
@ -233,3 +233,7 @@
|
||||||
</#list>
|
</#list>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
"guestAgentCmds":
|
||||||
|
- "osId": "*"
|
||||||
|
"executable": "/usr/local/libexec/vm-operator-cmd"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue