Rename templates, change model.
This commit is contained in:
parent
dd8407fb2d
commit
7655b7ab1a
2 changed files with 81 additions and 56 deletions
|
|
@ -1,11 +1,11 @@
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
namespace: ${ metadata.namespace.asString }
|
namespace: ${ cr.metadata.namespace.asString }
|
||||||
name: ${ metadata.name.asString }
|
name: ${ cr.metadata.name.asString }
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: ${ constants.APP_NAME }
|
app.kubernetes.io/name: ${ constants.APP_NAME }
|
||||||
app.kubernetes.io/instance: ${ metadata.name.asString }
|
app.kubernetes.io/instance: ${ cr.metadata.name.asString }
|
||||||
app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME }
|
app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME }
|
||||||
|
|
||||||
data:
|
data:
|
||||||
|
|
@ -13,17 +13,17 @@ data:
|
||||||
"/Runner":
|
"/Runner":
|
||||||
# The directory used to store data files. Defaults to (depending on
|
# The directory used to store data files. Defaults to (depending on
|
||||||
# values available):
|
# values available):
|
||||||
# * $XDG_DATA_HOME/vmrunner/${ metadata.name.asString }
|
# * $XDG_DATA_HOME/vmrunner/${ cr.metadata.name.asString }
|
||||||
# * $HOME/.local/share/vmrunner/${ metadata.name.asString }
|
# * $HOME/.local/share/vmrunner/${ cr.metadata.name.asString }
|
||||||
# * ./${ metadata.name.asString }
|
# * ./${ cr.metadata.name.asString }
|
||||||
dataDir: /var/local/vm-data
|
dataDir: /var/local/vm-data
|
||||||
|
|
||||||
# The directory used to store runtime files. Defaults to (depending on
|
# The directory used to store runtime files. Defaults to (depending on
|
||||||
# values available):
|
# values available):
|
||||||
# * $XDG_RUNTIME_DIR/vmrunner/${ metadata.name.asString }
|
# * $XDG_RUNTIME_DIR/vmrunner/${ cr.metadata.name.asString }
|
||||||
# * /tmp/$USER/vmrunner/${ metadata.name.asString }
|
# * /tmp/$USER/vmrunner/${ cr.metadata.name.asString }
|
||||||
# * /tmp/vmrunner/${ metadata.name.asString }
|
# * /tmp/vmrunner/${ cr.metadata.name.asString }
|
||||||
# runtimeDir: "$XDG_RUNTIME_DIR/vmrunner/${ metadata.name.asString }"
|
# runtimeDir: "$XDG_RUNTIME_DIR/vmrunner/${ cr.metadata.name.asString }"
|
||||||
|
|
||||||
# The template to use. Resolved relative to /usr/share/vmrunner/templates.
|
# The template to use. Resolved relative to /usr/share/vmrunner/templates.
|
||||||
# template: "Standard-VM-latest.ftl.yaml"
|
# template: "Standard-VM-latest.ftl.yaml"
|
||||||
|
|
@ -35,67 +35,67 @@ data:
|
||||||
# Define the VM (required)
|
# Define the VM (required)
|
||||||
vm:
|
vm:
|
||||||
# The VM's name (required)
|
# The VM's name (required)
|
||||||
name: ${ metadata.name.asString }
|
name: ${ cr.metadata.name.asString }
|
||||||
|
|
||||||
# The machine's uuid. If none is specified, a uuid is generated
|
# The machine's uuid. If none is specified, a uuid is generated
|
||||||
# and stored in the data directory. If the uuid is important
|
# and stored in the data directory. If the uuid is important
|
||||||
# (e.g. because licenses depend on it) it is recommaned to specify
|
# (e.g. because licenses depend on it) it is recommaned to specify
|
||||||
# it here explicitly or to carefully backup the data directory.
|
# it here explicitly or to carefully backup the data directory.
|
||||||
# uuid: "generated uuid"
|
# uuid: "generated uuid"
|
||||||
<#if spec.vm.machineUuid??>
|
<#if cr.spec.vm.machineUuid??>
|
||||||
uuid: "${ spec.vm.machineUuid.asString }"
|
uuid: "${ cr.spec.vm.machineUuid.asString }"
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
# Whether to provide a software TPM (defaults to false)
|
# Whether to provide a software TPM (defaults to false)
|
||||||
# useTpm: false
|
# useTpm: false
|
||||||
useTpm: ${ spec.vm.useTpm.asBoolean?c }
|
useTpm: ${ cr.spec.vm.useTpm.asBoolean?c }
|
||||||
|
|
||||||
# How to boot (see https://github.com/mnlipp/VM-Operator/blob/main/org.jdrupes.vmoperator.runner.qemu/resources/org/jdrupes/vmoperator/runner/qemu/defaults.yaml):
|
# How to boot (see https://github.com/mnlipp/VM-Operator/blob/main/org.jdrupes.vmoperator.runner.qemu/resources/org/jdrupes/vmoperator/runner/qemu/defaults.yaml):
|
||||||
# * bios
|
# * bios
|
||||||
# * uefi[-4m]
|
# * uefi[-4m]
|
||||||
# * secure[-4m]
|
# * secure[-4m]
|
||||||
firmware: ${ spec.vm.firmware.asString }
|
firmware: ${ cr.spec.vm.firmware.asString }
|
||||||
|
|
||||||
# Whether to show a boot menu.
|
# Whether to show a boot menu.
|
||||||
# bootMenu: false
|
# bootMenu: false
|
||||||
bootMenu: ${ spec.vm.bootMenu.asBoolean?c }
|
bootMenu: ${ cr.spec.vm.bootMenu.asBoolean?c }
|
||||||
|
|
||||||
# When terminating, a graceful powerdown is attempted. If it
|
# When terminating, a graceful powerdown is attempted. If it
|
||||||
# doesn't succeed within the given timeout (seconds) SIGTERM
|
# doesn't succeed within the given timeout (seconds) SIGTERM
|
||||||
# is sent to Qemu.
|
# is sent to Qemu.
|
||||||
# powerdownTimeout: 900
|
# powerdownTimeout: 900
|
||||||
powerdownTimeout: ${ spec.vm.powerdownTimeout.asLong?c }
|
powerdownTimeout: ${ cr.spec.vm.powerdownTimeout.asLong?c }
|
||||||
|
|
||||||
# CPU settings
|
# CPU settings
|
||||||
cpuModel: ${ spec.vm.cpuModel.asString }
|
cpuModel: ${ cr.spec.vm.cpuModel.asString }
|
||||||
# Setting maximumCpus to 1 omits the "-smp" options. The defaults (0)
|
# Setting maximumCpus to 1 omits the "-smp" options. The defaults (0)
|
||||||
# cause the corresponding property to be omitted from the "-smp" option.
|
# cause the corresponding property to be omitted from the "-smp" option.
|
||||||
# If currentCpus is greater than maximumCpus, the latter is adjusted.
|
# If currentCpus is greater than maximumCpus, the latter is adjusted.
|
||||||
<#if spec.vm.maximumCpus?? >
|
<#if cr.spec.vm.maximumCpus?? >
|
||||||
maximumCpus: ${ spec.vm.maximumCpus.asInt?c }
|
maximumCpus: ${ cr.spec.vm.maximumCpus.asInt?c }
|
||||||
</#if>
|
</#if>
|
||||||
<#if spec.vm.cpuTopology?? >
|
<#if cr.spec.vm.cpuTopology?? >
|
||||||
cpuSockets: ${ spec.vm.cpuTopology.cpuSockets.asInt?c }
|
cpuSockets: ${ cr.spec.vm.cpuTopology.cpuSockets.asInt?c }
|
||||||
diesPerSocket: ${ spec.vm.cpuTopology.diesPerSocket.asInt?c }
|
diesPerSocket: ${ cr.spec.vm.cpuTopology.diesPerSocket.asInt?c }
|
||||||
coresPerSocket: ${ spec.vm.cpuTopology.coresPerSocket.asInt?c }
|
coresPerSocket: ${ cr.spec.vm.cpuTopology.coresPerSocket.asInt?c }
|
||||||
threadsPerCore: ${ spec.vm.cpuTopology.threadsPerCore.asInt?c }
|
threadsPerCore: ${ cr.spec.vm.cpuTopology.threadsPerCore.asInt?c }
|
||||||
</#if>
|
</#if>
|
||||||
<#if spec.vm.currentCpus?? >
|
<#if cr.spec.vm.currentCpus?? >
|
||||||
currentCpus: ${ spec.vm.currentCpus.asInt?c }
|
currentCpus: ${ cr.spec.vm.currentCpus.asInt?c }
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
# RAM settings
|
# RAM settings
|
||||||
# Maximum defaults to 1G
|
# Maximum defaults to 1G
|
||||||
maximumRam: "${ spec.vm.maximumRam.asString }"
|
maximumRam: "${ cr.spec.vm.maximumRam.asString }"
|
||||||
<#if spec.vm.currentRam?? >
|
<#if cr.spec.vm.currentRam?? >
|
||||||
currentRam: "${ spec.vm.currentRam.asString }"
|
currentRam: "${ cr.spec.vm.currentRam.asString }"
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
# RTC settings.
|
# RTC settings.
|
||||||
# rtcBase: utc
|
# rtcBase: utc
|
||||||
# rtcClock: rt
|
# rtcClock: rt
|
||||||
rtcBase: ${ spec.vm.rtcBase.asString }
|
rtcBase: ${ cr.spec.vm.rtcBase.asString }
|
||||||
rtcClock: ${ spec.vm.rtcClock.asString }
|
rtcClock: ${ cr.spec.vm.rtcClock.asString }
|
||||||
|
|
||||||
# Network settings
|
# Network settings
|
||||||
# Supported types are "tap" and "user" (for debugging). Type "user"
|
# Supported types are "tap" and "user" (for debugging). Type "user"
|
||||||
|
|
@ -107,7 +107,7 @@ data:
|
||||||
# mac: (undefined)
|
# mac: (undefined)
|
||||||
network:
|
network:
|
||||||
<#assign nwCounter = 0/>
|
<#assign nwCounter = 0/>
|
||||||
<#list spec.vm.networks.asList() as itf>
|
<#list cr.spec.vm.networks.asList() as itf>
|
||||||
<#if itf.tap??>
|
<#if itf.tap??>
|
||||||
- type: tap
|
- type: tap
|
||||||
device: ${ itf.tap.device.asString }
|
device: ${ itf.tap.device.asString }
|
||||||
|
|
@ -135,7 +135,7 @@ data:
|
||||||
# file: (undefined)
|
# file: (undefined)
|
||||||
drives:
|
drives:
|
||||||
<#assign drvCounter = 0/>
|
<#assign drvCounter = 0/>
|
||||||
<#list spec.vm.disks.asList() as disk>
|
<#list cr.spec.vm.disks.asList() as disk>
|
||||||
<#if disk.volumeClaimTemplate.metadata??
|
<#if disk.volumeClaimTemplate.metadata??
|
||||||
&& disk.volumeClaimTemplate.metadata.name??>
|
&& disk.volumeClaimTemplate.metadata.name??>
|
||||||
<#assign name = disk.volumeClaimTemplate.metadata.name.asString>
|
<#assign name = disk.volumeClaimTemplate.metadata.name.asString>
|
||||||
|
|
@ -147,16 +147,16 @@ data:
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
display:
|
display:
|
||||||
<#if spec.vm.display.spice??>
|
<#if cr.spec.vm.display.spice??>
|
||||||
spice:
|
spice:
|
||||||
port: ${ spec.vm.display.spice.port.asInt?c }
|
port: ${ cr.spec.vm.display.spice.port.asInt?c }
|
||||||
<#if spec.vm.display.spice.ticket??>
|
<#if cr.spec.vm.display.spice.ticket??>
|
||||||
ticket: "${ spec.vm.display.spice.ticket.asString }"
|
ticket: "${ cr.spec.vm.display.spice.ticket.asString }"
|
||||||
</#if>
|
</#if>
|
||||||
<#if spec.vm.display.spice.streamingVideo??>
|
<#if cr.spec.vm.display.spice.streamingVideo??>
|
||||||
ticket: "${ spec.vm.display.spice.streamingVideo.asString }"
|
ticket: "${ cr.spec.vm.display.spice.streamingVideo.asString }"
|
||||||
</#if>
|
</#if>
|
||||||
usbRedirects: ${ spec.vm.display.spice.usbRedirects.asInt?c }
|
usbRedirects: ${ cr.spec.vm.display.spice.usbRedirects.asInt?c }
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
logging.properties: |
|
logging.properties: |
|
||||||
|
|
@ -100,8 +100,19 @@ public class Reconciler extends Component {
|
||||||
var vmDef = vmDefApi.get(defMeta.getNamespace(), defMeta.getName())
|
var vmDef = vmDefApi.get(defMeta.getNamespace(), defMeta.getName())
|
||||||
.getObject();
|
.getObject();
|
||||||
|
|
||||||
|
// Prepare Freemarker model
|
||||||
|
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
||||||
|
Map<String, Object> model = new HashMap<>();
|
||||||
|
model.put("cr", vmDef.getRaw());
|
||||||
|
model.put("constants",
|
||||||
|
(TemplateHashModel) new DefaultObjectWrapperBuilder(
|
||||||
|
Configuration.VERSION_2_3_32)
|
||||||
|
.build().getStaticModels().get(Constants.class.getName()));
|
||||||
|
|
||||||
|
// Reconcile
|
||||||
reconcileDisks(vmDef, channel);
|
reconcileDisks(vmDef, channel);
|
||||||
reconcileConfigMap(vmDef, channel);
|
reconcileConfigMap(model, channel);
|
||||||
|
reconcilePod(model, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reconcileDisks(DynamicKubernetesObject vmDef,
|
private void reconcileDisks(DynamicKubernetesObject vmDef,
|
||||||
|
|
@ -168,21 +179,13 @@ public class Reconciler extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reconcileConfigMap(DynamicKubernetesObject vmDefinition,
|
private void reconcileConfigMap(Map<String, Object> model,
|
||||||
WatchChannel channel) throws TemplateNotFoundException,
|
WatchChannel channel)
|
||||||
MalformedTemplateNameException, ParseException, IOException,
|
throws TemplateNotFoundException, MalformedTemplateNameException,
|
||||||
TemplateException, ApiException {
|
ParseException, IOException, TemplateException, ApiException {
|
||||||
// Combine template and data and parse result
|
// Combine template and data and parse result
|
||||||
// (tempting, but no need to use a pipe here)
|
var fmTemplate = fmConfig.getTemplate("runnerConfig.ftl.yaml");
|
||||||
var fmTemplate = fmConfig.getTemplate("etcConfig.ftl.yaml");
|
|
||||||
StringWriter out = new StringWriter();
|
StringWriter out = new StringWriter();
|
||||||
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
|
||||||
Map<String, Object> model = new HashMap<>();
|
|
||||||
model.putAll(vmDefinition.getRaw().asMap());
|
|
||||||
model.put("constants",
|
|
||||||
(TemplateHashModel) new DefaultObjectWrapperBuilder(
|
|
||||||
Configuration.VERSION_2_3_32)
|
|
||||||
.build().getStaticModels().get(Constants.class.getName()));
|
|
||||||
fmTemplate.process(model, out);
|
fmTemplate.process(model, out);
|
||||||
|
|
||||||
// Apply
|
// Apply
|
||||||
|
|
@ -191,11 +194,33 @@ public class Reconciler extends Component {
|
||||||
opts.setFieldManager("kubernetes-java-kubectl-apply");
|
opts.setFieldManager("kubernetes-java-kubectl-apply");
|
||||||
DynamicKubernetesApi pvcApi = new DynamicKubernetesApi("", "v1",
|
DynamicKubernetesApi pvcApi = new DynamicKubernetesApi("", "v1",
|
||||||
"configmaps", channel.client());
|
"configmaps", channel.client());
|
||||||
var vmDef = GsonPtr.to(vmDefinition.getRaw());
|
var vmDef = GsonPtr.to((JsonObject) model.get("cr"));
|
||||||
pvcApi.patch(vmDef.getAsString("metadata", "namespace").get(),
|
pvcApi.patch(vmDef.getAsString("metadata", "namespace").get(),
|
||||||
vmDef.getAsString("metadata", "name").get(),
|
vmDef.getAsString("metadata", "name").get(),
|
||||||
V1Patch.PATCH_FORMAT_APPLY_YAML, new V1Patch(out.toString()),
|
V1Patch.PATCH_FORMAT_APPLY_YAML, new V1Patch(out.toString()),
|
||||||
opts).throwsApiException();
|
opts).throwsApiException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reconcilePod(Map<String, Object> model, WatchChannel channel)
|
||||||
|
throws TemplateNotFoundException, MalformedTemplateNameException,
|
||||||
|
ParseException, IOException, TemplateException, ApiException {
|
||||||
|
// Combine template and data and parse result
|
||||||
|
var fmTemplate = fmConfig.getTemplate("runnerPod.ftl.yaml");
|
||||||
|
StringWriter out = new StringWriter();
|
||||||
|
fmTemplate.process(model, out);
|
||||||
|
out = null;
|
||||||
|
|
||||||
|
// // Apply
|
||||||
|
// PatchOptions opts = new PatchOptions();
|
||||||
|
// opts.setForce(false);
|
||||||
|
// opts.setFieldManager("kubernetes-java-kubectl-apply");
|
||||||
|
// DynamicKubernetesApi pvcApi = new DynamicKubernetesApi("", "v1",
|
||||||
|
// "pod", channel.client());
|
||||||
|
// var vmDef = GsonPtr.to((JsonObject) model.get("cr"));
|
||||||
|
// pvcApi.patch(vmDef.getAsString("metadata", "namespace").get(),
|
||||||
|
// vmDef.getAsString("metadata", "name").get(),
|
||||||
|
// V1Patch.PATCH_FORMAT_APPLY_YAML, new V1Patch(out.toString()),
|
||||||
|
// opts).throwsApiException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue