@Override int getDesiredReplicas(StatefulSet item) { return item.getSpec().getReplicas(); }
@Override public StatefulSet updateImage(String image) { StatefulSet oldRC = get(); if (oldRC == null) { throw new KubernetesClientException("Existing StatefulSet doesn't exist"); } if (oldRC.getSpec().getTemplate().getSpec().getContainers().size() > 1) { throw new KubernetesClientException("Image update is not supported for multicontainer pods"); } if (oldRC.getSpec().getTemplate().getSpec().getContainers().size() == 0) { throw new KubernetesClientException("Pod has no containers!"); } Container updatedContainer = new ContainerBuilder(oldRC.getSpec().getTemplate().getSpec().getContainers().iterator().next()).withImage(image).build(); StatefulSetBuilder newRCBuilder = new StatefulSetBuilder(oldRC); newRCBuilder.editMetadata().withResourceVersion(null).endMetadata() .editSpec().editTemplate().editSpec().withContainers(Collections.singletonList(updatedContainer)) .endSpec().endTemplate().endSpec(); return new StatefulSetRollingUpdater(client, config, namespace).rollUpdate(oldRC, newRCBuilder.build()); }
@Override protected PodList listSelectedPods(StatefulSet obj) { FilterWatchListDeletable<Pod, PodList, Boolean, Watch, Watcher<Pod>> podLister = pods().inNamespace(namespace); if (obj.getSpec().getSelector().getMatchLabels() != null) { podLister.withLabels(obj.getSpec().getSelector().getMatchLabels()); } if (obj.getSpec().getSelector().getMatchExpressions() != null) { for (LabelSelectorRequirement req : obj.getSpec().getSelector().getMatchExpressions()) { switch (req.getOperator()) { case "In": podLister.withLabelIn(req.getKey(), req.getValues().toArray(new String[]{})); break; case "NotIn": podLister.withLabelNotIn(req.getKey(), req.getValues().toArray(new String[]{})); break; case "DoesNotExist": podLister.withoutLabel(req.getKey()); break; case "Exists": podLister.withLabel(req.getKey()); break; } } } return podLister.list(); }
/** * Overridden to not cascade to dependent resources (e.g. pods). * * {@inheritDoc} */ @Override protected Future<ReconcileResult<StatefulSet>> internalPatch(String namespace, String name, StatefulSet current, StatefulSet desired) { if (shouldIncrementGeneration(current, desired)) { incrementGeneration(current, desired); } else { setGeneration(desired, getSsGeneration(current)); } // Don't scale via patch desired.getSpec().setReplicas(current.getSpec().getReplicas()); if (log.isTraceEnabled()) { log.trace("Patching {} {}/{} to match desired state {}", resourceKind, namespace, name, desired); } else { log.debug("Patching {} {}/{}", resourceKind, namespace, name); } return super.internalPatch(namespace, name, current, desired, false); }
desired.getSpec().setVolumeClaimTemplates(current.getSpec().getVolumeClaimTemplates()); desired.getSpec().getTemplate().getSpec().setInitContainers(current.getSpec().getTemplate().getSpec().getInitContainers()); desired.getSpec().getTemplate().getSpec().setSecurityContext(current.getSpec().getTemplate().getSpec().getSecurityContext()); if (current.getSpec().getVolumeClaimTemplates().isEmpty()) { List<Volume> volumes = current.getSpec().getTemplate().getSpec().getVolumes(); for (int i = 0; i < volumes.size(); i++) { Volume vol = volumes.get(i); if (vol.getName().startsWith(AbstractModel.VOLUME_NAME) && vol.getEmptyDir() != null) { desired.getSpec().getTemplate().getSpec().getVolumes().add(0, volumes.get(i)); break; List<Volume> volumes = desired.getSpec().getTemplate().getSpec().getVolumes(); for (int i = 0; i < volumes.size(); i++) { Volume vol = volumes.get(i);
private List<HasMetadata> createStandardInfra(AddressSpace addressSpace, StandardInfraConfig standardInfraConfig) { Map<String, String> parameters = new HashMap<>(); prepareParameters(standardInfraConfig, addressSpace, parameters); parameters.put(TemplateParameter.BROKER_MEMORY_LIMIT, standardInfraConfig.getSpec().getBroker().getResources().getMemory()); parameters.put(TemplateParameter.BROKER_ADDRESS_FULL_POLICY, standardInfraConfig.getSpec().getBroker().getAddressFullPolicy()); parameters.put(TemplateParameter.ADMIN_MEMORY_LIMIT, standardInfraConfig.getSpec().getAdmin().getResources().getMemory()); parameters.put(TemplateParameter.ROUTER_MEMORY_LIMIT, standardInfraConfig.getSpec().getRouter().getResources().getMemory()); parameters.put(TemplateParameter.ROUTER_LINK_CAPACITY, String.valueOf(standardInfraConfig.getSpec().getRouter().getLinkCapacity())); parameters.put(TemplateParameter.STANDARD_INFRA_CONFIG_NAME, standardInfraConfig.getMetadata().getName()); Map<String, String> infraAnnotations = standardInfraConfig.getMetadata().getAnnotations(); String templateName = getAnnotation(infraAnnotations, AnnotationKeys.TEMPLATE_NAME, "standard-space-infra"); List<HasMetadata> items = new ArrayList<>(kubernetes.processTemplate(templateName, parameters).getItems()); // Workaround since parameterized integer fields cannot be loaded locally by fabric8 kubernetes-client for (HasMetadata item : items) { if (item instanceof StatefulSet && "qdrouterd".equals(item.getMetadata().getLabels().get(LabelKeys.NAME))) { StatefulSet router = (StatefulSet) item; router.getSpec().setReplicas(standardInfraConfig.getSpec().getRouter().getMinReplicas()); } } if (Boolean.parseBoolean(getAnnotation(infraAnnotations, AnnotationKeys.WITH_MQTT, "false"))) { String mqttTemplateName = getAnnotation(infraAnnotations, AnnotationKeys.MQTT_TEMPLATE_NAME, "standard-space-infra-mqtt"); items.addAll(createStandardInfraMqtt(addressSpace, mqttTemplateName)); } return applyStorageClassName(standardInfraConfig.getSpec().getBroker().getStorageClassName(), items); }
@Override protected StatefulSetDiff revertStorageChanges(StatefulSet current, StatefulSet desired) { List<PersistentVolumeClaim> currentPvcs = current.getSpec().getVolumeClaimTemplates(); List<PersistentVolumeClaim> desiredPvcs = desired.getSpec().getVolumeClaimTemplates();
if (item instanceof StatefulSet) { StatefulSet set = (StatefulSet) item; set.getSpec().setReplicas(numReplicas); Kubernetes.addObjectAnnotation(item, AnnotationKeys.APPLIED_INFRA_CONFIG, mapper.writeValueAsString(standardInfraConfig)); } else if (item instanceof Deployment) {
@Override protected int getReplicas(StatefulSet obj) { return obj.getSpec().getReplicas(); }
private void setGeneration(StatefulSet desired, int nextGeneration) { Map<String, String> annotations = Annotations.annotations(desired.getSpec().getTemplate()); annotations.remove(ANNO_OP_STRIMZI_IO_GENERATION); annotations.put(ANNO_STRIMZI_IO_GENERATION, String.valueOf(nextGeneration)); }
StatefulSetSpec spec = resource.getSpec(); if (spec != null) { selector = spec.getSelector();
public static boolean isStatefulSetReady(StatefulSet ss) { Utils.checkNotNull(ss, "StatefulSet can't be null."); StatefulSetSpec spec = ss.getSpec(); StatefulSetStatus status =ss.getStatus(); if (status == null || status.getReplicas() == null) { return false; } //Can be true in testing, so handle it to make test writing easier. if (spec == null || spec.getReplicas() == null) { return false; } return spec.getReplicas().intValue() == status.getReplicas(); }
public static int getSsGeneration(StatefulSet resource) { if (resource == null) { return NO_GENERATION; } return Annotations.intAnnotation(resource.getSpec().getTemplate(), ANNO_STRIMZI_IO_GENERATION, NO_GENERATION, ANNO_OP_STRIMZI_IO_GENERATION); }
@Override protected Integer currentScale(String namespace, String name) { StatefulSet statefulSet = get(namespace, name); if (statefulSet != null) { return statefulSet.getSpec().getReplicas(); } else { return null; } }
private static ObjectMeta templateMetadata(StatefulSet resource) { return resource.getSpec().getTemplate().getMetadata(); }
/** * Returns a future that completes when all the pods [0..replicas-1] in the given statefulSet are ready. */ protected Future<?> podReadiness(String namespace, StatefulSet desired, long pollInterval, long operationTimeoutMs) { final int replicas = desired.getSpec().getReplicas(); List<Future> waitPodResult = new ArrayList<>(replicas); for (int i = 0; i < replicas; i++) { String podName = getPodName(desired, i); waitPodResult.add(podOperations.readiness(namespace, podName, pollInterval, operationTimeoutMs)); } return CompositeFuture.join(waitPodResult); }
protected void incrementGeneration(StatefulSet current, StatefulSet desired) { final int generation = Annotations.intAnnotation(current.getSpec().getTemplate(), ANNO_STRIMZI_IO_GENERATION, INIT_GENERATION, ANNO_OP_STRIMZI_IO_GENERATION); final int nextGeneration = generation + 1; setGeneration(desired, nextGeneration); }
private int findReplicas(List<HasMetadata> items) { for (HasMetadata item : items) { if (item instanceof StatefulSet) { return ((StatefulSet)item).getSpec().getReplicas(); } else if (item instanceof Deployment) { return ((Deployment)item).getSpec().getReplicas(); } } return 0; }
Future<ReconciliationState> zkStatefulSet() { StatefulSet zkSs = zkCluster.generateStatefulSet(isOpenShift); Annotations.annotations(zkSs.getSpec().getTemplate()).put(Ca.ANNO_STRIMZI_IO_CLUSTER_CA_CERT_GENERATION, String.valueOf(getCaCertGeneration(this.clusterCa))); return withZkDiff(zkSetOperations.reconcile(namespace, zkCluster.getName(), zkSs)); }
/** * Asynchronously perform a rolling update of all the pods in the StatefulSet identified by the given * {@code namespace} and {@code name}, returning a Future that will complete when the rolling update * is complete. Starting with pod 0, each pod will be deleted and re-created automatically by the ReplicaSet, * once the pod has been recreated then given {@code isReady} function will be polled until it returns true, * before the process proceeds with the pod with the next higher number. */ public Future<Void> maybeRollingUpdate(StatefulSet ss, Predicate<Pod> podRestart) { String namespace = ss.getMetadata().getNamespace(); String name = ss.getMetadata().getName(); final int replicas = ss.getSpec().getReplicas(); log.debug("Considering rolling update of {}/{}", namespace, name); Future<Void> f = Future.succeededFuture(); for (int i = 0; i < replicas; i++) { String podName = name + "-" + i; f = f.compose(ignored -> maybeRestartPod(ss, podName, podRestart)); } return f; }