Skip to content

Commit

Permalink
Merge pull request #991 from car-roll/guava
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlatombe committed May 19, 2021
2 parents 76be439 + c63a83b commit f4aa445
Show file tree
Hide file tree
Showing 24 changed files with 221 additions and 357 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Expand Up @@ -132,6 +132,11 @@
<artifactId>metrics</artifactId>
<version>4.0.2.6</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>caffeine-api</artifactId>
<version>2.9.1-23.v51c4e2c879c8</version>
</dependency>

<!-- for testing -->
<dependency>
Expand Down
Expand Up @@ -15,8 +15,6 @@
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import com.google.common.base.Preconditions;

import hudson.Extension;
import hudson.Util;
import hudson.model.AbstractDescribableImpl;
Expand Down Expand Up @@ -78,7 +76,9 @@ public ContainerTemplate(String image) {

@DataBoundConstructor
public ContainerTemplate(String name, String image) {
Preconditions.checkArgument(PodTemplateUtils.validateImage(image));
if (!PodTemplateUtils.validateImage(image)) {
throw new IllegalArgumentException();
}
this.name = name;
this.image = image;
}
Expand Down
Expand Up @@ -34,13 +34,12 @@
import java.io.IOException;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import static com.google.common.collect.Sets.newHashSet;

/**
* @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
*/
Expand Down Expand Up @@ -83,7 +82,7 @@ public void setUp(Context context, Run<?, ?> build, FilePath workspace, Launcher
}
workspace.mkdirs();
FilePath configFile = workspace.createTempFile(".kube", "config");
Set<String> tempFiles = newHashSet(configFile.getRemote());
Set<String> tempFiles = new HashSet<>(Arrays.asList(configFile.getRemote()));

context.env("KUBECONFIG", configFile.getRemote());
context.setDisposer(new CleanupDisposer(tempFiles));
Expand Down
@@ -1,12 +1,15 @@
package org.csanchez.jenkins.plugins.kubernetes;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import hudson.model.PeriodicWork;
import io.fabric8.kubernetes.client.HttpClientAware;
import okhttp3.Dispatcher;
Expand All @@ -15,10 +18,6 @@
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

import com.google.common.base.Objects;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import hudson.Extension;
import hudson.XmlFile;
import hudson.model.Saveable;
Expand All @@ -41,14 +40,14 @@ public class KubernetesClientProvider {
private static final long CACHE_EXPIRATION = Long.getLong(
KubernetesClientProvider.class.getPackage().getName() + ".clients.cacheExpiration", TimeUnit.MINUTES.toSeconds(10));

private static final Cache<String, Client> clients = CacheBuilder.newBuilder()
private static final Cache<String, Client> clients = Caffeine.newBuilder()
.expireAfterWrite(CACHE_EXPIRATION, TimeUnit.SECONDS)
.removalListener(rl -> {
Client client = (Client) rl.getValue();
.removalListener( (key, value, cause) -> {
Client client = (Client) value;
if (client != null) {
LOGGER.log(Level.FINE, () -> "Expiring Kubernetes client " + rl.getKey() + " " + client.client);
LOGGER.log(Level.FINE, () -> "Expiring Kubernetes client " + key + " " + client.client + ": " + cause);
}
})
} )
.build();

private KubernetesClientProvider() {
Expand All @@ -69,9 +68,10 @@ static KubernetesClient createClient(KubernetesCloud cloud) throws KubernetesAut
}

private static int getValidity(KubernetesCloud cloud) {
return Objects.hashCode(cloud.getServerUrl(), cloud.getNamespace(), cloud.getServerCertificate(),
Object cloudObjects[] = { cloud.getServerUrl(), cloud.getNamespace(), cloud.getServerCertificate(),
cloud.getCredentialsId(), cloud.isSkipTlsVerify(), cloud.getConnectTimeout(), cloud.getReadTimeout(),
cloud.getMaxRequestsPerHostStr(), cloud.isUseJenkinsProxy());
cloud.getMaxRequestsPerHostStr(), cloud.isUseJenkinsProxy() };
return Arrays.hashCode(cloudObjects);
}

private static class Client {
Expand Down
Expand Up @@ -18,13 +18,11 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.servlet.ServletException;

import com.google.common.annotations.VisibleForTesting;
import hudson.Main;
import hudson.model.ItemGroup;
import hudson.model.Node;
Expand All @@ -48,7 +46,6 @@
import com.cloudbees.plugins.credentials.common.StandardCredentials;
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
import com.google.common.collect.ImmutableMap;

import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
Expand Down Expand Up @@ -93,7 +90,7 @@ public class KubernetesCloud extends Cloud {
public static final String JNLP_NAME = "jnlp";
/** label for all pods started by the plugin */
@Deprecated
public static final Map<String, String> DEFAULT_POD_LABELS = ImmutableMap.of("jenkins", "slave");
public static final Map<String, String> DEFAULT_POD_LABELS = Collections.singletonMap("jenkins", "slave");

/** Default timeout for idle workers that don't correctly indicate exit. */
public static final int DEFAULT_RETENTION_TIMEOUT_MINUTES = 5;
Expand Down
Expand Up @@ -28,6 +28,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
Expand All @@ -43,9 +44,6 @@
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;

import hudson.model.TaskListener;
import hudson.slaves.JNLPLauncher;
import hudson.slaves.SlaveComputer;
Expand Down Expand Up @@ -176,7 +174,7 @@ else if (httpCode == 409 && e.getMessage().contains("Operation cannot be fulfill

// We need the pod to be running and connected before returning
// otherwise this method keeps being called multiple times
List<String> validStates = ImmutableList.of("Running");
List<String> validStates = Collections.unmodifiableList(Arrays.asList("Running"));

int waitForSlaveToConnect = template.getSlaveConnectTimeout();
int waitedForSlave;
Expand Down Expand Up @@ -263,7 +261,7 @@ else if (httpCode == 409 && e.getMessage().contains("Operation cannot be fulfill
} catch (IOException | InterruptedException e) {
LOGGER.log(Level.WARNING, "Unable to remove Jenkins node", e);
}
throw Throwables.propagate(ex);
throw new RuntimeException(ex);
}
}

Expand Down
@@ -1,6 +1,5 @@
package org.csanchez.jenkins.plugins.kubernetes;

import com.google.common.annotations.VisibleForTesting;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
import hudson.ExtensionList;
Expand All @@ -11,6 +10,8 @@
import jenkins.metrics.api.Metrics;
import jenkins.model.Jenkins;
import jenkins.model.NodeListener;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

import javax.annotation.Nonnull;
import java.util.Collections;
Expand Down Expand Up @@ -121,13 +122,13 @@ public void unregister(@Nonnull KubernetesCloud cloud, @Nonnull PodTemplate podT
}

@Nonnull
@VisibleForTesting
@Restricted(NoExternalUse.class)
AtomicInteger getGlobalCount(String name) {
return cloudCounts.computeIfAbsent(name, k -> new AtomicInteger());
}

@Nonnull
@VisibleForTesting
@Restricted(NoExternalUse.class)
AtomicInteger getPodTemplateCount(String id) {
return podTemplateCounts.computeIfAbsent(id, k -> new AtomicInteger());
}
Expand Down
@@ -1,6 +1,5 @@
package org.csanchez.jenkins.plugins.kubernetes;

import com.google.common.collect.ImmutableMap;
import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
Expand All @@ -11,6 +10,8 @@
import javax.annotation.Nonnull;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -53,11 +54,11 @@ public void setValue(String value) {
*/
@Nonnull
static Map<String, String> toMap(@Nonnull Iterable<PodLabel> labels) {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
Map<String, String> builder = new HashMap<>();
for (PodLabel podLabel : labels) {
builder.put(podLabel.getKey(), substituteEnv(podLabel.getValue()));
}
return builder.build();
return Collections.unmodifiableMap(builder);
}

/**
Expand Down
@@ -1,9 +1,14 @@
package org.csanchez.jenkins.plugins.kubernetes;

import java.io.Serializable;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -15,10 +20,6 @@
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;

import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import hudson.model.DescriptorVisibilityFilter;
Expand All @@ -38,9 +39,6 @@
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;

import hudson.Extension;
import hudson.Util;
import hudson.model.labels.LabelAtom;
Expand Down Expand Up @@ -74,8 +72,19 @@ public class PodTemplate extends AbstractDescribableImpl<PodTemplate> implements

/**
* Digest function that is used to compute the kubernetes label "jenkins/label-digest"
* Not used for security.
*/
public static final HashFunction LABEL_DIGEST_FUNCTION = Hashing.sha1();
protected static final MessageDigest LABEL_DIGEST_FUNCTION;
static {
try {
LABEL_DIGEST_FUNCTION = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
// will never happen, SHA-256 support required on every Java implementation
e.printStackTrace();
// throw error to allow variable to be set as final
throw new AssertionError(e);
}
}

private String id;

Expand All @@ -88,9 +97,9 @@ public class PodTemplate extends AbstractDescribableImpl<PodTemplate> implements
private String image;

private boolean privileged;

private Long runAsUser;

private Long runAsGroup;

private String supplementalGroups;
Expand Down Expand Up @@ -461,17 +470,16 @@ public void setLabel(String label) {

private void recomputeLabelDerivedFields() {
this.labelSet = Label.parse(label);
Map<String, String> tempMap = new HashMap<>();
if (label == null) {
labelsMap = ImmutableMap.of(
"jenkins/label", DEFAULT_LABEL,
"jenkins/label-digest", "0"
);
tempMap.put("jenkins/label", DEFAULT_LABEL);
tempMap.put("jenkins/label-digest", "0");
} else {
labelsMap = ImmutableMap.of(
"jenkins/label", sanitizeLabel(label),
"jenkins/label-digest", LABEL_DIGEST_FUNCTION.hashString(label).toString()
);
LABEL_DIGEST_FUNCTION.update(label.getBytes(StandardCharsets.UTF_8));
tempMap.put("jenkins/label", sanitizeLabel(label));
tempMap.put("jenkins/label-digest", String.format("%040x", new BigInteger(1, LABEL_DIGEST_FUNCTION.digest())));
}
labelsMap = Collections.unmodifiableMap(tempMap);
}

public String getLabel() {
Expand Down Expand Up @@ -516,7 +524,7 @@ public boolean isPrivileged() {
public void setRunAsUser(String runAsUser) {
this.runAsUser = PodTemplateUtils.parseLong(runAsUser);
}

public String getRunAsUser() {
return runAsUser == null ? null : runAsUser.toString();
}
Expand Down Expand Up @@ -781,7 +789,6 @@ public List<String> getYamls() {
return yamls;
}

@VisibleForTesting
@Restricted(NoExternalUse.class)
List<String> _getYamls() {
return yamls;
Expand Down Expand Up @@ -828,13 +835,13 @@ public void setTerminationGracePeriodSeconds(Long terminationGracePeriodSeconds)
this.terminationGracePeriodSeconds = terminationGracePeriodSeconds;
}

protected Object readResolve() throws NoSuchAlgorithmException {
protected Object readResolve() {
if (containers == null) {
// upgrading from 0.8
containers = new ArrayList<>();
ContainerTemplate containerTemplate = new ContainerTemplate(KubernetesCloud.JNLP_NAME, this.image);
containerTemplate.setCommand(command);
containerTemplate.setArgs(Strings.isNullOrEmpty(args) ? FALLBACK_ARGUMENTS : args);
containerTemplate.setArgs(PodTemplateUtils.isNullOrEmpty(args) ? FALLBACK_ARGUMENTS : args);
containerTemplate.setPrivileged(privileged);
containerTemplate.setRunAsUser(getRunAsUser());
containerTemplate.setRunAsGroup(getRunAsGroup());
Expand Down

0 comments on commit f4aa445

Please sign in to comment.