diff --git a/org.jdrupes.vmoperator.manager/config-sample.yaml b/org.jdrupes.vmoperator.manager/config-sample.yaml deleted file mode 100644 index 56cfefc..0000000 --- a/org.jdrupes.vmoperator.manager/config-sample.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# The values in comments are the defaults. - -"/Manager": - "/Controller": - # Explicitly specify the namespace to be managed (only for development). - # namespace: vmop-dev - - "/Reconciler": - # Amount by which the current cpu count is devided when generating - # the resource properties. - cpuOvercommit: 2 - - # Amount by which the current ram size is devided when generating - # the resource properties. - ramOvercommit: 1.5 - - # Values used when creating the PVC for the runner's data - runnerDataPvc: - storageClassName: null - - # If defined, causes a load balancer service to be created. - # May be a boolean or a string with nested yaml that - # defines additional labels or annotations to be merged - # into the service. - # loadBalancerService: | - # labels: {} - # annotations: {} - 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 fe668cb..998dc1d 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 @@ -29,6 +29,38 @@ import org.jgrapes.core.events.Start; /** * Implements a controller as defined in the * [Operator Whitepaper](https://github.com/cncf/tag-app-delivery/blob/eece8f7307f2970f46f100f51932db106db46968/operator-wg/whitepaper/Operator-WhitePaper_v1-0.md#operator-components-in-kubernetes). + * + * The implementation splits the controller in two components. The + * {@link VmWatcher} and the {@link Reconciler}. The former watches + * the VM definitions (CRs) and generates {@link VmDefChanged} events + * when they change. The latter handles the changes and reconciles the + * resources in the cluster. + * + * The controller itself supports a single configuration property: + * ```yaml + * "/Manager": + * "/Controller": + * namespace: vmop-dev + * ``` + * This may only be set when running the Manager (and thus the Controller) + * outside a container during development. + * + * ![Controller components](controller-components.svg) + * + * @startuml controller-components.svg + * skinparam component { + * BackGroundColor #FEFECE + * BorderColor #A80036 + * BorderThickness 1.25 + * BackgroundColor<> #F1F1F1 + * BorderColor<> #181818 + * BorderThickness<> 1 + * } + * + * [Controller] + * [Controller] *--> [VmWatcher] + * [Controller] *--> [Reconciler] + * @enduml */ public class Controller extends Component { diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java index 1dcd5c8..fed9740 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java @@ -42,7 +42,30 @@ import org.jgrapes.util.YamlConfigurationStore; import org.jgrapes.util.events.WatchFile; /** - * The application class. + * The application class. In framework term, this is the root component. + * Two of its child components, the {@link Controller} and the WebGui + * implement user-visible functions. The others are used internally. + * + * ![Manager components](manager-components.svg) + * + * @startuml manager-components.svg + * skinparam component { + * BackGroundColor #FEFECE + * BorderColor #A80036 + * BorderThickness 1.25 + * BackgroundColor<> #F1F1F1 + * BorderColor<> #181818 + * BorderThickness<> 1 + * } + * + * [Manager] + * [Manager] *--> [Controller] + * [Manager] *--> [WebGui] + * [NioDispatcher] <> + * [Manager] *--> [NioDispatcher] <> + * [FileSystemWatcher] <> + * [Manager] *--> [FileSystemWatcher] <> + * @enduml */ public class Manager extends Component { diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java index eb91e2f..0608f10 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java @@ -49,7 +49,72 @@ import org.jgrapes.core.annotation.Handler; import org.jgrapes.util.events.ConfigurationUpdate; /** - * Adapts Kubenetes resources to changes in VM definitions (CRs). + * Adapts Kubenetes resources for instances of the Runner + * application (the VMs) to changes in VM definitions (the CRs). + * + * In particular, the reconciler generates and updates: + * + * * A [`PVC`](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) + * for storage used by all VMs as a common repository for CDROM images. + * + * * A [`ConfigMap`](https://kubernetes.io/docs/concepts/configuration/configmap/) + * that defines the configuration file for the runner. + * + * * A [`StatefulSet`](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) + * that creates + * * the [`Pod`](https://kubernetes.io/docs/concepts/workloads/pods/) + * with the Runner instance, + * * a PVC for 1 MiB of persistent storage used by the Runner + * (referred to as the "runnerDataPvc") and + * * the PVCs for the VM's disks. + * + * * (Optional) A load balancer + * [`Service`](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/) + * that allows the user to access a VM's console without knowing which + * node it runs on. + * + * The reconciler is part of the {@link Controller} component. It's + * configuration properties are therefore defined in + * ```yaml + * "/Manager": + * "/Controller": + * "/Reconciler": + * ... + * ``` + * + * The reconciler supports the following configuration properties: + * + * * `runnerDataPvc.storageClassName`: The storage class name + * to be used for the "runnerDataPvc" (the small volume used + * by the runner for information such as the EFI variables). By + * default, no `storageClassName` is generated, which causes + * Kubernetes to use storage from the default storage class. + * Define this if you want to use a specific storage class. + * + * * `cpuOvercommit`: The amount by which the current cpu count + * from the VM definition is divided when generating the + * [`resources`](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) + * properties for the VM (defaults to 2). + * + * * `ramOvercommit`: The amount by which the current ram size + * from the VM definition is divided when generating the + * [`resources`](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) + * properties for the VM (defaults to 1.25). + * + * * `loadBalancerService`: If defined, causes a load balancer service + * to be created. This property may be a boolean or a string with nested + * YAML that defines additional labels or annotations to be merged + * into the service defintion. Here's an example for using + * [MetalLb](https://metallb.universe.tf/) as "internal load balancer": + * ```yaml + * loadBalancerService: | + * annotations: + * metallb.universe.tf/loadBalancerIPs: 192.168.168.1 + * metallb.universe.tf/ip-allocated-from-pool: single-common + * metallb.universe.tf/allow-shared-ip: single-common + * ``` + * This make all VM consoles available at IP address 192.168.168.1 + * with the port numbers from the VM definitions. */ @SuppressWarnings({ "PMD.DataflowAnomalyAnalysis", "PMD.AvoidDuplicateLiterals" }) @@ -87,7 +152,7 @@ public class Reconciler extends Component { } /** - * Configure the component. + * Configures the component. * * @param event the event */