private void addNodesFromXml(ApplicationContainerCluster cluster, Element containerElement, ConfigModelContext context) {
        Element nodesElement = XML.getChild(containerElement, "nodes");
        if (nodesElement == null) {
            cluster.addContainers(allocateWithoutNodesTag(cluster, context));
            cluster.setJvmGCOptions(buildJvmGCOptions(context, null));
        } else {
            List<ApplicationContainer> nodes = createNodes(cluster, containerElement, nodesElement, context);

            extractJvmOptions(nodes, cluster, nodesElement, context);
            applyDefaultPreload(nodes, nodesElement);
            var envVars = getEnvironmentVariables(XML.getChild(nodesElement, ENVIRONMENT_VARIABLES_ELEMENT)).entrySet();
            for (var container : nodes) {
                for (var entry : envVars) {
                    container.addEnvironmentVariable(entry.getKey(), entry.getValue());
                }
            }
            if (useCpuSocketAffinity(nodesElement))
                AbstractService.distributeCpuSocketAffinity(nodes);
            cluster.addContainers(nodes);
        }
    }
Add nodes to cluster according to the given containerElement.

Note: DO NOT change allocation behaviour to allow version X and Y of the config-model to allocate a different set
of nodes. Such changes must be guarded by a common condition (e.g. feature flag) so the behaviour can be changed
simultaneously for all active config models.
config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java