Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
rsandell authored Aug 23, 2022
2 parents 7cf5c2a + 08e21c6 commit e815fd6
Show file tree
Hide file tree
Showing 36 changed files with 798 additions and 174 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "weekly"
17 changes: 17 additions & 0 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Note: additional setup is required, see https://github.com/jenkinsci/.github/blob/master/.github/release-drafter.adoc

name: Release Drafter

on:
push:
branches:
- master

jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
# Drafts your next Release notes as Pull Requests are merged into the default branch
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .mvn/extensions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<extension>
<groupId>io.jenkins.tools.incrementals</groupId>
<artifactId>git-changelist-maven-extension</artifactId>
<version>1.0-beta-7</version>
<version>1.4</version>
</extension>
</extensions>
50 changes: 26 additions & 24 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.2</version>
<version>4.46</version>
<relativePath />
</parent>

Expand All @@ -32,12 +32,12 @@
</scm>

<properties>
<revision>1.18</revision>
<revision>1.20</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.222.4</jenkins.version>
<java.level>8</java.level>
<pipeline-model-definition-version>1.3.8</pipeline-model-definition-version>
<jcasc.version>1.41</jcasc.version>
<bom>2.263</bom>
<jenkins.version>2.263.1</jenkins.version>
<pipeline-model-definition.version>1.9.3</pipeline-model-definition.version>
<jcasc.version>1.51</jcasc.version>
</properties>

<repositories>
Expand Down Expand Up @@ -66,21 +66,15 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>authentication-tokens</artifactId>
<version>1.3</version>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-extensions</artifactId>
<version>${pipeline-model-definition-version}</version>
<version>${pipeline-model-definition.version}</version>
<!-- optional because the dependency subtree is quite large -->
<optional>true</optional>
</dependency>
<!-- TODO: remove after upgrading to Jenkins 2.171+ and migrating to f:secretTextarea -->
<dependency>
<groupId>io.jenkins.temp.jelly</groupId>
<artifactId>multiline-secrets-ui</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
Expand Down Expand Up @@ -148,7 +142,7 @@
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-definition</artifactId>
<version>${pipeline-model-definition-version}</version>
<version>${pipeline-model-definition.version}</version>
<scope>test</scope>
</dependency>
<!-- Dependencies for testing JCasC compatibility-->
Expand All @@ -164,23 +158,31 @@
<version>${jcasc.version}</version>
<scope>test</scope>
</dependency>
<!-- these dependencies are added to satisfy the enforcer rules -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.222.x</artifactId>
<version>11</version>
<artifactId>bom-${bom}.x</artifactId>
<version>984.vb5eaac999a7e</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-api</artifactId>
<version>${pipeline-model-definition.version}</version>
</dependency>
<dependency>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-stage-tags-metadata</artifactId>
<version>${pipeline-model-definition.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.model.Job;
import jenkins.model.Jenkins;

import javax.annotation.Nonnull;
import java.util.Collection;
Expand Down Expand Up @@ -58,13 +57,9 @@ public abstract class DockerImageExtractor implements ExtensionPoint {
*/
@Nonnull
public static Set<String> getDockerImagesUsedByJobFromAll(@Nonnull Job<?,?> job) {
Jenkins j = Jenkins.getInstance();
Set<String> names = new TreeSet<String>();
if (j != null) {
//TODO use ExtensionList.lookup(DockerImageExtractor.class); when core req is past 1.572 to not have to check for Jenkins instance
for (DockerImageExtractor extractor : j.getExtensionList(DockerImageExtractor.class)) {
names.addAll(extractor.getDockerImagesUsedByJob(job));
}
for (DockerImageExtractor extractor : ExtensionList.lookup(DockerImageExtractor.class)) {
names.addAll(extractor.getDockerImagesUsedByJob(job));
}
return names;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
import com.cloudbees.plugins.credentials.domains.HostnameRequirement;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.AbortException;
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.AbstractDescribableImpl;
Expand All @@ -41,17 +46,15 @@
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.remoting.VirtualChannel;
import hudson.slaves.WorkspaceList;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import jenkins.authentication.tokens.api.AuthenticationTokens;
import jenkins.model.Jenkins;

import org.jenkinsci.plugins.docker.commons.tools.DockerTool;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
Expand All @@ -62,12 +65,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.cloudbees.plugins.credentials.CredentialsMatchers.*;
import hudson.AbortException;
import hudson.EnvVars;
import hudson.Launcher;
import hudson.slaves.WorkspaceList;
import org.jenkinsci.plugins.docker.commons.tools.DockerTool;
import static com.cloudbees.plugins.credentials.CredentialsMatchers.allOf;
import static com.cloudbees.plugins.credentials.CredentialsMatchers.firstOrNull;
import static com.cloudbees.plugins.credentials.CredentialsMatchers.withId;
import static org.jenkinsci.plugins.docker.commons.credentials.ImageNameValidator.validateUserAndRepo;

/**
* Encapsulates the endpoint of DockerHub and how to interact with it.
Expand Down Expand Up @@ -139,7 +140,7 @@ public static DockerRegistryEndpoint fromImageName(String s, @CheckForNull Strin
/**
* Gets the endpoint URL, such as "https://index.docker.io/v1/"
*/
public @Nonnull URL getEffectiveUrl() throws IOException {
public @NonNull URL getEffectiveUrl() throws IOException {
if (url != null) {
return new URL(url);
} else {
Expand Down Expand Up @@ -227,7 +228,7 @@ public static DockerRegistryEndpoint fromImageName(String s, @CheckForNull Strin
* @deprecated Call {@link #newKeyMaterialFactory(Run, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(@Nonnull AbstractBuild build) throws IOException, InterruptedException {
public KeyMaterialFactory newKeyMaterialFactory(@NonNull AbstractBuild build) throws IOException, InterruptedException {
final FilePath workspace = build.getWorkspace();
if (workspace == null) {
throw new IllegalStateException("Requires workspace.");
Expand All @@ -239,15 +240,15 @@ public KeyMaterialFactory newKeyMaterialFactory(@Nonnull AbstractBuild build) th
* @deprecated Call {@link #newKeyMaterialFactory(Run, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(Item context, @Nonnull VirtualChannel target) throws IOException, InterruptedException {
public KeyMaterialFactory newKeyMaterialFactory(Item context, @NonNull VirtualChannel target) throws IOException, InterruptedException {
return newKeyMaterialFactory(context, target, null, TaskListener.NULL);
}

/**
* @deprecated Call {@link #newKeyMaterialFactory(Run, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @Nonnull VirtualChannel target, @CheckForNull Launcher launcher, @Nonnull TaskListener listener) throws IOException, InterruptedException {
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @NonNull VirtualChannel target, @CheckForNull Launcher launcher, @NonNull TaskListener listener) throws IOException, InterruptedException {
if (credentialsId == null) {
return KeyMaterialFactory.NULL; // nothing needed to be done
}
Expand All @@ -262,15 +263,15 @@ public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @Non
* @deprecated Call {@link #newKeyMaterialFactory(Run, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener, @Nonnull String dockerExecutable) throws IOException, InterruptedException {
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener listener, @NonNull String dockerExecutable) throws IOException, InterruptedException {
return newKeyMaterialFactory(context, workspace, launcher, new EnvVars(), listener, dockerExecutable);
}

/**
* @deprecated Call {@link #newKeyMaterialFactory(Run, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull EnvVars env, @Nonnull TaskListener listener, @Nonnull String dockerExecutable) throws IOException, InterruptedException {
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull EnvVars env, @NonNull TaskListener listener, @NonNull String dockerExecutable) throws IOException, InterruptedException {
if (credentialsId == null) {
return KeyMaterialFactory.NULL; // nothing needed to be done
}
Expand All @@ -288,7 +289,7 @@ public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Item context, @Non
* @param workspace a workspace being used for operations ({@link WorkspaceList#tempDir} will be applied)
* @param dockerExecutable as in {@link DockerTool#getExecutable}, with a 1.8+ client
*/
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Run context, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull EnvVars env, @Nonnull TaskListener listener, @Nonnull String dockerExecutable) throws IOException, InterruptedException {
public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Run context, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull EnvVars env, @NonNull TaskListener listener, @NonNull String dockerExecutable) throws IOException, InterruptedException {
if (credentialsId == null) {
return KeyMaterialFactory.NULL; // nothing needed to be done
}
Expand All @@ -308,10 +309,16 @@ public KeyMaterialFactory newKeyMaterialFactory(@CheckForNull Run context, @Nonn
* @return the full registry:port/namespace/name string
* @throws IOException
*/
public String imageName(@Nonnull String userAndRepo) throws IOException {
public String imageName(@NonNull String userAndRepo) throws IOException {
if (userAndRepo == null) {
throw new IllegalArgumentException("Image name cannot be null.");
}

final FormValidation validation = validateUserAndRepo(userAndRepo);
if (validation.kind != FormValidation.Kind.OK) {
throw validation;
}

if (url == null) {
return userAndRepo;
}
Expand Down Expand Up @@ -359,13 +366,14 @@ public boolean equals(Object obj) {

@Extension
public static class DescriptorImpl extends Descriptor<DockerRegistryEndpoint> {
@NonNull
@Override
public String getDisplayName() {
return "Docker Hub";
}

public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Item item) {
if (item == null && !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER) ||
if (item == null && !Jenkins.get().hasPermission(Jenkins.ADMINISTER) ||
item != null && !item.hasPermission(Item.EXTENDED_READ)) {
return new StandardListBoxModel();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
package org.jenkinsci.plugins.docker.commons.credentials;

import com.cloudbees.plugins.credentials.Credentials;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
Expand All @@ -35,10 +37,7 @@
import java.io.Serializable;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import jenkins.authentication.tokens.api.AuthenticationTokens;
import jenkins.security.MasterToSlaveCallable;
import net.sf.json.JSONObject;
Expand Down Expand Up @@ -75,15 +74,15 @@ public String getToken() {
* @deprecated use {@link #newKeyMaterialFactory(URL, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(final URL endpoint, @Nonnull VirtualChannel target) throws InterruptedException, IOException {
public KeyMaterialFactory newKeyMaterialFactory(final URL endpoint, @NonNull VirtualChannel target) throws InterruptedException, IOException {
return newKeyMaterialFactory(endpoint, target, null, TaskListener.NULL);
}

/**
* @deprecated use {@link #newKeyMaterialFactory(URL, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(@Nonnull URL endpoint, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener, @Nonnull String dockerExecutable) throws InterruptedException, IOException {
public KeyMaterialFactory newKeyMaterialFactory(@NonNull URL endpoint, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener listener, @NonNull String dockerExecutable) throws InterruptedException, IOException {
return newKeyMaterialFactory(endpoint, workspace, launcher, new EnvVars(), listener, dockerExecutable);
}

Expand All @@ -95,15 +94,20 @@ public KeyMaterialFactory newKeyMaterialFactory(@Nonnull URL endpoint, @Nonnull
* Sets up an environment logged in to the specified Docker registry.
* @param dockerExecutable as in {@link DockerTool#getExecutable}, with a 1.8+ client
*/
public KeyMaterialFactory newKeyMaterialFactory(@Nonnull URL endpoint, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull EnvVars env, @Nonnull TaskListener listener, @Nonnull String dockerExecutable) throws InterruptedException, IOException {
public KeyMaterialFactory newKeyMaterialFactory(@NonNull URL endpoint, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull EnvVars env, @NonNull TaskListener listener, @NonNull String dockerExecutable) throws InterruptedException, IOException {
if (!USE_CUSTOM_LOGIN) {
try {
// see UsernamePasswordDockerRegistryTokenSource for example
String usernameColonPassword = new String(Base64.getDecoder().decode(token), StandardCharsets.UTF_8);
int colon = usernameColonPassword.indexOf(':');
if (colon > 0) {
return new RegistryKeyMaterialFactory(usernameColonPassword.substring(0, colon), usernameColonPassword.substring(colon + 1), endpoint, launcher, env, listener, dockerExecutable).
contextualize(new KeyMaterialContext(WorkspaceList.tempDir(workspace)));
FilePath tempDir = WorkspaceList.tempDir(workspace);
if (tempDir != null) {
return new RegistryKeyMaterialFactory(usernameColonPassword.substring(0, colon), usernameColonPassword.substring(colon + 1), endpoint, launcher, env, listener, dockerExecutable).
contextualize(new KeyMaterialContext(tempDir));
} else {
listener.getLogger().println("Failed to create temporary directory for docker login");
}
}
} catch (IllegalArgumentException x) {
// not Base64-encoded
Expand All @@ -121,7 +125,7 @@ public KeyMaterialFactory newKeyMaterialFactory(@Nonnull URL endpoint, @Nonnull
* @deprecated use {@link #newKeyMaterialFactory(URL, FilePath, Launcher, EnvVars, TaskListener, String)}
*/
@Deprecated
public KeyMaterialFactory newKeyMaterialFactory(final @Nonnull URL endpoint, @Nonnull VirtualChannel target, @CheckForNull Launcher launcher, final @Nonnull TaskListener listener) throws InterruptedException, IOException {
public KeyMaterialFactory newKeyMaterialFactory(final @NonNull URL endpoint, @NonNull VirtualChannel target, @CheckForNull Launcher launcher, final @NonNull TaskListener listener) throws InterruptedException, IOException {
target.call(new MasterToSlaveCallable<Void, IOException>() {
/**
* Insert the token into {@code ~/.dockercfg}
Expand Down
Loading

0 comments on commit e815fd6

Please sign in to comment.