提交 1d8af331 编写于 作者: J Jesse Glick

Merge branch 'master' into mirror-INFRA-1176

......@@ -12,7 +12,9 @@ import java.util.List;
* {@link CLICommand} that acts on a series of {@link AbstractBuild}s.
*
* @author Kohsuke Kawaguchi
* @deprecated rather use {@link RunRangeCommand}
*/
@Deprecated
public abstract class AbstractBuildRangeCommand extends CLICommand {
@Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0)
public AbstractProject<?,?> job;
......
......@@ -25,7 +25,6 @@ package hudson.cli;
import hudson.Util;
import hudson.console.ModelHyperlinkNote;
import hudson.model.AbstractProject;
import hudson.model.Cause.UserIdCause;
import hudson.model.CauseAction;
import hudson.model.Job;
......
......@@ -2,10 +2,10 @@ package hudson.cli;
import hudson.Extension;
import hudson.console.AnnotatedLargeText;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Item;
import hudson.model.Job;
import hudson.model.PermalinkProjectAction.Permalink;
import hudson.model.Run;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
......@@ -29,7 +29,7 @@ public class ConsoleCommand extends CLICommand {
}
@Argument(metaVar="JOB",usage="Name of the job",required=true)
public AbstractProject<?,?> job;
public Job<?,?> job;
@Argument(metaVar="BUILD",usage="Build number or permalink to point to the build. Defaults to the last build",required=false,index=1)
public String build="lastBuild";
......@@ -43,7 +43,7 @@ public class ConsoleCommand extends CLICommand {
protected int run() throws Exception {
job.checkPermission(Item.BUILD);
AbstractBuild<?,?> run;
Run<?,?> run;
try {
int n = Integer.parseInt(build);
......@@ -54,7 +54,7 @@ public class ConsoleCommand extends CLICommand {
// maybe a permalink?
Permalink p = job.getPermalinks().get(build);
if (p!=null) {
run = (AbstractBuild)p.resolve(job);
run = p.resolve(job);
if (run==null)
throw new IllegalStateException("Permalink "+build+" produced no build");
} else {
......@@ -94,7 +94,7 @@ public class ConsoleCommand extends CLICommand {
/**
* Find the byte offset in the log input stream that marks "last N lines".
*/
private long seek(AbstractBuild<?, ?> run) throws IOException {
private long seek(Run<?, ?> run) throws IOException {
class RingBuffer {
long[] lastNlines = new long[n];
int ptr=0;
......
......@@ -24,21 +24,23 @@
package hudson.cli;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.Run;
import java.io.IOException;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.List;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
/**
* Deletes builds records in a bulk.
*
* @author Kohsuke Kawaguchi
*/
@Restricted(DoNotUse.class) // command implementation only
@Extension
public class DeleteBuildsCommand extends AbstractBuildRangeCommand {
public class DeleteBuildsCommand extends RunRangeCommand {
@Override
public String getShortDescription() {
return Messages.DeleteBuildsCommand_ShortDescription();
......@@ -52,12 +54,12 @@ public class DeleteBuildsCommand extends AbstractBuildRangeCommand {
}
@Override
protected int act(List<AbstractBuild<?, ?>> builds) throws IOException {
protected int act(List<Run<?, ?>> builds) throws IOException {
job.checkPermission(Run.DELETE);
final HashSet<Integer> hsBuilds = new HashSet<Integer>();
for (AbstractBuild build : builds) {
for (Run<?, ?> build : builds) {
if (!hsBuilds.contains(build.number)) {
build.delete();
hsBuilds.add(build.number);
......
package hudson.cli;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.Run;
import hudson.scm.ChangeLogSet;
import hudson.scm.ChangeLogSet.Entry;
import hudson.util.QuotedStringTokenizer;
import jenkins.scm.RunWithSCM;
import org.kohsuke.args4j.Option;
import org.kohsuke.stapler.export.Flavor;
import org.kohsuke.stapler.export.Model;
......@@ -13,14 +14,17 @@ import org.kohsuke.stapler.export.ModelBuilder;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
/**
* Retrieves a change list for the specified builds.
*
* @author Kohsuke Kawaguchi
*/
@Restricted(DoNotUse.class) // command implementation only
@Extension
public class ListChangesCommand extends AbstractBuildRangeCommand {
public class ListChangesCommand extends RunRangeCommand {
@Override
public String getShortDescription() {
return Messages.ListChangesCommand_ShortDescription();
......@@ -39,40 +43,50 @@ public class ListChangesCommand extends AbstractBuildRangeCommand {
public Format format = Format.PLAIN;
@Override
protected int act(List<AbstractBuild<?, ?>> builds) throws IOException {
protected int act(List<Run<?, ?>> builds) throws IOException {
// Loading job for this CLI command requires Item.READ permission.
// No other permission check needed.
switch (format) {
case XML:
PrintWriter w = new PrintWriter(stdout);
w.println("<changes>");
for (AbstractBuild build : builds) {
w.println("<build number='"+build.getNumber()+"'>");
ChangeLogSet<?> cs = build.getChangeSet();
Model p = new ModelBuilder().get(cs.getClass());
p.writeTo(cs,Flavor.XML.createDataWriter(cs,w));
w.println("</build>");
for (Run<?, ?> build : builds) {
if (build instanceof RunWithSCM) {
w.println("<build number='" + build.getNumber() + "'>");
for (ChangeLogSet<?> cs : ((RunWithSCM<?, ?>) build).getChangeSets()) {
Model p = new ModelBuilder().get(cs.getClass());
p.writeTo(cs, Flavor.XML.createDataWriter(cs, w));
}
w.println("</build>");
}
}
w.println("</changes>");
w.flush();
break;
case CSV:
for (AbstractBuild build : builds) {
ChangeLogSet<?> cs = build.getChangeSet();
for (Entry e : cs) {
stdout.printf("%s,%s%n",
QuotedStringTokenizer.quote(e.getAuthor().getId()),
QuotedStringTokenizer.quote(e.getMsg()));
for (Run<?, ?> build : builds) {
if (build instanceof RunWithSCM) {
for (ChangeLogSet<?> cs : ((RunWithSCM<?, ?>) build).getChangeSets()) {
for (Entry e : cs) {
stdout.printf("%s,%s%n",
QuotedStringTokenizer.quote(e.getAuthor().getId()),
QuotedStringTokenizer.quote(e.getMsg()));
}
}
}
}
break;
case PLAIN:
for (AbstractBuild build : builds) {
ChangeLogSet<?> cs = build.getChangeSet();
for (Entry e : cs) {
stdout.printf("%s\t%s%n",e.getAuthor(),e.getMsg());
for (String p : e.getAffectedPaths())
stdout.println(" "+p);
for (Run<?, ?> build : builds) {
if (build instanceof RunWithSCM) {
for (ChangeLogSet<?> cs : ((RunWithSCM<?, ?>) build).getChangeSets()) {
for (Entry e : cs) {
stdout.printf("%s\t%s%n", e.getAuthor(), e.getMsg());
for (String p : e.getAffectedPaths()) {
stdout.println(" " + p);
}
}
}
}
}
break;
......
......@@ -29,6 +29,8 @@ import hudson.model.AbstractItem;
import hudson.model.AbstractProject;
import hudson.model.Item;
import hudson.model.Items;
import hudson.model.TopLevelItem;
import jenkins.model.Jenkins;
import org.kohsuke.args4j.Argument;
......@@ -69,7 +71,6 @@ public class ReloadJobCommand extends CLICommand {
AbstractItem job = null;
try {
// TODO: JENKINS-30786
Item item = jenkins.getItemByFullName(job_s);
if (item instanceof AbstractItem) {
job = (AbstractItem) item;
......@@ -78,11 +79,10 @@ public class ReloadJobCommand extends CLICommand {
}
if(job == null) {
// TODO: JENKINS-30785
AbstractProject project = AbstractProject.findNearest(job_s);
AbstractItem project = Items.findNearest(AbstractItem.class, job_s, jenkins);
throw new IllegalArgumentException(project == null ?
"No such job \u2018" + job_s + "\u2019 exists." :
String.format("No such job \u2018%s\u2019 exists. Perhaps you meant \u2018%s\u2019?",
"No such item \u2018" + job_s + "\u2019 exists." :
String.format("No such item \u2018%s\u2019 exists. Perhaps you meant \u2018%s\u2019?",
job_s, project.getFullName()));
}
......
package hudson.cli;
import hudson.model.Fingerprint.RangeSet;
import hudson.model.Job;
import hudson.model.Run;
import org.kohsuke.args4j.Argument;
import java.io.IOException;
import java.util.List;
/**
* {@link CLICommand} that acts on a series of {@link Run}s.
* @since FIXME
*/
public abstract class RunRangeCommand extends CLICommand {
@Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0)
public Job<?,?> job;
@Argument(metaVar="RANGE",usage="Range of the build records to delete. 'N-M', 'N,M', or 'N'",required=true,index=1)
public String range;
protected int run() throws Exception {
RangeSet rs = RangeSet.fromString(range,false);
return act((List)job.getBuilds(rs));
}
protected abstract int act(List<Run<?,?>> builds) throws IOException;
}
package hudson.cli;
import hudson.Extension;
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.Run;
import java.io.Serializable;
......@@ -18,7 +18,7 @@ public class SetBuildDescriptionCommand extends CLICommand implements Serializab
}
@Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0)
public transient AbstractProject<?,?> job;
public transient Job<?,?> job;
@Argument(metaVar="BUILD#",usage="Number of the build",required=true,index=1)
public int number;
......
package hudson.cli;
import hudson.Extension;
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.Run;
import org.apache.commons.io.IOUtils;
import org.kohsuke.args4j.Argument;
......@@ -18,7 +18,7 @@ public class SetBuildDisplayNameCommand extends CLICommand implements Serializab
}
@Argument(metaVar="JOB", usage="Name of the job to build", required=true, index=0)
public transient AbstractProject<?, ?> job;
public transient Job<?, ?> job;
@Argument(metaVar="BUILD#", usage="Number of the build", required=true, index=1)
public int number;
......
......@@ -850,11 +850,11 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
*/
@CLIResolver
public static AbstractItem resolveForCLI(
@Argument(required=true,metaVar="NAME",usage="Job name") String name) throws CmdLineException {
@Argument(required=true,metaVar="NAME",usage="Item name") String name) throws CmdLineException {
// TODO can this (and its pseudo-override in AbstractProject) share code with GenericItemOptionHandler, used for explicit CLICommand’s rather than CLIMethod’s?
AbstractItem item = Jenkins.getInstance().getItemByFullName(name, AbstractItem.class);
if (item==null) {
AbstractProject project = AbstractProject.findNearest(name); // TODO should be Items.findNearest
AbstractItem project = Items.findNearest(AbstractItem.class, name, Jenkins.getInstance());
throw new CmdLineException(null, project == null ? Messages.AbstractItem_NoSuchJobExistsWithoutSuggestion(name)
: Messages.AbstractItem_NoSuchJobExists(name, project.getFullName()));
}
......
......@@ -64,11 +64,14 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import static hudson.model.queue.Executables.*;
import hudson.security.ACLContext;
import java.util.Collection;
import static java.util.logging.Level.*;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import jenkins.model.queue.AsynchronousExecution;
import jenkins.security.QueueItemAuthenticatorConfiguration;
import jenkins.security.QueueItemAuthenticatorDescriptor;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
......@@ -398,11 +401,21 @@ public class Executor extends Thread implements ModelObject {
}
}
ACL.impersonate(workUnit.context.item.authenticate());
setName(getName() + " : executing " + executable.toString());
if (LOGGER.isLoggable(FINE))
LOGGER.log(FINE, getName()+" is now executing "+executable);
queue.execute(executable, task);
Authentication auth = workUnit.context.item.authenticate();
LOGGER.log(FINE, "{0} is now executing {1} as {2}", new Object[] {getName(), executable, auth});
if (LOGGER.isLoggable(FINE) && auth.equals(ACL.SYSTEM)) { // i.e., unspecified
if (QueueItemAuthenticatorDescriptor.all().isEmpty()) {
LOGGER.fine("no QueueItemAuthenticator implementations installed");
} else if (QueueItemAuthenticatorConfiguration.get().getAuthenticators().isEmpty()) {
LOGGER.fine("no QueueItemAuthenticator implementations configured");
} else {
LOGGER.log(FINE, "some QueueItemAuthenticator implementations configured but neglected to authenticate {0}", executable);
}
}
try (ACLContext context = ACL.as(auth)) {
queue.execute(executable, task);
}
} catch (AsynchronousExecution x) {
lock.writeLock().lock();
try {
......
......@@ -34,9 +34,7 @@ import java.util.Collection;
import java.util.Collections;
import javax.annotation.Nonnull;
import jenkins.security.QueueItemAuthenticator;
import jenkins.security.QueueItemAuthenticatorConfiguration;
import static hudson.model.queue.Executables.getParentOf;
import jenkins.security.QueueItemAuthenticatorProvider;
/**
* Convenience methods around {@link Task} and {@link SubTask}.
......@@ -136,7 +134,7 @@ public class Tasks {
* @since 1.560
*/
public static @Nonnull Authentication getAuthenticationOf(@Nonnull Task t) {
for (QueueItemAuthenticator qia : QueueItemAuthenticatorConfiguration.get().getAuthenticators()) {
for (QueueItemAuthenticator qia : QueueItemAuthenticatorProvider.authenticators()) {
Authentication a = qia.authenticate(t);
if (a != null) {
return a;
......
......@@ -63,13 +63,9 @@ import javax.annotation.Nonnull;
import jenkins.model.DependencyDeclarer;
import jenkins.model.Jenkins;
import jenkins.model.ParameterizedJobMixIn;
import jenkins.security.QueueItemAuthenticatorConfiguration;
import jenkins.security.QueueItemAuthenticatorDescriptor;
import jenkins.triggers.ReverseBuildTrigger;
import net.sf.json.JSONObject;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.AncestorInPath;
......@@ -270,53 +266,24 @@ public class BuildTrigger extends Recorder implements DependencyDeclarer {
}
});
Authentication auth = Jenkins.getAuthentication(); // from build
if (auth.equals(ACL.SYSTEM)) { // i.e., unspecified
if (QueueItemAuthenticatorDescriptor.all().isEmpty()) {
if (downstreamProjects.isEmpty()) {
return true;
}
logger.println(Messages.BuildTrigger_warning_you_have_no_plugins_providing_ac());
} else if (QueueItemAuthenticatorConfiguration.get().getAuthenticators().isEmpty()) {
if (downstreamProjects.isEmpty()) {
return true;
}
logger.println(Messages.BuildTrigger_warning_access_control_for_builds_in_glo());
} else {
// This warning must be printed even if downstreamProjects is empty.
// Otherwise you could effectively escalate DISCOVER to READ just by trying different project names and checking whether a warning was printed or not.
// If there were an API to determine whether any DependencyDeclarer’s in this project requested downstream project names,
// then we could suppress the warnings in case none did; but if any do, yet Items.fromNameList etc. ignore unknown projects,
// that has to be treated the same as if there really are downstream projects but the anonymous user cannot see them.
// For the above two cases, it is OK to suppress the warning when there are no downstream projects, since running as SYSTEM we would be able to see them anyway.
logger.println(Messages.BuildTrigger_warning_this_build_has_no_associated_aut());
auth = Jenkins.ANONYMOUS;
}
}
for (Dependency dep : downstreamProjects) {
List<Action> buildActions = new ArrayList<Action>();
SecurityContext orig = ACL.impersonate(auth);
try {
if (dep.shouldTriggerBuild(build, listener, buildActions)) {
AbstractProject p = dep.getDownstreamProject();
// Allow shouldTriggerBuild to return false first, in case it is skipping because of a lack of Item.READ/DISCOVER permission:
if (p.isDisabled()) {
logger.println(Messages.BuildTrigger_Disabled(ModelHyperlinkNote.encodeTo(p)));
continue;
}
boolean scheduled = p.scheduleBuild(p.getQuietPeriod(), new UpstreamCause((Run)build), buildActions.toArray(new Action[buildActions.size()]));
if (Jenkins.getInstance().getItemByFullName(p.getFullName()) == p) {
String name = ModelHyperlinkNote.encodeTo(p);
if (scheduled) {
logger.println(Messages.BuildTrigger_Triggering(name));
} else {
logger.println(Messages.BuildTrigger_InQueue(name));
}
} // otherwise upstream users should not know that it happened
if (dep.shouldTriggerBuild(build, listener, buildActions)) {
AbstractProject p = dep.getDownstreamProject();
// Allow shouldTriggerBuild to return false first, in case it is skipping because of a lack of Item.READ/DISCOVER permission:
if (p.isDisabled()) {
logger.println(Messages.BuildTrigger_Disabled(ModelHyperlinkNote.encodeTo(p)));
continue;
}
} finally {
SecurityContextHolder.setContext(orig);
boolean scheduled = p.scheduleBuild(p.getQuietPeriod(), new UpstreamCause((Run)build), buildActions.toArray(new Action[buildActions.size()]));
if (Jenkins.getInstance().getItemByFullName(p.getFullName()) == p) {
String name = ModelHyperlinkNote.encodeTo(p);
if (scheduled) {
logger.println(Messages.BuildTrigger_Triggering(name));
} else {
logger.println(Messages.BuildTrigger_InQueue(name));
}
} // otherwise upstream users should not know that it happened
}
}
......@@ -443,9 +410,6 @@ public class BuildTrigger extends Recorder implements DependencyDeclarer {
return FormValidation.error(Messages.BuildTrigger_NotBuildable(projectName));
// check whether the supposed user is expected to be able to build
Authentication auth = Tasks.getAuthenticationOf(project);
if (auth.equals(ACL.SYSTEM) && !QueueItemAuthenticatorConfiguration.get().getAuthenticators().isEmpty()) {
auth = Jenkins.ANONYMOUS; // compare behavior in execute, above
}
if (!item.getACL().hasPermission(auth, Item.BUILD)) {
return FormValidation.error(Messages.BuildTrigger_you_have_no_permission_to_build_(projectName));
}
......
......@@ -9,6 +9,7 @@ import hudson.model.CauseAction;
import hudson.model.Queue;
import hudson.model.Queue.Item;
import hudson.model.Queue.Task;
import hudson.model.queue.Tasks;
import java.util.Calendar;
import java.util.Collections;
import javax.annotation.CheckForNull;
......@@ -20,8 +21,9 @@ import org.acegisecurity.Authentication;
* @author Kohsuke Kawaguchi
* @since 1.520
* @see QueueItemAuthenticatorConfiguration
* @see QueueItemAuthenticatorProvider
* @see Item#authenticate()
* @see Task#getDefaultAuthentication()
* @see Tasks#getAuthenticationOf
*/
public abstract class QueueItemAuthenticator extends AbstractDescribableImpl<QueueItemAuthenticator> implements ExtensionPoint {
/**
......
package jenkins.security;
import hudson.Extension;
import hudson.model.queue.Tasks;
import hudson.util.DescribableList;
import jenkins.model.GlobalConfiguration;
import jenkins.model.GlobalConfigurationCategory;
......@@ -38,6 +39,14 @@ public class QueueItemAuthenticatorConfiguration extends GlobalConfiguration {
return GlobalConfigurationCategory.get(GlobalConfigurationCategory.Security.class);
}
/**
* Provides all user-configured authenticators.
* Note that if you are looking to determine all <em>effective</em> authenticators,
* including any potentially supplied by plugins rather than user configuration,
* you should rather call {@link QueueItemAuthenticatorProvider#authenticators};
* or if you are looking for the authentication of an actual project, build, etc., use
* {@link hudson.model.Queue.Item#authenticate} or {@link Tasks#getAuthenticationOf}.
*/
public DescribableList<QueueItemAuthenticator, QueueItemAuthenticatorDescriptor> getAuthenticators() {
return authenticators;
}
......
......@@ -65,7 +65,6 @@ import java.util.logging.Logger;
import jenkins.model.DependencyDeclarer;
import jenkins.model.Jenkins;
import jenkins.model.ParameterizedJobMixIn;
import jenkins.security.QueueItemAuthenticatorConfiguration;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
......@@ -128,9 +127,6 @@ public final class ReverseBuildTrigger extends Trigger<Job> implements Dependenc
Authentication originalAuth = Jenkins.getAuthentication();
Job upstream = upstreamBuild.getParent();
Authentication auth = Tasks.getAuthenticationOf((Queue.Task) job);
if (auth.equals(ACL.SYSTEM) && !QueueItemAuthenticatorConfiguration.get().getAuthenticators().isEmpty()) {
auth = Jenkins.ANONYMOUS; // cf. BuildTrigger
}
SecurityContext orig = ACL.impersonate(auth);
Item authUpstream = null;
......
......@@ -50,9 +50,6 @@ BuildTrigger.NoProjectSpecified=No project specified
BuildTrigger.NotBuildable={0} is not buildable
BuildTrigger.Triggering=Triggering a new build of {0}
BuildTrigger.ok_ancestor_is_null=Ancestor/Context Unknown: the project specified cannot be validated
BuildTrigger.warning_access_control_for_builds_in_glo=Warning: \u2018Access Control for Builds\u2019 in global security configuration is empty, so falling back to legacy behavior of permitting any downstream builds to be triggered
BuildTrigger.warning_this_build_has_no_associated_aut=Warning: this build has no associated authentication, so build permissions may be lacking, and downstream projects which cannot even be seen by an anonymous user will be silently skipped
BuildTrigger.warning_you_have_no_plugins_providing_ac=Warning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggered
BuildTrigger.you_have_no_permission_to_build_=You have no permission to build {0}
CommandInterpreter.CommandFailed=command execution failed
......@@ -84,4 +81,4 @@ Maven.NoExecutable=Couldn\u2019t find any executable in {0}
Shell.DisplayName=Execute shell
Shell.invalid_exit_code_range=Invalid exit code value: {0}. Check help section
Shell.invalid_exit_code_zero=Exit code zero is ignored and does not make the build unstable
\ No newline at end of file
Shell.invalid_exit_code_zero=Exit code zero is ignored and does not make the build unstable
......@@ -67,18 +67,6 @@ BuildTrigger.NotBuildable=\
\u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438
BuildTrigger.Triggering=\
\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c
BuildTrigger.warning_access_control_for_builds_in_glo=\
\u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u041f\u043e\u043b\u0435\u0442\u043e \u201e\u041f\u0440\u0430\u0432\u0430 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430\u201c \u0432 \u043e\u0431\u0449\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\
\u0437\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430 \u043d\u0435 \u0435 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u043e. \u0429\u0435 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u0441\u0442\u0430\u0440\u044f\u043b\u043e\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0430\
\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438, \u0437\u0430\u0432\u0438\u0441\u0435\u0449\u0438 \u043e\u0442 \u0442\u0430\u0437\u0438
BuildTrigger.warning_this_build_has_no_associated_aut=\
\u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u043b\u0438\u043f\u0441\u0432\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0437\u0430 \u0442\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0437\u0430\u0442\u043e\u0432\u0430 \u0438 \u043f\u0440\u0430\u0432\u0430\u0442\u0430 \u043a\u044a\u043c\
\u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0430 \u043f\u044a\u043b\u043d\u0438. \u0417\u0430\u0432\u0438\u0441\u0435\u0449\u0438\u0442\u0435 \u043e\u0442 \u0442\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438, \u043a\u043e\u0438\u0442\u043e\
\u043d\u0435 \u0441\u0435 \u0432\u0438\u0436\u0434\u0430\u0442 \u043e\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u043d\u0430\u0442\u0438.
BuildTrigger.warning_you_have_no_plugins_providing_ac=\
\u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u043b\u0438\u043f\u0441\u0432\u0430\u0442 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043f\u0440\u0430\u0432\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. \u0429\u0435\
\u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u0441\u0442\u0430\u0440\u044f\u043b\u043e\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438\
\u0437\u0430\u0434\u0430\u0447\u0438, \u0437\u0430\u0432\u0438\u0441\u0435\u0449\u0438 \u043e\u0442 \u0442\u0430\u0437\u0438
BuildTrigger.you_have_no_permission_to_build_=\
\u041d\u044f\u043c\u0430\u0442\u0435 \u043f\u0440\u0430\u0432\u0430 \u0434\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0435 \u201e{0}\u201c
......
......@@ -48,9 +48,6 @@ BuildTrigger.NotBuildable={0} kann nicht gebaut werden.
BuildTrigger.Triggering=L\u00F6se einen neuen Build von {0} aus
BuildTrigger.you_have_no_permission_to_build_=Sie haben nicht die Berechtigung, Builds von {0} zu starten.
BuildTrigger.ok_ancestor_is_null=Der angegebene Projektname kann im aktuellen Kontext nicht gepr\u00FCft werden.
BuildTrigger.warning_access_control_for_builds_in_glo=Achtung: Die Zugriffskontrolle von Builds ist in der globalen Sicherheitskonfiguration nicht konfiguriert, daher wird erlaubt, beliebige Downstream-Builds zu starten.
BuildTrigger.warning_you_have_no_plugins_providing_ac=Achtung: Keine Plugins f\u00FCr die Zugriffskontrolle von Builds sind installiert, daher wird erlaubt, beliebige Downstream-Builds zu starten.
BuildTrigger.warning_this_build_has_no_associated_aut=Achtung: Dieser Build hat keine zugeordnete Authentifizierung, daher k\u00F6nnen Berechtigungen fehlen und Downstream-Builds ggf. nicht gestartet werden, wenn anonyme Nutzer auf diese keinen Zugriff haben.
CommandInterpreter.CommandFailed=Befehlsausf\u00FChrung fehlgeschlagen
CommandInterpreter.UnableToDelete=Kann Skriptdatei {0} nicht l\u00F6schen
......
......@@ -78,11 +78,5 @@ JavadocArchiver.NoMatchFound=Nenhum javadoc encontrado {0}: {1}
ArtifactArchiver.SkipBecauseOnlyIfSuccessful=Arquivamento ignorado devido ao t\u00e9rmino do build sem sucesso
# No project specified
BuildTrigger.NoProjectSpecified=Nenhum projeto especificado
# Warning: \u2018Access Control for Builds\u2019 in global security configuration is empty, so falling back to legacy behavior of permitting any downstream builds to be triggered
BuildTrigger.warning_access_control_for_builds_in_glo=Aten\u00e7\u00e3o: o \u2018Controle de acesso para Builds\u2019 nas configura\u00e7\u00f5es de seguran\u00e7a globais est\u00e1 vazio, portanto retornando para o comportamento legado de permitir que quaisquer builds decendentes sejam disparados
# Warning: this build has no associated authentication, so build permissions may be lacking, and downstream projects which cannot even be seen by an anonymous user will be silently skipped
BuildTrigger.warning_this_build_has_no_associated_aut=Aten\u00e7\u00e3o: este build n\u00e3o possui authentica\u00e7\u00e3o associada, portanto permiss\u1ebds de build podem estar faltando, e projetos descendentes que n\u00e3o podem sequer ser vistos por um usu\u00e1rio an\u00f4nimo ser\u00e3o ignorados silenciosamente
# Warning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggered
BuildTrigger.warning_you_have_no_plugins_providing_ac=Aten\u00e7\u00e3o: voc\u00ea n\u00e3o possui plugins fornecendo controle de accesso para builds, portanto retornando para o comportamento legado de permitir que quaisquer builds descendentes sejam disparados
# You have no permission to build {0}
BuildTrigger.you_have_no_permission_to_build_=Voc\u00ea n\u00e3o tem permiss\u00e3o para construir {0}
......@@ -24,8 +24,6 @@ BuildTrigger.NoProjectSpecified=\u041D\u0438\u0458\u0435 \u043D\u0430\u0432\u043
BuildTrigger.NotBuildable={0} \u043D\u0435\u043C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0438
BuildTrigger.Triggering=\u041F\u043E\u0447\u0438\u045A\u0435 \u043D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0437\u0430 {0}
BuildTrigger.ok_ancestor_is_null=\u041D\u0435\u043F\u043E\u0437\u043D\u0430\u0442 \u0440\u043E\u0434\u0438\u0442\u0435\u043B/\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442: \u043D\u0430\u0432\u0435\u0434\u0435\u043D \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043F\u0440\u043E\u0432\u0435\u0440\u0435\u043D
BuildTrigger.warning_access_control_for_builds_in_glo=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043F\u043E\u0459\u0435 '\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0430' \u0443 \u043E\u043F\u0448\u0442\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0438\u043C\u0430 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442\u0438 \u043D\u0438\u0458\u0435 \u0438\u0441\u043F\u0443\u045A\u0435\u043Do. \u041A\u043E\u0440\u0438\u0441\u0442\u0438\u045B\u0435 \u0441\u0435 \u0441\u0442\u0430\u0440\u043E \u043F\u043E\u043D\u0430\u0448\u0430\u045A\u0435 \u043A\u043E\u0458\u0435 \u0434\u043E\u0437\u0432\u043E\u0459\u0430\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0441\u0432\u0438\u0445 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 \u043A\u043E\u0458\u0435 \u0437\u0430\u0432\u0438\u0441\u0435 \u043E\u0434 \u043E\u0432\u0435.
BuildTrigger.warning_this_build_has_no_associated_aut=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u043C\u0430 \u043A\u0430\u043D\u0430\u043B \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0435, \u043F\u0430 \u045B\u0435 \u0434\u043E\u0437\u0432\u043E\u043B\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u0458\u0430\u0442\u0438 \u0438 \u043E\u043D\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \u043A\u043E\u0458\u0438 \u0437\u0430\u0432\u0438\u0441\u0435 \u043E\u0434 \u043E\u0432\u0435 \u0430 \u043D\u0438\u0441\u0443 \u0432\u0438\u0434\u0459\u0438\u0432\u0438 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438\u043C \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430, \u045B\u0435 \u0431\u0438\u0442\u0438 \u043F\u0440\u0435\u0441\u043A\u043E\u045B\u0435\u043D\u0438.
BuildTrigger.you_have_no_permission_to_build_=\u041D\u0435\u043C\u0430\u0442\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0435 {0}
CommandInterpreter.CommandFailed=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E
CommandInterpreter.UnableToDelete=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u0442\u0438 \u0441\u043A\u0440\u0438\u043F\u0442 {0}
......@@ -34,7 +32,6 @@ Fingerprinter.Aborted=\u041F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u043E
Fingerprinter.Action.DisplayName=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0445 \u043E\u0442\u0438\u0441\u0430\u043A\u0430
Fingerprinter.DigestFailed=\u041D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E \u043E\u0431\u0440\u0430\u0447\u0443\u043D \u043D\u0430 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u043E\u043C \u043E\u0442\u0438\u0441\u043A\u0443 {0}
Fingerprinter.DisplayName=\u0421\u043D\u0438\u043C\u0438 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0435 \u043E\u0442\u0438\u0441\u043A\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0434\u0430 \u043F\u0440\u0430\u0442\u0438\u0442\u0435 \u045A\u0438\u0445\u043E\u0432\u0443 \u0443\u043F\u043E\u0442\u0435\u0431\u0440\u0443
BuildTrigger.warning_you_have_no_plugins_providing_ac=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043D\u0435\u043C\u0430\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043A\u043E\u0458\u0435 \u0434\u0435\u043B\u0435 \u043F\u0440\u0438\u0441\u0442\u0443\u043F, \u043F\u0430 \u0441\u0435 \u0432\u0440\u0430\u045B\u0430 \u043D\u0430\u0437\u0430\u0434 \u043D\u0430 \u0440\u0435\u0436\u0438\u043C \u043A\u043E\u0458\u0438 \u0438\u0437\u0430\u0437\u0438\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0438\u0437\u0432\u0438\u0441\u043D\u0438\u0445 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430.
Fingerprinter.Failed=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u043D\u0438\u043C\u0430\u045A\u0435 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0445 \u043E\u0442\u0438\u0441\u043A\u0430
Fingerprinter.FailedFor=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u043D\u0438\u043C\u0430\u045A\u0435 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0443 \u043E\u0442\u0438\u0441\u043A\u0443 \u0437\u0430 {0}
Fingerprinter.Recording=\u0421\u043D\u0438\u043C\u0430\u045A\u0435 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0445 \u043E\u0442\u0438\u0441\u043A\u0430
......@@ -52,4 +49,4 @@ Maven.NotMavenDirectory={0} \u043D\u0435 \u043B\u0438\u0447\u0438 \u043D\u0430 M
Maven.NoExecutable=\u041D\u0438\u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u043E \u0438\u0437\u0432\u0440\u0448\u043D\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0443 {0}
Shell.DisplayName=\u0418\u0437\u0432\u0440\u0448\u0438 shell \u043A\u043E\u043C\u0430\u043D\u0434\u0443
Maven.NotADirectory={0} \u043D\u0438\u0458\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C
Indien=
\ No newline at end of file
Indien=
......@@ -91,7 +91,7 @@ public class ReloadJobCommandTest {
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: No such job \u2018aProject\u2019 exists."));
assertThat(result.stderr(), containsString("ERROR: No such item ‘aProject’ exists."));
assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1"));
}
......@@ -121,7 +121,7 @@ public class ReloadJobCommandTest {
.invokeWithArgs("never_created");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: No such job \u2018never_created\u2019 exists."));
assertThat(result.stderr(), containsString("ERROR: No such item ‘never_created’ exists."));
}
@Test public void reloadJobShouldFailIfJobDoesNotExistButNearExists() throws Exception {
......@@ -133,7 +133,7 @@ public class ReloadJobCommandTest {
.invokeWithArgs("never_created1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: No such job \u2018never_created1\u2019 exists. Perhaps you meant \u2018never_created\u2019?"));
assertThat(result.stderr(), containsString("ERROR: No such item ‘never_created1’ exists. Perhaps you meant ‘never_created’?"));
}
@Test public void reloadJobManyShouldSucceed() throws Exception {
......@@ -182,7 +182,7 @@ public class ReloadJobCommandTest {
assertThat(result, failedWith(5));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("never_created: No such job \u2018never_created\u2019 exists."));
assertThat(result.stderr(), containsString("never_created: No such item ‘never_created’ exists."));
assertThat(result.stderr(), containsString("ERROR: " + CLICommand.CLI_LISTPARAM_SUMMARY_ERROR_TEXT));
assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 2"));
......@@ -208,7 +208,7 @@ public class ReloadJobCommandTest {
assertThat(result, failedWith(5));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("never_created: No such job \u2018never_created\u2019 exists."));
assertThat(result.stderr(), containsString("never_created: No such item ‘never_created’ exists."));
assertThat(result.stderr(), containsString("ERROR: " + CLICommand.CLI_LISTPARAM_SUMMARY_ERROR_TEXT));
assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 2"));
......@@ -234,7 +234,7 @@ public class ReloadJobCommandTest {
assertThat(result, failedWith(5));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("never_created: No such job \u2018never_created\u2019 exists."));
assertThat(result.stderr(), containsString("never_created: No such item ‘never_created’ exists."));
assertThat(result.stderr(), containsString("ERROR: " + CLICommand.CLI_LISTPARAM_SUMMARY_ERROR_TEXT));
assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 2"));
......@@ -260,8 +260,8 @@ public class ReloadJobCommandTest {
assertThat(result, failedWith(5));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("never_created1: No such job \u2018never_created1\u2019 exists."));
assertThat(result.stderr(), containsString("never_created2: No such job \u2018never_created2\u2019 exists."));
assertThat(result.stderr(), containsString("never_created1: No such item ‘never_created1’ exists."));
assertThat(result.stderr(), containsString("never_created2: No such item ‘never_created2’ exists."));
assertThat(result.stderr(), containsString("ERROR: " + CLICommand.CLI_LISTPARAM_SUMMARY_ERROR_TEXT));
assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 2"));
......
......@@ -54,14 +54,14 @@ import static org.hamcrest.Matchers.not;
/**
* @author pjanouse
*/
public class AbstractBuildRangeCommand2Test {
public class RunRangeCommand2Test {
private CLICommandInvoker command;
@Rule public final JenkinsRule j = new JenkinsRule();
@Before public void setUp() {
command = new CLICommandInvoker(j, new AbstractBuildRangeCommandTest.DummyRangeCommand());
command = new CLICommandInvoker(j, new RunRangeCommandTest.DummyRangeCommand());
}
@Test public void dummyRangeShouldFailIfJobNameIsEmptyOnEmptyJenkins() throws Exception {
......
......@@ -25,9 +25,9 @@
package hudson.cli;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Job;
import hudson.model.Run;
import jenkins.model.Jenkins;
import org.junit.BeforeClass;
import org.junit.ClassRule;
......@@ -48,7 +48,7 @@ import static org.hamcrest.Matchers.not;
/**
* @author pjanouse
*/
public class AbstractBuildRangeCommandTest {
public class RunRangeCommandTest {
private static CLICommandInvoker command = null;
private static FreeStyleProject project = null;
......@@ -977,18 +977,18 @@ public class AbstractBuildRangeCommandTest {
}
@Extension
public static class DummyRangeCommand extends AbstractBuildRangeCommand {
public static class DummyRangeCommand extends RunRangeCommand {
@Override
public String getShortDescription() {
return "DummyRangeCommand";
}
@Override
protected int act(List<AbstractBuild<?, ?>> builds) throws IOException {
protected int act(List<Run<?, ?>> builds) throws IOException {
boolean comma = false;
stdout.print("Builds: ");
for (AbstractBuild build : builds) {
for (Run<?, ?> build : builds) {
if (comma)
stdout.print(",");
else
......
......@@ -69,6 +69,7 @@ import org.acegisecurity.context.SecurityContextHolder;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.junit.Assume;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
......@@ -91,6 +92,11 @@ public class BuildTriggerTest {
@ClassRule
public static BuildWatcher buildWatcher = new BuildWatcher();
@Before
public void runMoreQuickly() throws Exception {
j.jenkins.setQuietPeriod(0);
}
private FreeStyleProject createDownstreamProject() throws Exception {
FreeStyleProject dp = j.createFreeStyleProject("downstream");
dp.setQuietPeriod(0);
......@@ -253,13 +259,12 @@ public class BuildTriggerTest {
Cause.UpstreamCause cause = b2.getCause(Cause.UpstreamCause.class);
assertNotNull(cause);
assertEquals(b, cause.getUpstreamRun());
// Now if we have configured some QIA’s but they are not active on this job, we should run as anonymous. Which would normally have no permissions:
QueueItemAuthenticatorConfiguration.get().getAuthenticators().replace(new MockQueueItemAuthenticator(Collections.<String, Authentication>emptyMap()));
// Now if we have configured some QIA’s but they are not active on this job, we should normally fall back to running as anonymous. Which would normally have no permissions:
QueueItemAuthenticatorConfiguration.get().getAuthenticators().replace(new MockQueueItemAuthenticator(Collections.singletonMap("upstream", Jenkins.ANONYMOUS)));
assertDoCheck(alice, Messages.BuildTrigger_you_have_no_permission_to_build_(downstreamName), upstream, downstreamName);
assertDoCheck(alice, null, null, downstreamName);
b = j.buildAndAssertSuccess(upstream);
j.assertLogNotContains(downstreamName, b);
j.assertLogContains(Messages.BuildTrigger_warning_this_build_has_no_associated_aut(), b);
j.waitUntilNoActivity();
assertEquals(1, downstream.getLastBuild().number);
// Unless we explicitly granted them:
......@@ -276,8 +281,6 @@ public class BuildTriggerTest {
assertEquals(2, downstream.getLastBuild().number);
FreeStyleProject simple = j.createFreeStyleProject("simple");
FreeStyleBuild b3 = j.buildAndAssertSuccess(simple);
// See discussion in BuildTrigger for why this is necessary:
j.assertLogContains(Messages.BuildTrigger_warning_this_build_has_no_associated_aut(), b3);
// Finally, in legacy mode we run as SYSTEM:
grantedPermissions.clear(); // similar behavior but different message if DescriptorImpl removed
downstream.removeProperty(amp);
......@@ -288,11 +291,9 @@ public class BuildTriggerTest {
assertDoCheck(alice, null, null, downstreamName);
b = j.buildAndAssertSuccess(upstream);
j.assertLogContains(downstreamName, b);
j.assertLogContains(Messages.BuildTrigger_warning_access_control_for_builds_in_glo(), b);
j.waitUntilNoActivity();
assertEquals(3, downstream.getLastBuild().number);
b3 = j.buildAndAssertSuccess(simple);
j.assertLogNotContains(Messages.BuildTrigger_warning_access_control_for_builds_in_glo(), b3);
}
private void assertDoCheck(Authentication auth, @CheckForNull String expectedError, AbstractProject<?, ?> project, String value) {
FormValidation result;
......
......@@ -24,6 +24,7 @@
package jenkins.triggers;
import com.google.common.collect.ImmutableMap;
import hudson.model.Cause;
import hudson.model.Computer;
import hudson.model.FreeStyleBuild;
......@@ -47,9 +48,12 @@ import org.acegisecurity.Authentication;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockAuthorizationStrategy;
......@@ -57,8 +61,16 @@ import org.jvnet.hudson.test.MockQueueItemAuthenticator;
public class ReverseBuildTriggerTest {
@ClassRule
public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public JenkinsRule r = new JenkinsRule();
@Before
public void runMoreQuickly() throws Exception {
r.jenkins.setQuietPeriod(0);
}
@Test public void configRoundtrip() throws Exception {
r.createFreeStyleProject("upstream");
FreeStyleProject downstream = r.createFreeStyleProject("downstream");
......@@ -100,19 +112,18 @@ public class ReverseBuildTriggerTest {
// Legacy mode: alice has no read permission on upstream but it works anyway
FreeStyleBuild b = r.buildAndAssertSuccess(upstream);
r.assertLogContains(downstreamName, b);
r.assertLogContains(hudson.tasks.Messages.BuildTrigger_warning_access_control_for_builds_in_glo(), b);
r.waitUntilNoActivity();
assertNotNull(JenkinsRule.getLog(b), downstream.getLastBuild());
assertEquals(1, downstream.getLastBuild().number);
// A QIA is configured but does not specify any authentication for downstream, so upstream should not trigger it:
QueueItemAuthenticatorConfiguration.get().getAuthenticators().add(new MockQueueItemAuthenticator(Collections.singletonMap(upstreamName, User.get("admin").impersonate())));
QueueItemAuthenticatorConfiguration.get().getAuthenticators().add(new MockQueueItemAuthenticator(ImmutableMap.of(upstreamName, User.get("admin").impersonate(), downstreamName, Jenkins.ANONYMOUS)));
b = r.buildAndAssertSuccess(upstream);
r.assertLogContains(downstreamName, b);
r.assertLogContains(Messages.ReverseBuildTrigger_running_as_cannot_even_see_for_trigger_f("anonymous", upstreamName, downstreamName), b);
r.waitUntilNoActivity();
assertEquals(1, downstream.getLastBuild().number);
// Auth for upstream is defined but cannot see downstream, so no message is printed about it:
QueueItemAuthenticatorConfiguration.get().getAuthenticators().replace(new MockQueueItemAuthenticator(Collections.singletonMap(upstreamName, User.get("bob").impersonate())));
QueueItemAuthenticatorConfiguration.get().getAuthenticators().replace(new MockQueueItemAuthenticator(ImmutableMap.of(upstreamName, User.get("bob").impersonate(), downstreamName, Jenkins.ANONYMOUS)));
b = r.buildAndAssertSuccess(upstream);
r.assertLogNotContains(downstreamName, b);
r.waitUntilNoActivity();
......@@ -163,6 +174,7 @@ public class ReverseBuildTriggerTest {
auth.grant(Item.DISCOVER).onItems(upstream).to("anonymous");
qiaConfig = new HashMap<String,Authentication>();
qiaConfig.put(upstreamName, User.get("bob").impersonate());
qiaConfig.put(downstreamName, Jenkins.ANONYMOUS);
QueueItemAuthenticatorConfiguration.get().getAuthenticators().replace(new MockQueueItemAuthenticator(qiaConfig));
b = r.buildAndAssertSuccess(upstream);
r.assertLogNotContains(downstreamName, b);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册