From 7fb1cc95af2700db5748838b6087d1ee25709291 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 27 Jul 2023 18:47:00 +0200 Subject: [PATCH] Add configuration. --- .../config-sample.yaml | 5 ++ .../vmoperator/manager/Controller.java | 51 +++++++++++++++++++ .../jdrupes/vmoperator/manager/Operator.java | 36 +++++++++++-- 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 org.jdrupes.vmoperator.manager/config-sample.yaml diff --git a/org.jdrupes.vmoperator.manager/config-sample.yaml b/org.jdrupes.vmoperator.manager/config-sample.yaml new file mode 100644 index 0000000..dfd1e1f --- /dev/null +++ b/org.jdrupes.vmoperator.manager/config-sample.yaml @@ -0,0 +1,5 @@ +# The values in comments are the defaults. + +"/Operator": + "/Controller": + test: yes diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java index 9ceb232..40598c2 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java @@ -19,14 +19,20 @@ package org.jdrupes.vmoperator.manager; import java.io.IOException; +import java.util.Map; import org.jgrapes.core.Channel; import org.jgrapes.core.Component; +import org.jgrapes.core.annotation.Handler; +import org.jgrapes.util.events.ConfigurationUpdate; +import org.jgrapes.util.events.InitialConfiguration; /** * The application class. */ public class Controller extends Component { +// private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + /** * Instantiates a new manager. * @@ -38,4 +44,49 @@ public class Controller extends Component { attach(new VmWatcher(channel())); attach(new Reconciler(channel())); } + + /** + * On configuration update. + * + * @param event the event + */ + @Handler + public void onConfigurationUpdate(ConfigurationUpdate event) { + event.structured(componentPath()).ifPresent(c -> { + if (event instanceof InitialConfiguration) { + processInitialConfiguration(c); + } + }); + } + + private void processInitialConfiguration( + Map runnerConfiguration) { +// try { +// config = mapper.convertValue(runnerConfiguration, +// Configuration.class); +// if (!config.check()) { +// // Invalid configuration, not used, problems already logged. +// config = null; +// } +// +// // Prepare firmware files and add to config +// setFirmwarePaths(); +// +// // Obtain more context data from template +// var tplData = dataFromTemplate(); +// swtpmDefinition = Optional.ofNullable(tplData.get("swtpm")) +// .map(d -> new CommandDefinition("swtpm", d)).orElse(null); +// qemuDefinition = Optional.ofNullable(tplData.get("qemu")) +// .map(d -> new CommandDefinition("qemu", d)).orElse(null); +// +// // Forward some values to child components +// qemuMonitor.configure(config.monitorSocket, +// config.vm.powerdownTimeout); +// } catch (IllegalArgumentException | IOException | TemplateException e) { +// logger.log(Level.SEVERE, e, () -> "Invalid configuration: " +// + e.getMessage()); +// // Don't use default configuration +// config = null; +// } + } } diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Operator.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Operator.java index d87b7d1..24476fd 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Operator.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Operator.java @@ -18,10 +18,17 @@ package org.jdrupes.vmoperator.manager; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.util.logging.LogManager; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import static org.jdrupes.vmoperator.manager.Constants.VM_OP_NAME; import org.jdrupes.vmoperator.util.FsdUtils; import org.jgrapes.core.Channel; import org.jgrapes.core.Component; @@ -29,6 +36,9 @@ import org.jgrapes.core.Components; import org.jgrapes.core.annotation.Handler; import org.jgrapes.core.events.Stop; import org.jgrapes.io.NioDispatcher; +import org.jgrapes.util.FileSystemWatcher; +import org.jgrapes.util.YamlConfigurationStore; +import org.jgrapes.util.events.WatchFile; /** * The application class. @@ -39,13 +49,26 @@ public class Operator extends Component { /** * Instantiates a new manager. + * @param cmdLine * * @throws IOException Signals that an I/O exception has occurred. */ - public Operator() throws IOException { + public Operator(CommandLine cmdLine) throws IOException { // Prepare component tree attach(new NioDispatcher()); + attach(new FileSystemWatcher(channel())); attach(new Controller(channel())); + + // Configuration store with file in /etc/opt (default) + File config = new File(cmdLine.getOptionValue('c', + "/etc/opt/" + VM_OP_NAME + "/config.yaml")); + // Don't rely on night config to produce a good exception + // for this simple case + if (!Files.isReadable(config.toPath())) { + throw new IOException("Cannot read configuration file " + config); + } + attach(new YamlConfigurationStore(channel(), config, false)); + fire(new WatchFile(config.toPath())); } /** @@ -66,7 +89,8 @@ public class Operator extends Component { if (path.isPresent()) { props = Files.newInputStream(path.get()); } else { - props = Operator.class.getResourceAsStream("logging.properties"); + props + = Operator.class.getResourceAsStream("logging.properties"); } LogManager.getLogManager().readConfiguration(props); } catch (IOException e) { @@ -82,8 +106,14 @@ public class Operator extends Component { */ @SuppressWarnings("PMD.SignatureDeclareThrowsException") public static void main(String[] args) throws Exception { + CommandLineParser parser = new DefaultParser(); + // parse the command line arguments + final Options options = new Options(); + options.addOption(new Option("c", "config", true, "The configu" + + "ration file (defaults to /etc/opt/vmoperator/config.yaml).")); + CommandLine cmd = parser.parse(options, args); // The Operator is the root component - app = new Operator(); + app = new Operator(cmd); // Prepare Stop Runtime.getRuntime().addShutdownHook(new Thread(() -> {