From 638c44ac8bea1c703f6a52f404274e35e8deb718 Mon Sep 17 00:00:00 2001 From: Duncan Grant Date: Wed, 29 Apr 2020 10:56:20 +0100 Subject: [PATCH 1/5] Brings back the helm code Revert "Revert "This closes #830"" This reverts commit 4236ff272903a8ffe77a06d9b146aea40b3f057e. --- locations/container/README.md | 30 ++ locations/container/pom.xml | 48 +++ .../kubernetes/KubernetesHelmChart.java | 37 ++ .../kubernetes/KubernetesHelmChartImpl.java | 35 ++ .../kubernetes/KubernetesLocation.java | 316 ++++++++++++------ .../location/openshift/OpenShiftLocation.java | 2 +- .../container/supplier/TillerSupplier.java | 43 +++ .../KubernetesLocationLiveTest.java | 2 + .../KubernetesLocationYamlLiveTest.java | 24 ++ 9 files changed, 443 insertions(+), 94 deletions(-) create mode 100644 locations/container/README.md create mode 100644 locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java create mode 100644 locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java create mode 100644 locations/container/src/main/java/org/apache/brooklyn/container/supplier/TillerSupplier.java diff --git a/locations/container/README.md b/locations/container/README.md new file mode 100644 index 0000000000..5c62b017ae --- /dev/null +++ b/locations/container/README.md @@ -0,0 +1,30 @@ + +# Kubernetes Location + +Brooklyn Container Location has an extensive support for Kubernetes deployments +In particular, it supports + +- KubernetesResource +- KubernetesHelmChart +- KubernetesContainer + +## Kubernets Helm Chart + +Here's an example of an Helm based blueprint + +```YAML +location: + kubernetes: + endpoint: https://localhost:6443 + kubeconfig: /home/user/.kube/config +services: +- type: org.apache.brooklyn.container.entity.kubernetes.KubernetesHelmChart + name: jenkins-helm + chartName: jenkins +``` + +Notice, in this case, it is pointing at a local k8s cluster (created using Docker on Mac) and specify a `kubeconfig` +file for connection details. + +The `KubernetesHelmChart` entity will install the latest version of the `chart` named `jenkins` from the Chart repository `stable` at `https://kubernetes-charts.storage.googleapis.com/` +You can install a specific version of the chart by using `chartVersion` config key. \ No newline at end of file diff --git a/locations/container/pom.xml b/locations/container/pom.xml index 2a4021b7c5..7958f358aa 100644 --- a/locations/container/pom.xml +++ b/locations/container/pom.xml @@ -32,6 +32,17 @@ + + org.microbean + microbean-helm + 2.8.2.1.1.1 + + + com.google.errorprone + error_prone_annotations + + + io.fabric8 openshift-client @@ -150,4 +161,41 @@ test + + + + + + + kr.motd.maven + os-maven-plugin + 1.5.0.Final + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + initialize + + true + + + + + + + + run + + + + + + diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java new file mode 100644 index 0000000000..e44a4bc5d8 --- /dev/null +++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.brooklyn.container.entity.kubernetes; + +import org.apache.brooklyn.api.entity.ImplementedBy; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.entity.software.base.SoftwareProcess; +import org.apache.brooklyn.util.core.ResourcePredicates; + +@ImplementedBy(KubernetesHelmChartImpl.class) +public interface KubernetesHelmChart extends SoftwareProcess { + + ConfigKey CHART_NAME = ConfigKeys.builder(String.class) + .name("chartName") + .description("Helm Chart name") + .build(); + + ConfigKey CHART_VERSION = ConfigKeys.builder(String.class) + .name("chartVersion") + .description("Helm Chart version") + .build(); +} diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java new file mode 100644 index 0000000000..9d3484e525 --- /dev/null +++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.brooklyn.container.entity.kubernetes; + +import org.apache.brooklyn.core.entity.BrooklynConfigKeys; +import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl; + +public class KubernetesHelmChartImpl extends EmptySoftwareProcessImpl implements KubernetesHelmChart { + + @Override + public void init() { + super.init(); + + config().set(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true); + config().set(PROVISIONING_PROPERTIES.subKey("useJcloudsSshInit"), false); + config().set(PROVISIONING_PROPERTIES.subKey("waitForSshable"), false); + config().set(PROVISIONING_PROPERTIES.subKey("pollForFirstReachableAddress"), false); + config().set(EmptySoftwareProcessImpl.USE_SSH_MONITORING, false); + } + +} diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java b/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java index d6023a0235..5301a0d9a9 100644 --- a/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java +++ b/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java @@ -18,16 +18,35 @@ */ package org.apache.brooklyn.container.location.kubernetes; -import java.io.InputStream; -import java.net.InetAddress; -import java.nio.charset.Charset; -import java.util.*; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nullable; - +import com.google.common.base.Optional; +import com.google.common.base.*; +import com.google.common.collect.*; +import com.google.common.io.BaseEncoding; +import com.google.common.net.HostAndPort; +//import hapi.chart.ChartOuterClass.Chart; +//import hapi.release.ReleaseOuterClass.Release; +//import hapi.services.tiller.Tiller.InstallReleaseRequest; +//import hapi.services.tiller.Tiller.InstallReleaseResponse; +//import hapi.services.tiller.Tiller.UninstallReleaseRequest; +//import hapi.services.tiller.Tiller.UninstallReleaseResponse; +import hapi.chart.ChartOuterClass.Chart; +import hapi.release.ReleaseOuterClass.Release; +import hapi.services.tiller.Tiller.InstallReleaseRequest; +import hapi.services.tiller.Tiller.InstallReleaseResponse; +import hapi.services.tiller.Tiller.UninstallReleaseRequest; +import hapi.services.tiller.Tiller.UninstallReleaseResponse; +import io.fabric8.kubernetes.client.AutoAdaptableKubernetesClient; +import org.microbean.helm.ReleaseManager; +import org.microbean.helm.Tiller; +import org.microbean.helm.TillerInstaller; +import org.microbean.helm.chart.repository.ChartRepository; import io.fabric8.kubernetes.api.model.*; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; +import io.fabric8.kubernetes.api.model.apps.DeploymentStatus; +import io.fabric8.kubernetes.client.DefaultKubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientException; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.location.MachineLocation; @@ -37,12 +56,14 @@ import org.apache.brooklyn.api.sensor.EnricherSpec; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.container.entity.docker.DockerContainer; +import org.apache.brooklyn.container.entity.kubernetes.KubernetesHelmChart; import org.apache.brooklyn.container.entity.kubernetes.KubernetesPod; import org.apache.brooklyn.container.entity.kubernetes.KubernetesResource; import org.apache.brooklyn.container.location.docker.DockerJcloudsLocation; import org.apache.brooklyn.container.location.kubernetes.machine.KubernetesEmptyMachineLocation; import org.apache.brooklyn.container.location.kubernetes.machine.KubernetesMachineLocation; import org.apache.brooklyn.container.location.kubernetes.machine.KubernetesSshMachineLocation; +import org.apache.brooklyn.container.supplier.TillerSupplier; import org.apache.brooklyn.core.entity.BrooklynConfigKeys; import org.apache.brooklyn.core.entity.EntityInternal; import org.apache.brooklyn.core.location.AbstractLocation; @@ -72,28 +93,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Functions; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.base.Stopwatch; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.io.BaseEncoding; -import com.google.common.net.HostAndPort; - -import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; -import io.fabric8.kubernetes.api.model.apps.DeploymentStatus; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; +import javax.annotation.Nullable; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; public class KubernetesLocation extends AbstractLocation implements MachineProvisioningLocation, KubernetesLocationConfig { @@ -131,6 +143,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi */ public static final String BROOKLYN_ROOT_PASSWORD = "BROOKLYN_ROOT_PASSWORD"; private static final Logger LOG = LoggerFactory.getLogger(KubernetesLocation.class); + private Tiller tiller; public static final String ADDRESS_KEY = "address"; private ConfigBag currentConfig; @@ -171,6 +184,8 @@ public KubernetesMachineLocation obtain(Map flags) { Entity entity = validateCallerContext(setup); if (isKubernetesResource(entity)) { return createKubernetesResourceLocation(entity, setup); + } else if (isKubernetesHelmChart(entity)) { + return createKubernetesHelmChartLocation(entity, setup); } else { return createKubernetesContainerLocation(entity, setup); } @@ -181,6 +196,8 @@ public void release(KubernetesMachineLocation machine) { Entity entity = validateCallerContext(machine); if (isKubernetesResource(entity)) { deleteKubernetesResourceLocation(entity); + } else if (isKubernetesHelmChart(entity)) { + deleteKubernetesHelmChartLocation(entity); } else { deleteKubernetesContainerLocation(entity, machine); } @@ -266,6 +283,26 @@ public String getFailureMessage() { waitForExitCondition(exitCondition); } } + protected void deleteKubernetesHelmChartLocation(Entity entity) { + final String releaseName = entity.sensors().get(KubernetesResource.RESOURCE_NAME); + ReleaseManager chartManager = new ReleaseManager(tiller); + try { + Future uninstallReleaseResponseFuture = chartManager.uninstall(UninstallReleaseRequest.newBuilder() + .setTimeout(300L) + .setName(releaseName) + .setPurge(true) + .build()); + UninstallReleaseResponse response = uninstallReleaseResponseFuture.get(); + LOG.debug("Release {} uninstalled", response); + } catch (IOException e) { + throw Throwables.propagate(e); + } catch (InterruptedException e) { + throw Throwables.propagate(e); + } catch (ExecutionException e) { + throw Throwables.propagate(e); + } + } + protected synchronized void deleteEmptyNamespace(final String name) { if (!name.equals("default") && isNamespaceEmpty(name)) { @@ -314,15 +351,18 @@ protected KubernetesMachineLocation createKubernetesResourceLocation(Entity enti try (KubernetesClient client = getClient()) { final List result = client.load(processedResource).createOrReplace(); - ExitCondition exitCondition = new ExitCondition() { - @Override - public Boolean call() { - if (result.isEmpty()) { - return false; - } - HasMetadata check = client.resource(result.get(0)).inNamespace(result.get(0).getMetadata().getNamespace()).get(); - return check != null; + ExitCondition exitCondition = new ExitCondition() { + @Override + public Boolean call() { + if (result.isEmpty()) { + return false; + } + HasMetadata check = client.resource(result.get(0)).inNamespace(result.get(0).getMetadata().getNamespace()).get(); + if (result.size() > 1 || check != null || check.getMetadata() == null) { + return false; } + return true; + } @Override public String getFailureMessage() { @@ -374,7 +414,10 @@ protected boolean findResourceAddress(LocationSpec inboundPorts = findInboundPorts(entity, setup); Map env = findEnvironmentVariables(entity, setup, imageName); Map metadata = findMetadata(entity, setup, deploymentName); + KubernetesSshMachineLocation machine; + try(KubernetesClient client = getClient()) { + if (volumes != null) { + createPersistentVolumes(volumes, client); + } + + Namespace namespace = createOrGetNamespace(lookup(NAMESPACE, entity, setup), setup.get(CREATE_NAMESPACE)); + + if (secrets != null) { + createSecrets(namespace.getMetadata().getName(), secrets); + } + + Container container = buildContainer(namespace.getMetadata().getName(), metadata, deploymentName, imageName, inboundPorts, env, limits, privileged); + deploy(namespace.getMetadata().getName(), entity, metadata, deploymentName, container, replicas, secrets); + Service service = exposeService(namespace.getMetadata().getName(), metadata, deploymentName, inboundPorts); + Pod pod = getPod(namespace.getMetadata().getName(), metadata, client); + + entity.sensors().set(KubernetesPod.KUBERNETES_NAMESPACE, namespace.getMetadata().getName()); + entity.sensors().set(KubernetesPod.KUBERNETES_DEPLOYMENT, deploymentName); + entity.sensors().set(KubernetesPod.KUBERNETES_POD, pod.getMetadata().getName()); + entity.sensors().set(KubernetesPod.KUBERNETES_SERVICE, service.getMetadata().getName()); + + LocationSpec locationSpec = prepareSshableLocationSpec(entity, setup, service, pod) + .configure(KubernetesMachineLocation.KUBERNETES_NAMESPACE, namespace.getMetadata().getName()) + .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, deploymentName) + .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE, getContainerResourceType()); - if (volumes != null) { - createPersistentVolumes(volumes); + machine = getManagementContext().getLocationManager().createLocation(locationSpec); + registerPortMappings(machine, entity, service); + if (!isDockerContainer(entity)) { + waitForSshable(machine, Duration.FIVE_MINUTES); + } } + return machine; + } - Namespace namespace = createOrGetNamespace(lookup(NAMESPACE, entity, setup), setup.get(CREATE_NAMESPACE)); + protected String getContainerResourceType() { + return KubernetesResource.DEPLOYMENT; + } - if (secrets != null) { - createSecrets(namespace.getMetadata().getName(), secrets); + protected KubernetesMachineLocation createKubernetesHelmChartLocation(Entity entity, ConfigBag setup) { + try (KubernetesClient client = getClient()){ + Map podLabels = ImmutableMap.of("name", "tiller", "app", "helm"); + if (!isTillerInstalled("kube-system", podLabels, client)) { + installTillerPodAndService("kube-system", "tiller-deploy", podLabels, client); } + // Create ${HOME}/.helm/{cache/archive,repository/cache} + try { + Files.createDirectories(Paths.get(System.getProperty("user.home"),".helm", "cache", "archive")); + Files.createDirectories(Paths.get(System.getProperty("user.home"),".helm", "repository", "cache")); + } catch (IOException e) { + throw Throwables.propagate(e); + } + + tiller = Suppliers.memoize(new TillerSupplier((DefaultKubernetesClient) client)).get(); + String chartName = entity.config().get(KubernetesHelmChart.CHART_NAME); + String chartVersion = entity.config().get(KubernetesHelmChart.CHART_VERSION); - Container container = buildContainer(namespace.getMetadata().getName(), metadata, deploymentName, imageName, inboundPorts, env, limits, privileged); - deploy(namespace.getMetadata().getName(), entity, metadata, deploymentName, container, replicas, secrets); - Service service = exposeService(namespace.getMetadata().getName(), metadata, deploymentName, inboundPorts); - Pod pod = getPod(namespace.getMetadata().getName(), metadata); + ReleaseManager chartManager = new ReleaseManager(tiller); + InstallReleaseRequest.Builder requestBuilder = InstallReleaseRequest.newBuilder(); + requestBuilder.setTimeout(300L); + requestBuilder.setWait(true); - entity.sensors().set(KubernetesPod.KUBERNETES_NAMESPACE, namespace.getMetadata().getName()); - entity.sensors().set(KubernetesPod.KUBERNETES_DEPLOYMENT, deploymentName); - entity.sensors().set(KubernetesPod.KUBERNETES_POD, pod.getMetadata().getName()); - entity.sensors().set(KubernetesPod.KUBERNETES_SERVICE, service.getMetadata().getName()); + ChartRepository chartRepository = new ChartRepository("stable", new URI("https://kubernetes-charts.storage.googleapis.com/")); + if (chartVersion == null) { + ChartRepository.Index.Entry latest = chartRepository.getIndex().getEntries().get(chartName).first(); + chartVersion = latest.getVersion(); + } - LocationSpec locationSpec = prepareSshableLocationSpec(entity, setup, service, pod) - .configure(KubernetesMachineLocation.KUBERNETES_NAMESPACE, namespace.getMetadata().getName()) - .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, deploymentName) - .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE, getContainerResourceType()); + Chart.Builder chartBuilder = chartRepository.resolve(chartName, chartVersion); - KubernetesSshMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec); - registerPortMappings(machine, entity, service); - if (!isDockerContainer(entity)) { - waitForSshable(machine, Duration.FIVE_MINUTES); + Future releaseFuture = chartManager.install(requestBuilder, chartBuilder); + Release release = releaseFuture.get().getRelease(); + + String resourceName = release.getName(); + String namespace = release.getNamespace(); + LOG.debug("Resource {} (from chart {}) deployed to {}", new Object[]{resourceName, chartName, namespace}); + + Node node = Iterables.getFirst(client.nodes().list().getItems(), null); // null should never happen here + String nodeAddress = node.getStatus().getAddresses().get(0).getAddress(); + InetAddress inetAddress = Networking.getInetAddressWithFixedName(nodeAddress); + + entity.sensors().set(KubernetesPod.KUBERNETES_NAMESPACE, namespace); + entity.sensors().set(KubernetesResource.RESOURCE_NAME, resourceName); + + LocationSpec locationSpec = LocationSpec.create(KubernetesEmptyMachineLocation.class); + locationSpec.configure(CALLER_CONTEXT, setup.get(CALLER_CONTEXT)) + .configure(KubernetesMachineLocation.KUBERNETES_NAMESPACE, namespace) + .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, resourceName) + .configure("address", inetAddress) + .configure(SshMachineLocation.PRIVATE_ADDRESSES, ImmutableSet.of(nodeAddress)); + + KubernetesMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec); + + String serviceName = String.format("%s-%s", resourceName, chartName); + Service service = getService(namespace, serviceName, client); + registerPortMappings(machine, entity, service); + return machine; + + } catch (Exception e) { + throw Throwables.propagate(e); } + } - return machine; + private void installTillerPodAndService(String namespace, String serviceName, Map podLabels, KubernetesClient client) { + TillerInstaller installer = new TillerInstaller(); + installer.init(true); + getPod(namespace, podLabels, client); + getService(namespace, serviceName, client); } - protected String getContainerResourceType() { - return KubernetesResource.DEPLOYMENT; + private boolean isTillerInstalled(String namespace, Map podLabels, KubernetesClient client) { + return !Iterables.isEmpty(client.pods().inNamespace(namespace).withLabels(podLabels).list().getItems()); } protected void waitForSshable(final SshMachineLocation machine, Duration timeout) { @@ -502,12 +621,17 @@ protected void waitForSshable(final SshMachineLocation machine, Duration timeout } } - protected void registerPortMappings(KubernetesSshMachineLocation machine, Entity entity, Service service) { + protected void registerPortMappings(KubernetesMachineLocation machine, Entity entity, Service service) { PortForwardManager portForwardManager = (PortForwardManager) getManagementContext().getLocationRegistry() .getLocationManaged(PortForwardManagerLocationResolver.PFM_GLOBAL_SPEC); List ports = service.getSpec().getPorts(); - String publicHostText = machine.getSshHostAndPort().getHostText(); - LOG.debug("Recording port-mappings for container {} of {}: {}", machine, this, ports); + String publicHostText; + if (machine instanceof SshMachineLocation) { + publicHostText = ((SshMachineLocation) machine).getSshHostAndPort().getHostText(); + } else { + publicHostText = Iterables.getFirst(machine.config().get(SshMachineLocation.PRIVATE_ADDRESSES), null); + } + LOG.debug("Recording port-mappings for container {} of {}: {}", new Object[]{machine, this, ports}); for (ServicePort port : ports) { String protocol = port.getProtocol(); @@ -559,8 +683,7 @@ public String getFailureMessage() { } } - protected Pod getPod(final String namespace, final String name) { - try (KubernetesClient client = getClient()) { + protected Pod getPod(final String namespace, final String name, KubernetesClient client) { ExitCondition exitCondition = new ExitCondition() { @Override public Boolean call() { @@ -575,27 +698,30 @@ public String getFailureMessage() { }; waitForExitCondition(exitCondition); return client.pods().inNamespace(namespace).withName(name).get(); - } } - protected Pod getPod(final String namespace, final Map metadata) { - try (KubernetesClient client = getClient()) { - ExitCondition exitCondition = new ExitCondition() { - @Override - public Boolean call() { - PodList result = client.pods().inNamespace(namespace).withLabels(metadata).list(); - return !result.getItems().isEmpty() && result.getItems().get(0).getStatus().getPodIP() != null; - } + protected Pod getPod(final String namespace, final Map metadata, KubernetesClient client) { + ExitCondition exitCondition = new ExitCondition() { + @Override + public Boolean call() { + PodList result = client.pods().inNamespace(namespace).withLabels(metadata).list(); + return result.getItems().size() >= 1 && + Iterables.any(result.getItems().get(0).getStatus().getConditions(), new Predicate() { + @Override + public boolean apply(@Nullable PodCondition input) { + return input.getStatus().equals("True"); + } + }); + } - @Override - public String getFailureMessage() { - return "Cannot find pod with metadata: " + Joiner.on(" ").withKeyValueSeparator("=").join(metadata); - } - }; - waitForExitCondition(exitCondition); - PodList result = client.pods().inNamespace(namespace).withLabels(metadata).list(); - return result.getItems().get(0); - } + @Override + public String getFailureMessage() { + return "Cannot find pod with metadata: " + Joiner.on(" ").withKeyValueSeparator("=").join(metadata); + } + }; + waitForExitCondition(exitCondition); + PodList result = client.pods().inNamespace(namespace).withLabels(metadata).list(); + return result.getItems().get(0); } protected void createSecrets(String namespace, Map secrets) { @@ -765,7 +891,9 @@ public Boolean call() { return false; } for (EndpointSubset subset : endpoints.getSubsets()) { - if (!subset.getNotReadyAddresses().isEmpty()) { + if (!subset.getNotReadyAddresses().isEmpty() && + subset.getAddresses().isEmpty() && + subset.getNotReadyAddresses().size() > 0) { return false; } } @@ -808,7 +936,7 @@ protected LocationSpec prepareSshableLocationSpec( return locationSpec; } - protected void createPersistentVolumes(List volumes) { + protected void createPersistentVolumes(List volumes, KubernetesClient client) { for (final String persistentVolume : volumes) { PersistentVolume volume = new PersistentVolumeBuilder() .withNewMetadata() @@ -821,7 +949,6 @@ protected void createPersistentVolumes(List volumes) { .withNewHostPath().withPath("/tmp/pv-1").endHostPath() // TODO make it configurable .endSpec() .build(); - try (KubernetesClient client = getClient()) { client.persistentVolumes().create(volume); ExitCondition exitCondition = new ExitCondition() { @Override @@ -838,7 +965,6 @@ public String getFailureMessage() { } }; waitForExitCondition(exitCondition); - } } } @@ -970,6 +1096,10 @@ protected boolean isKubernetesResource(Entity entity) { return implementsInterface(entity, KubernetesResource.class); } + protected boolean isKubernetesHelmChart(Entity entity) { + return implementsInterface(entity, KubernetesHelmChart.class); + } + public boolean implementsInterface(Entity entity, Class type) { return Iterables.tryFind(Arrays.asList(entity.getClass().getInterfaces()), Predicates.assignableFrom(type)).isPresent(); } diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/location/openshift/OpenShiftLocation.java b/locations/container/src/main/java/org/apache/brooklyn/container/location/openshift/OpenShiftLocation.java index a66938d710..3df344f8da 100644 --- a/locations/container/src/main/java/org/apache/brooklyn/container/location/openshift/OpenShiftLocation.java +++ b/locations/container/src/main/java/org/apache/brooklyn/container/location/openshift/OpenShiftLocation.java @@ -107,7 +107,7 @@ protected boolean findResourceAddress(LocationSpec labels = deploymentConfig.getSpec().getTemplate().getMetadata().getLabels(); - Pod pod = getPod(namespace, labels); + Pod pod = getPod(namespace, labels, client); entity.sensors().set(OpenShiftPod.KUBERNETES_POD, pod.getMetadata().getName()); InetAddress node = Networking.getInetAddressWithFixedName(pod.getSpec().getNodeName()); diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/supplier/TillerSupplier.java b/locations/container/src/main/java/org/apache/brooklyn/container/supplier/TillerSupplier.java new file mode 100644 index 0000000000..ce9f22e531 --- /dev/null +++ b/locations/container/src/main/java/org/apache/brooklyn/container/supplier/TillerSupplier.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.brooklyn.container.supplier; + +import java.net.MalformedURLException; + +import org.microbean.helm.Tiller; + +import com.google.common.base.Supplier; +import com.google.common.base.Throwables; + +import io.fabric8.kubernetes.client.DefaultKubernetesClient; + +public class TillerSupplier implements Supplier { + private final DefaultKubernetesClient client; + + public TillerSupplier(DefaultKubernetesClient client) { + this.client = client; + } + + @Override + public Tiller get() { + try { + return new Tiller(client); + } catch (MalformedURLException e) { + throw Throwables.propagate(e); + } + } +} diff --git a/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationLiveTest.java b/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationLiveTest.java index ed42bd2250..4df41b42be 100644 --- a/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationLiveTest.java +++ b/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationLiveTest.java @@ -61,6 +61,8 @@ public class KubernetesLocationLiveTest extends BrooklynAppLiveTestSupport { public static final String KUBERNETES_ENDPOINT = System.getProperty("test.brooklyn-container-service.kubernetes.endpoint", ""); public static final String IDENTITY = System.getProperty("test.brooklyn-container-service.kubernetes.identity", ""); public static final String CREDENTIAL = System.getProperty("test.brooklyn-container-service.kubernetes.credential", ""); + public static final String KUBECONFIG = System.getProperty("test.brooklyn-container-service.kubernetes.kubeconfig", ""); + private static final Logger LOG = LoggerFactory.getLogger(KubernetesLocationLiveTest.class); protected KubernetesLocation loc; protected List machines; diff --git a/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java b/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java index a3030b1522..76bcd59695 100644 --- a/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java +++ b/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java @@ -24,6 +24,7 @@ import static com.google.common.base.Predicates.notNull; import static org.apache.brooklyn.container.location.kubernetes.KubernetesLocationLiveTest.CREDENTIAL; import static org.apache.brooklyn.container.location.kubernetes.KubernetesLocationLiveTest.IDENTITY; +import static org.apache.brooklyn.container.location.kubernetes.KubernetesLocationLiveTest.KUBECONFIG; import static org.apache.brooklyn.container.location.kubernetes.KubernetesLocationLiveTest.KUBERNETES_ENDPOINT; import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEquals; import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEqualsEventually; @@ -43,6 +44,7 @@ import org.apache.brooklyn.api.location.MachineProvisioningLocation; import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; import org.apache.brooklyn.container.entity.docker.DockerContainer; +import org.apache.brooklyn.container.entity.kubernetes.KubernetesHelmChart; import org.apache.brooklyn.container.entity.kubernetes.KubernetesPod; import org.apache.brooklyn.container.entity.kubernetes.KubernetesResource; import org.apache.brooklyn.core.entity.Attributes; @@ -93,6 +95,7 @@ public void setUp() throws Exception { "location:", " kubernetes:", " " + KubernetesLocationConfig.MASTER_URL.getName() + ": \"" + KUBERNETES_ENDPOINT + "\"", + " " + (StringUtils.isBlank(KUBECONFIG) ? "" : "kubeconfig: " + KUBECONFIG), " " + (StringUtils.isBlank(IDENTITY) ? "" : "identity: " + IDENTITY), " " + (StringUtils.isBlank(CREDENTIAL) ? "" : "credential: " + CREDENTIAL)); } @@ -510,6 +513,27 @@ public void testNginxService() throws Exception { assertReachableEventually(HostAndPort.fromString(httpPublicPort)); } + @Test(groups={"Live"}) + public void testJenkinsHelmChart() throws Exception { + String yaml = Joiner.on("\n").join( + locationYaml, + "services:", + " - type: " + KubernetesHelmChart.class.getName(), + " name: \"jenkins-helm\"", + " chartName: jenkins"); + Entity app = createStartWaitAndLogApplication(yaml); + + Iterable resources = Entities.descendantsAndSelf(app, KubernetesHelmChart.class); + KubernetesHelmChart jenkisHelm = Iterables.find(resources, EntityPredicates.displayNameEqualTo("jenkins-helm")); + + assertEntityHealthy(jenkisHelm); + + Entities.dumpInfo(app); + + Integer httpPort = assertAttributeEventuallyNonNull(jenkisHelm, Sensors.newIntegerSensor("kubernetes.http.port")); + assertEquals(httpPort, Integer.valueOf(8080)); + } + protected void assertReachableEventually(final HostAndPort hostAndPort) { succeedsEventually(new Runnable() { public void run() { From 424ac85c45c185485f00a0db80282d58534c7986 Mon Sep 17 00:00:00 2001 From: iuliana Date: Mon, 18 May 2020 16:54:11 +0100 Subject: [PATCH 2/5] upgraded versions to support microbean-helm dependencies --- karaf/features/pom.xml | 187 +++++++++--------- karaf/features/src/main/feature/feature.xml | 51 ++++- locations/container/pom.xml | 21 +- .../kubernetes/KubernetesHelmChart.java | 1 - .../kubernetes/KubernetesHelmChartImpl.java | 2 +- .../kubernetes/KubernetesLocation.java | 125 ++++++------ pom.xml | 31 ++- 7 files changed, 227 insertions(+), 191 deletions(-) diff --git a/karaf/features/pom.xml b/karaf/features/pom.xml index 34da460647..13ed9008ef 100755 --- a/karaf/features/pom.xml +++ b/karaf/features/pom.xml @@ -19,101 +19,102 @@ --> - - 4.0.0 - - org.apache.brooklyn - brooklyn-karaf - 1.1.0-SNAPSHOT - - brooklyn-features - Brooklyn Karaf Features - pom + 4.0.0 + + org.apache.brooklyn + brooklyn-karaf + 1.1.0-SNAPSHOT + - - - - src/main/feature - true - - **/* - - - - - - org.apache.maven.plugins - maven-resources-plugin - 2.6 - - false - - ${*} - - - - - filter - generate-resources - - resources - - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - package - - attach-artifact - - - - - target/classes/feature.xml - features - xml - - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.apache.karaf.tooling - karaf-maven-plugin - [4.1.6,) - - verify - - - - - - - - - - - - - + brooklyn-features + Brooklyn Karaf Features + pom + + + + + src/main/feature + true + + **/* + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + false + + ${*} + + + + + filter + generate-resources + + resources + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.1.0 + + + package + + attach-artifact + + + + + target/classes/feature.xml + features + xml + + + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.karaf.tooling + karaf-maven-plugin + [4.1.6,) + + verify + + + + + + + + + + + + + diff --git a/karaf/features/src/main/feature/feature.xml b/karaf/features/src/main/feature/feature.xml index 8ce7ecf343..db417622ea 100644 --- a/karaf/features/src/main/feature/feature.xml +++ b/karaf/features/src/main/feature/feature.xml @@ -202,7 +202,7 @@ brooklyn-camp-brooklyn brooklyn-camp-base - cxf-jaxrs-with-optional-dependencies + cxf-jaxrs mvn:org.apache.cxf/cxf-rt-rs-security-cors/${cxf.version} mvn:org.apache.cxf/cxf-rt-frontend-jaxrs/${cxf.version} mvn:org.apache.cxf.karaf/cxf-karaf-commands/${cxf.version} @@ -218,14 +218,6 @@ - - cxf-jaxrs - - - mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${fasterxml.jackson.version} - - - brooklyn-rest-resources-prereqs mvn:org.apache.brooklyn/brooklyn-rest-resources/${project.version} @@ -301,6 +293,8 @@ brooklyn-core + brooklyn-utils-common + brooklyn-locations-jclouds mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${fasterxml.jackson.version} mvn:com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/${fasterxml.jackson.version} @@ -315,6 +309,7 @@ wrap:mvn:com.squareup.okhttp3/okhttp/3.12.6$Bundle-SymbolicName=squareup-okhttp3&Bundle-Version=3.12.6&Import-Package=okio;version=1.15,*;resolution:=optional wrap:mvn:com.squareup.okhttp3/logging-interceptor/3.12.6$Bundle-SymbolicName=squareup-okhttp3-logging-interceptor&Bundle-Version=3.12.6&Import-Package=*;resolution:=mandatory + mvn:io.fabric8/zjsonpatch/0.3.0 @@ -322,9 +317,47 @@ mvn:io.fabric8/kubernetes-client/${kubernetes-client.version}/jar/bundle mvn:io.fabric8/openshift-client/${kubernetes-client.version}/jar/bundle + wrap:mvn:org.microbean/microbean-helm/2.12.4-SNAPSHOT/jar/$Bundle-SymbolicName=microbean-helm&Bundle-Version=2.12.4-SNAPSHOT&Import-Package=*;resolution:=mandatory + + wrap:mvn:org.microbean/microbean-development-annotations/0.1.3$Bundle-SymbolicName=microbean-development-annotations&Bundle-Version=0.1.3&Import-Package=*;resolution:=mandatory + wrap:mvn:org.kamranzafar/jtar/2.3$Bundle-SymbolicName=jtar&Bundle-Version=2.3&Import-Package=*;resolution:=mandatory + wrap:mvn:com.github.zafarkhaja/java-semver/0.9.0$Bundle-SymbolicName=java-semver&Bundle-Version=0.9.0&Import-Package=*;resolution:=mandatory + wrap:mvn:org.microbean/microbean-kubernetes/0.1.3$Bundle-SymbolicName=microbean-kubernetes&Bundle-Version=0.1.3&Import-Package=*;resolution:=mandatory + + wrap:mvn:io.grpc/grpc-netty/1.23.0$Bundle-SymbolicName=grpc-netty&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + mvn:io.netty/netty-codec-http2/4.1.38.Final + mvn:io.netty/netty-resolver/4.1.38.Final + mvn:io.netty/netty-common/4.1.38.Final + mvn:io.netty/netty-buffer/4.1.38.Final + mvn:io.netty/netty-codec/4.1.38.Final + mvn:io.netty/netty-transport/4.1.38.Final + mvn:io.netty/netty-codec-http/4.1.38.Final + mvn:io.netty/netty-codec-socks/4.1.38.Final + mvn:io.netty/netty-handler/4.1.38.Final + mvn:io.netty/netty-handler-proxy/4.1.38.Final + wrap:mvn:io.grpc/grpc-core/1.23.0$Bundle-SymbolicName=grpc-core&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.grpc/grpc-context/1.23.0$Bundle-SymbolicName=grpc-context&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.opencensus/opencensus-api/0.11.0$Bundle-SymbolicName=opencensus-api&Bundle-Version=0.11.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.opencensus/opencensus-contrib-grpc-metrics/0.11.0$Bundle-SymbolicName=opencensus-contrib-grpc-metrics&Bundle-Version=0.11.0&Import-Package=*;resolution:=mandatory + + mvn:com.google.protobuf/protobuf-java/3.9.0 + wrap:mvn:io.grpc/grpc-protobuf/1.23.0$Bundle-SymbolicName=grpc-protobuf&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.grpc/grpc-services/1.23.0$Bundle-SymbolicName=grpc-services&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.grpc/grpc-stub/1.23.0$Bundle-SymbolicName=grpc-stub&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.grpc/grpc-protobuf-lite/1.23.0$Bundle-SymbolicName=grpc-protobuf-lite&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + mvn:com.google.protobuf/protobuf-java-util/3.9.0 + wrap:mvn:com.google.api.grpc/proto-google-common-protos/1.12.0$Bundle-SymbolicName=proto-google-common-protos&Bundle-Version=1.12.0&Import-Package=*;resolution:=mandatory + wrap:mvn:io.grpc/grpc-core/1.23.0$Bundle-SymbolicName=grpc-core&Bundle-Version=1.23.0&Import-Package=*;resolution:=mandatory + wrap:mvn:com.google.instrumentation/instrumentation-api/0.4.3$Bundle-SymbolicName=instrumentation-api&Bundle-Version=0.4.3&Import-Package=*;resolution:=mandatory + + wrap:mvn:com.google.errorprone/error_prone_annotations/2.3.2$Bundle-SymbolicName=error_prone_annotations&Bundle-Version=2.3.2&Import-Package=*;resolution:=optional + wrap:mvn:io.perfmark/perfmark-api/0.17.0$Bundle-SymbolicName=perfmark-api&Bundle-Version=0.17.0&Import-Package=*;resolution:=optional + mvn:io.netty/netty-tcnative-boringssl-static/2.0.30.Final/jar/${os.detected.classifier} + mvn:org.apache.brooklyn/brooklyn-locations-container/${project.version} + mvn:org.apache.brooklyn/brooklyn-test-framework/${project.version} diff --git a/locations/container/pom.xml b/locations/container/pom.xml index 7958f358aa..34c054623a 100644 --- a/locations/container/pom.xml +++ b/locations/container/pom.xml @@ -35,14 +35,29 @@ org.microbean microbean-helm - 2.8.2.1.1.1 + 2.12.4-SNAPSHOT + + org.yaml + snakeyaml + com.google.errorprone error_prone_annotations + + io.netty + netty-tcnative-boringssl-static + + + + io.netty + netty-tcnative-boringssl-static + 2.0.30.Final + ${os.detected.classifier} + io.fabric8 openshift-client @@ -164,12 +179,12 @@ + - kr.motd.maven os-maven-plugin - 1.5.0.Final + 1.6.2 diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java index e44a4bc5d8..55362074c8 100644 --- a/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java +++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChart.java @@ -20,7 +20,6 @@ import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.entity.software.base.SoftwareProcess; -import org.apache.brooklyn.util.core.ResourcePredicates; @ImplementedBy(KubernetesHelmChartImpl.class) public interface KubernetesHelmChart extends SoftwareProcess { diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java index 9d3484e525..04bd3ce974 100644 --- a/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java +++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/kubernetes/KubernetesHelmChartImpl.java @@ -31,5 +31,5 @@ public void init() { config().set(PROVISIONING_PROPERTIES.subKey("pollForFirstReachableAddress"), false); config().set(EmptySoftwareProcessImpl.USE_SSH_MONITORING, false); } - + } diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java b/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java index 5301a0d9a9..d0147b1beb 100644 --- a/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java +++ b/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java @@ -23,19 +23,12 @@ import com.google.common.collect.*; import com.google.common.io.BaseEncoding; import com.google.common.net.HostAndPort; -//import hapi.chart.ChartOuterClass.Chart; -//import hapi.release.ReleaseOuterClass.Release; -//import hapi.services.tiller.Tiller.InstallReleaseRequest; -//import hapi.services.tiller.Tiller.InstallReleaseResponse; -//import hapi.services.tiller.Tiller.UninstallReleaseRequest; -//import hapi.services.tiller.Tiller.UninstallReleaseResponse; import hapi.chart.ChartOuterClass.Chart; import hapi.release.ReleaseOuterClass.Release; import hapi.services.tiller.Tiller.InstallReleaseRequest; import hapi.services.tiller.Tiller.InstallReleaseResponse; import hapi.services.tiller.Tiller.UninstallReleaseRequest; import hapi.services.tiller.Tiller.UninstallReleaseResponse; -import io.fabric8.kubernetes.client.AutoAdaptableKubernetesClient; import org.microbean.helm.ReleaseManager; import org.microbean.helm.Tiller; import org.microbean.helm.TillerInstaller; @@ -292,13 +285,9 @@ protected void deleteKubernetesHelmChartLocation(Entity entity) { .setName(releaseName) .setPurge(true) .build()); - UninstallReleaseResponse response = uninstallReleaseResponseFuture.get(); + UninstallReleaseResponse response = uninstallReleaseResponseFuture.get(); LOG.debug("Release {} uninstalled", response); - } catch (IOException e) { - throw Throwables.propagate(e); - } catch (InterruptedException e) { - throw Throwables.propagate(e); - } catch (ExecutionException e) { + } catch (IOException | InterruptedException | ExecutionException e) { throw Throwables.propagate(e); } } @@ -351,18 +340,18 @@ protected KubernetesMachineLocation createKubernetesResourceLocation(Entity enti try (KubernetesClient client = getClient()) { final List result = client.load(processedResource).createOrReplace(); - ExitCondition exitCondition = new ExitCondition() { - @Override - public Boolean call() { - if (result.isEmpty()) { - return false; - } - HasMetadata check = client.resource(result.get(0)).inNamespace(result.get(0).getMetadata().getNamespace()).get(); - if (result.size() > 1 || check != null || check.getMetadata() == null) { - return false; + ExitCondition exitCondition = new ExitCondition() { + @Override + public Boolean call() { + if (result.isEmpty()) { + return false; + } + HasMetadata check = client.resource(result.get(0)).inNamespace(result.get(0).getMetadata().getNamespace()).get(); + if (result.size() > 1 || check != null || check.getMetadata() == null) { + return false; + } + return true; } - return true; - } @Override public String getFailureMessage() { @@ -506,7 +495,7 @@ protected KubernetesMachineLocation createKubernetesContainerLocation(Entity ent .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, deploymentName) .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE, getContainerResourceType()); - machine = getManagementContext().getLocationManager().createLocation(locationSpec); + machine = getManagementContext().getLocationManager().createLocation(locationSpec); registerPortMappings(machine, entity, service); if (!isDockerContainer(entity)) { waitForSshable(machine, Duration.FIVE_MINUTES); @@ -521,23 +510,23 @@ protected String getContainerResourceType() { protected KubernetesMachineLocation createKubernetesHelmChartLocation(Entity entity, ConfigBag setup) { try (KubernetesClient client = getClient()){ - Map podLabels = ImmutableMap.of("name", "tiller", "app", "helm"); - if (!isTillerInstalled("kube-system", podLabels, client)) { - installTillerPodAndService("kube-system", "tiller-deploy", podLabels, client); - } - // Create ${HOME}/.helm/{cache/archive,repository/cache} - try { - Files.createDirectories(Paths.get(System.getProperty("user.home"),".helm", "cache", "archive")); - Files.createDirectories(Paths.get(System.getProperty("user.home"),".helm", "repository", "cache")); - } catch (IOException e) { - throw Throwables.propagate(e); - } + Map podLabels = ImmutableMap.of("name", "tiller", "app", "helm"); + if (!isTillerInstalled("kube-system", podLabels, client)) { + installTillerPodAndService("kube-system", "tiller-deploy", podLabels, client); + } + // Create ${HOME}/.helm/{cache/archive,repository/cache} + try { + Files.createDirectories(Paths.get(System.getProperty("user.home"),".helm", "cache", "archive")); + Files.createDirectories(Paths.get(System.getProperty("user.home"),".helm", "repository", "cache")); + } catch (IOException e) { + throw Throwables.propagate(e); + } - tiller = Suppliers.memoize(new TillerSupplier((DefaultKubernetesClient) client)).get(); - String chartName = entity.config().get(KubernetesHelmChart.CHART_NAME); - String chartVersion = entity.config().get(KubernetesHelmChart.CHART_VERSION); + tiller = Suppliers.memoize(new TillerSupplier((DefaultKubernetesClient) client)).get(); + String chartName = entity.config().get(KubernetesHelmChart.CHART_NAME); + String chartVersion = entity.config().get(KubernetesHelmChart.CHART_VERSION); - ReleaseManager chartManager = new ReleaseManager(tiller); + ReleaseManager chartManager = new ReleaseManager(tiller); InstallReleaseRequest.Builder requestBuilder = InstallReleaseRequest.newBuilder(); requestBuilder.setTimeout(300L); requestBuilder.setWait(true); @@ -684,20 +673,20 @@ public String getFailureMessage() { } protected Pod getPod(final String namespace, final String name, KubernetesClient client) { - ExitCondition exitCondition = new ExitCondition() { - @Override - public Boolean call() { - Pod result = client.pods().inNamespace(namespace).withName(name).get(); - return result != null && result.getStatus().getPodIP() != null; - } + ExitCondition exitCondition = new ExitCondition() { + @Override + public Boolean call() { + Pod result = client.pods().inNamespace(namespace).withName(name).get(); + return result != null && result.getStatus().getPodIP() != null; + } - @Override - public String getFailureMessage() { - return "Cannot find pod with name: " + name; - } - }; - waitForExitCondition(exitCondition); - return client.pods().inNamespace(namespace).withName(name).get(); + @Override + public String getFailureMessage() { + return "Cannot find pod with name: " + name; + } + }; + waitForExitCondition(exitCondition); + return client.pods().inNamespace(namespace).withName(name).get(); } protected Pod getPod(final String namespace, final Map metadata, KubernetesClient client) { @@ -949,22 +938,22 @@ protected void createPersistentVolumes(List volumes, KubernetesClient cl .withNewHostPath().withPath("/tmp/pv-1").endHostPath() // TODO make it configurable .endSpec() .build(); - client.persistentVolumes().create(volume); - ExitCondition exitCondition = new ExitCondition() { - @Override - public Boolean call() { - PersistentVolume pv = client.persistentVolumes().withName(persistentVolume).get(); - return pv != null && pv.getStatus() != null - && pv.getStatus().getPhase().equals(PHASE_AVAILABLE); - } + client.persistentVolumes().create(volume); + ExitCondition exitCondition = new ExitCondition() { + @Override + public Boolean call() { + PersistentVolume pv = client.persistentVolumes().withName(persistentVolume).get(); + return pv != null && pv.getStatus() != null + && pv.getStatus().getPhase().equals(PHASE_AVAILABLE); + } - @Override - public String getFailureMessage() { - PersistentVolume pv = client.persistentVolumes().withName(persistentVolume).get(); - return "PersistentVolume for " + persistentVolume + " " + (pv == null ? "absent" : "pv=" + pv); - } - }; - waitForExitCondition(exitCondition); + @Override + public String getFailureMessage() { + PersistentVolume pv = client.persistentVolumes().withName(persistentVolume).get(); + return "PersistentVolume for " + persistentVolume + " " + (pv == null ? "absent" : "pv=" + pv); + } + }; + waitForExitCondition(exitCondition); } } diff --git a/pom.xml b/pom.xml index 761a03231d..780e85c784 100644 --- a/pom.xml +++ b/pom.xml @@ -105,7 +105,7 @@ 1.2.3 1.7.25 - 18.0 + 19.0 - 2.10.1 - 3.3.5 - 4.5.10 - 4.4.12 + 2.10.1 + 3.3.2 + 4.5.8 + 4.4.11 - 4.5.10 + 4.5.8 3.3.2 2.4.15 2.0.1 - 1.25 + 1.25 1.5.6 - 2.5 + 2.7 3.0.1 1.61 0.2.0 @@ -161,21 +161,20 @@ 1.0 1.7 2.4 - 2.1.1 + 2.1.1 2.8.0-rc1 1.2.1 - 0.9.0 + 0.8.0 1.4.0 4.9.0 - 4.2.8 + 4.2.7 ${karaf.version} - 9.4.22.v20191022 + 9.4.20.v20190813 3.2.2 - 7.2.14 + 7.2.11 2.3.2 - 1.2.3 4.1.0 @@ -187,10 +186,10 @@ 1.2 2.3 1.2 - 5.2 + 5.2 1.9.4 1.4.7 - 1.3.2 + 1.3.1 6.10 From a53ab4e8b205b529b4d44d25c68dd6aad76558cd Mon Sep 17 00:00:00 2001 From: iuliana Date: Mon, 18 May 2020 17:03:22 +0100 Subject: [PATCH 3/5] upgraded deps that were overriden from master --- pom.xml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 780e85c784..a9fe4e2f60 100644 --- a/pom.xml +++ b/pom.xml @@ -123,15 +123,15 @@ 2.3.0_3 2.10.1 - 3.3.2 - 4.5.8 - 4.4.11 + 3.3.5 + 4.5.10 + 4.4.12 - 4.5.8 + 4.5.10 3.3.2 2.4.15 2.0.1 - 1.25 + 1.25 1.5.6 2.7 @@ -169,12 +169,13 @@ 4.9.0 - 4.2.7 + 4.2.8 ${karaf.version} - 9.4.20.v20190813 + 9.4.22.v20191022 3.2.2 - 7.2.11 + 7.2.14 2.3.2 + 1.2.3 4.1.0 @@ -186,10 +187,10 @@ 1.2 2.3 1.2 - 5.2 + 5.2 1.9.4 1.4.7 - 1.3.1 + 1.3.2 6.10 From c03b7affd6be351a7681ce15f2b1f38f135d0b20 Mon Sep 17 00:00:00 2001 From: iuliana Date: Mon, 18 May 2020 17:11:20 +0100 Subject: [PATCH 4/5] upgraded cxf dep --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a9fe4e2f60..4d45d1d300 100644 --- a/pom.xml +++ b/pom.xml @@ -161,10 +161,10 @@ 1.0 1.7 2.4 - 2.1.1 + 2.1.1 2.8.0-rc1 1.2.1 - 0.8.0 + 0.9.0 1.4.0 4.9.0 From b9a39705a4c6c5dfdbe7cb2ee3b81b5fea32ce0a Mon Sep 17 00:00:00 2001 From: iuliana Date: Mon, 25 May 2020 16:31:55 +0100 Subject: [PATCH 5/5] added comments and new OSGI microhelm bundle --- karaf/features/src/main/feature/feature.xml | 7 ++-- locations/container/pom.xml | 37 --------------------- pom.xml | 6 ++-- 3 files changed, 7 insertions(+), 43 deletions(-) diff --git a/karaf/features/src/main/feature/feature.xml b/karaf/features/src/main/feature/feature.xml index db417622ea..dd71f9fdeb 100644 --- a/karaf/features/src/main/feature/feature.xml +++ b/karaf/features/src/main/feature/feature.xml @@ -317,8 +317,8 @@ mvn:io.fabric8/kubernetes-client/${kubernetes-client.version}/jar/bundle mvn:io.fabric8/openshift-client/${kubernetes-client.version}/jar/bundle - wrap:mvn:org.microbean/microbean-helm/2.12.4-SNAPSHOT/jar/$Bundle-SymbolicName=microbean-helm&Bundle-Version=2.12.4-SNAPSHOT&Import-Package=*;resolution:=mandatory - + mvn:org.microbean/microbean-helm/2.12.4-SNAPSHOT + wrap:mvn:org.microbean/microbean-development-annotations/0.1.3$Bundle-SymbolicName=microbean-development-annotations&Bundle-Version=0.1.3&Import-Package=*;resolution:=mandatory wrap:mvn:org.kamranzafar/jtar/2.3$Bundle-SymbolicName=jtar&Bundle-Version=2.3&Import-Package=*;resolution:=mandatory wrap:mvn:com.github.zafarkhaja/java-semver/0.9.0$Bundle-SymbolicName=java-semver&Bundle-Version=0.9.0&Import-Package=*;resolution:=mandatory @@ -352,7 +352,8 @@ wrap:mvn:com.google.errorprone/error_prone_annotations/2.3.2$Bundle-SymbolicName=error_prone_annotations&Bundle-Version=2.3.2&Import-Package=*;resolution:=optional wrap:mvn:io.perfmark/perfmark-api/0.17.0$Bundle-SymbolicName=perfmark-api&Bundle-Version=0.17.0&Import-Package=*;resolution:=optional - mvn:io.netty/netty-tcnative-boringssl-static/2.0.30.Final/jar/${os.detected.classifier} + + mvn:io.netty/netty-tcnative-boringssl-static/2.0.30.Final mvn:org.apache.brooklyn/brooklyn-locations-container/${project.version} diff --git a/locations/container/pom.xml b/locations/container/pom.xml index 34c054623a..85e9c1f37e 100644 --- a/locations/container/pom.xml +++ b/locations/container/pom.xml @@ -56,7 +56,6 @@ io.netty netty-tcnative-boringssl-static 2.0.30.Final - ${os.detected.classifier} io.fabric8 @@ -177,40 +176,4 @@ - - - - - - kr.motd.maven - os-maven-plugin - 1.6.2 - - - - - - org.apache.maven.plugins - maven-antrun-plugin - - - initialize - - true - - - - - - - - run - - - - - - diff --git a/pom.xml b/pom.xml index 4d45d1d300..50f75bb3e8 100644 --- a/pom.xml +++ b/pom.xml @@ -104,8 +104,8 @@ 2.1.2 1.2.3 1.7.25 - - 19.0 + + 19.0 1.5.6 - 2.7 + 2.7 3.0.1 1.61 0.2.0