提交 244e4dcd 编写于 作者: O Oliver Gondža

Introduce OfflineCause.UserCause

上级 03a04ac3
......@@ -1085,9 +1085,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
checkPermission(DISCONNECT);
offlineMessage = Util.fixEmptyAndTrim(offlineMessage);
setTemporarilyOffline(!temporarilyOffline,
OfflineCause.create(hudson.slaves.Messages._SlaveComputer_DisconnectedBy(
Jenkins.getAuthentication().getName(),
offlineMessage!=null ? " : " + offlineMessage : "")));
new OfflineCause.UserCause(User.current(), offlineMessage));
} else {
checkPermission(CONNECT);
setTemporarilyOffline(!temporarilyOffline,null);
......@@ -1099,9 +1097,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
checkPermission(DISCONNECT);
offlineMessage = Util.fixEmptyAndTrim(offlineMessage);
setTemporarilyOffline(true,
OfflineCause.create(hudson.slaves.Messages._SlaveComputer_DisconnectedBy(
Jenkins.getAuthentication().getName(),
offlineMessage != null ? " : " + offlineMessage : "")));
new OfflineCause.UserCause(User.current(), offlineMessage));
return HttpResponses.redirectToDot();
}
......
......@@ -24,8 +24,12 @@
package hudson.slaves;
import jenkins.model.Jenkins;
import hudson.Functions;
import hudson.model.Computer;
import hudson.model.User;
import org.acegisecurity.Authentication;
import org.jvnet.localizer.Localizable;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.export.Exported;
......@@ -96,19 +100,33 @@ public abstract class OfflineCause {
}
}
public static class ByCLI extends OfflineCause {
/**
* Taken offline by user.
* @since TODO
*/
public static class UserCause extends SimpleOfflineCause {
private final User user;
public UserCause(User user, String message) {
super(hudson.slaves.Messages._SlaveComputer_DisconnectedBy(
user.getId(),
message != null ? " : " + message : ""
));
this.user = user;
}
public User getUser() {
return user;
}
}
public static class ByCLI extends UserCause {
@Exported
public final String message;
public ByCLI(String message) {
super(User.current(), message);
this.message = message;
}
@Override
public String toString() {
if (message==null)
return Messages.OfflineCause_DisconnectedFromCLI();
return message;
}
}
}
......@@ -530,10 +530,7 @@ public class SlaveComputer extends Computer {
//does nothing in case computer is already disconnected
checkPermission(DISCONNECT);
offlineMessage = Util.fixEmptyAndTrim(offlineMessage);
disconnect(OfflineCause.create(Messages._SlaveComputer_DisconnectedBy(
Jenkins.getAuthentication().getName(),
offlineMessage!=null ? " : " + offlineMessage : "")
));
disconnect(new OfflineCause.UserCause(User.current(), offlineMessage));
}
return new HttpRedirect(".");
}
......
......@@ -31,7 +31,6 @@ CommandLauncher.NoLaunchCommand=No launch command specified
ConnectionActivityMonitor.OfflineCause=Repeated ping attempts failed
DumbSlave.displayName=Dumb Slave
NodeProvisioner.EmptyString=
OfflineCause.DisconnectedFromCLI=Disconnected from CLI
OfflineCause.LaunchFailed=This node is offline because Jenkins failed to launch the slave agent on it.
OfflineCause.connection_was_broken_=Connection was broken: {0}
SimpleScheduledRetentionStrategy.FinishedUpTime=Computer has finished its scheduled uptime
......
......@@ -24,7 +24,6 @@ SimpleScheduledRetentionStrategy.displayName=Bring denne slave online efter en t
RetentionStrategy.Always.displayName=Hold denne slave online s\u00e5 meget som muligt
RetentionStrategy.Demand.OfflineIdle=Offline da computeren var i tomgang; vil blive genstartet n\u00e5r n\u00f8dvendigt.
SimpleScheduledRetentionStrategy.FinishedUpTime=Computeren har afsluttet sin planlagte oppetid
OfflineCause.DisconnectedFromCLI=Afkoblet fra CLI''en
EnvironmentVariablesNodeProperty.displayName=Milj\u00f8variable
DumbSlave.displayName=Dum Slave
ComputerLauncher.abortedLaunch=Opstart af slaveproces afbrudt.
......
......@@ -31,7 +31,6 @@ ComputerLauncher.abortedLaunch=Start eines Slave-Prozesses abgebrochen.
CommandLauncher.NoLaunchCommand=Kein Startkommando angegeben.
DumbSlave.displayName=Dumb slave
OfflineCause.LaunchFailed=Dieser Knoten ist nicht verfügbar, weil Jenkins den Slave nicht starten konnte.
OfflineCause.DisconnectedFromCLI=Getrennt mittels CLI
SimpleScheduledRetentionStrategy.displayName=Slave zeitgesteuert anschalten
SimpleScheduledRetentionStrategy.FinishedUpTime=Slave hat seine geplante Online-Zeit beendet.
EnvironmentVariablesNodeProperty.displayName=Umgebungsvariablen
......
......@@ -30,7 +30,6 @@ ComputerLauncher.abortedLaunch=El inicio del agente en el nodo secundario ha sid
CommandLauncher.NoLaunchCommand=No se ha especificado ningn comando
ConnectionActivityMonitor.OfflineCause=No hubo respuesta a ''ping'' despues de varios intentos
DumbSlave.displayName=Secundario pasivo
OfflineCause.DisconnectedFromCLI=Desconectado de CLI
OfflineCause.LaunchFailed=Este nodo est fuera de lnea porque Jenkins no pudo iniciar el agente esclavo.
SimpleScheduledRetentionStrategy.FinishedUpTime=El nodo ha finalizado el tiempo programado de estar on-line
SimpleScheduledRetentionStrategy.displayName=Programar cundo se debe poner este nodo secundario en lnea.
......
......@@ -31,7 +31,6 @@ CommandLauncher.NoLaunchCommand=\u8d77\u52d5\u30b3\u30de\u30f3\u30c9\u304c\u6307
ConnectionActivityMonitor.OfflineCause=\u4f55\u5ea6\u3082ping\u304c\u5931\u6557\u3057\u307e\u3057\u305f\u3002
DumbSlave.displayName=\u30c0\u30e0\u30b9\u30ec\u30fc\u30d6
NodeProvisioner.EmptyString=
OfflineCause.DisconnectedFromCLI=CLI\u3068\u306e\u63a5\u7d9a\u304c\u5207\u65ad\u3055\u308c\u307e\u3057\u305f\u3002
OfflineCause.LaunchFailed=\u30b9\u30ec\u30fc\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u306e\u8d77\u52d5\u306b\u5931\u6557\u3057\u305f\u305f\u3081\u3001\u3053\u306e\u30ce\u30fc\u30c9\u306f\u30aa\u30d5\u30e9\u30a4\u30f3\u3067\u3059\u3002
SimpleScheduledRetentionStrategy.FinishedUpTime=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u306e\u52d5\u4f5c\u53ef\u80fd\u6642\u9593\u304c\u7d42\u4e86\u3057\u307e\u3057\u305f\u3002
SimpleScheduledRetentionStrategy.displayName=\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306b\u5f93\u3063\u3066\u30aa\u30f3\u30e9\u30a4\u30f3\u306b\u3059\u308b
......
......@@ -30,8 +30,6 @@ ComputerLauncher.abortedLaunch=Processo de lan\u00e7amento de slave abortado.
SimpleScheduledRetentionStrategy.displayName=Colocar o slave online de acordo com o agendamento
# This node is offline because Jenkins failed to launch the slave agent on it.
OfflineCause.LaunchFailed=Esse n\u00f3 est\u00e1 offline porque Jenkins falhou ao lan\u00e7ar o agente slave
# Disconnected from CLI
OfflineCause.DisconnectedFromCLI=Desconectado do CLI
# No launch command specified
CommandLauncher.NoLaunchCommand=Sem nenhum comando de lan\u00e7amento especificado
# Offline because computer was idle; it will be relaunched when needed.
......
......@@ -36,7 +36,6 @@ EnvironmentVariablesNodeProperty.displayName=\u74b0\u5883\u8b8a\u6578
JNLPLauncher.displayName=\u900f\u904e Java Web Start \u555f\u52d5 Slave \u4ee3\u7406\u7a0b\u5f0f
NodeDescripter.CheckName.Mandatory=\u4e00\u5b9a\u8981\u8f38\u5165\u540d\u7a31
OfflineCause.DisconnectedFromCLI=\u7531\u547d\u4ee4\u5217\u4ecb\u9762\u4e2d\u65b7\u9023\u7dda
OfflineCause.LaunchFailed=\u7bc0\u9ede\u96e2\u7dda\uff0c\u56e0\u70ba Jenkins \u7121\u6cd5\u555f\u52d5\u4e0a\u9762\u7684 Slave \u4ee3\u7406\u7a0b\u5f0f\u3002
RetentionStrategy.Always.displayName=\u76e1\u53ef\u80fd\u8b93 Slave \u4e0a\u7dda
......
......@@ -74,6 +74,13 @@ public class CLICommandInvoker {
this.command = command;
}
public CLICommandInvoker(final JenkinsRule rule, final String command) {
this.rule = rule;
this.command = CLICommand.clone(command);
if (this.command == null) throw new AssertionError("No such command: " + command);
}
public CLICommandInvoker authorizedTo(final Permission... permissions) {
this.permissions = Arrays.asList(permissions);
......@@ -228,6 +235,14 @@ public class CLICommandInvoker {
};
}
public static Matcher succeededSilently() {
return new Matcher("Succeeded silently") {
@Override protected boolean matchesSafely(Result result) {
return result.result == 0 && "".equals(result.stderr()) && "".equals(result.stdout());
}
};
}
public static Matcher failedWith(final long expectedCode) {
return new Matcher("Exited with " + expectedCode + " return code") {
@Override protected boolean matchesSafely(Result result) {
......
/*
* The MIT License
*
* Copyright (c) 2014 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.cli;
import static org.junit.Assert.*;
import static hudson.cli.CLICommandInvoker.Matcher.*;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import jenkins.model.Jenkins;
import hudson.cli.CLICommandInvoker.Result;
import hudson.model.Computer;
import hudson.model.Slave;
import hudson.model.User;
import hudson.security.ACL;
import hudson.slaves.OfflineCause.UserCause;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
/**
* @author ogondza
*/
public class ComputerStateTest {
@Rule public JenkinsRule j = new JenkinsRule();
@Test
public void connect() throws Exception {
CLICommandInvoker command = new CLICommandInvoker(j, "connect-node");
Slave slave = j.createSlave();
assertTrue(slave.toComputer().isOffline());
Result result = command.authorizedTo(Jenkins.READ, Computer.CONNECT)
.invokeWithArgs(slave.getNodeName())
;
assertThat(result, succeededSilently());
slave.toComputer().waitUntilOnline();
assertTrue(slave.toComputer().isOnline());
}
@Test
public void online() throws Exception {
CLICommandInvoker command = new CLICommandInvoker(j, "online-node");
Slave slave = j.createSlave();
assertTrue(slave.toComputer().isOffline());
Result result = command.authorizedTo(Jenkins.READ, Computer.CONNECT)
.invokeWithArgs(slave.getNodeName())
;
assertThat(result, succeededSilently());
slave.toComputer().waitUntilOnline();
assertTrue(slave.toComputer().isOnline());
}
@Test
public void disconnect() throws Exception {
CLICommandInvoker command = new CLICommandInvoker(j, "disconnect-node");
Slave slave = j.createOnlineSlave();
assertTrue(slave.toComputer().isOnline());
Result result = command.authorizedTo(Jenkins.READ, Computer.DISCONNECT)
.invokeWithArgs(slave.getNodeName(), "-m", "Custom cause message")
;
assertThat(result, succeededSilently());
assertTrue(slave.toComputer().isOffline());
UserCause cause = (UserCause) slave.toComputer().getOfflineCause();
assertThat(cause.toString(), endsWith("Custom cause message"));
assertThat(cause.getUser(), equalTo(command.user()));
}
@Test
public void offline() throws Exception {
CLICommandInvoker command = new CLICommandInvoker(j, "offline-node");
Slave slave = j.createOnlineSlave();
assertTrue(slave.toComputer().isOnline());
Result result = command.authorizedTo(Jenkins.READ, Computer.DISCONNECT)
.invokeWithArgs(slave.getNodeName(), "-m", "Custom cause message")
;
assertThat(result, succeededSilently());
assertTrue(slave.toComputer().isOffline());
UserCause cause = (UserCause) slave.toComputer().getOfflineCause();
assertThat(cause.toString(), endsWith("Custom cause message"));
assertThat(cause.getUser(), equalTo(command.user()));
}
}
......@@ -31,12 +31,15 @@ import hudson.util.TagCloud.Entry;
import hudson.util.TagCloud;
import hudson.model.labels.LabelAtom;
import hudson.model.queue.CauseOfBlockage;
import hudson.security.ACL;
import hudson.security.GlobalMatrixAuthorizationStrategy;
import hudson.security.HudsonPrivateSecurityRealm;
import hudson.slaves.ComputerListener;
import hudson.slaves.NodeProperty;
import hudson.slaves.OfflineCause;
import hudson.slaves.OfflineCause.ByCLI;
import hudson.slaves.OfflineCause.UserCause;
import java.util.Collection;
import java.util.GregorianCalendar;
import org.junit.Rule;
......@@ -88,6 +91,32 @@ public class NodeTest {
assertEquals("Node should have original offline cause after setting another.", cause, node.toComputer().getOfflineCause());
}
@Test
public void testOfflineCause() throws Exception {
Node node = j.createOnlineSlave();
Computer computer = node.toComputer();
OfflineCause.UserCause cause;
final User someone = User.get("someone@somewhere.com");
ACL.impersonate(someone.impersonate());
computer.doToggleOffline("original message");
cause = (UserCause) computer.getOfflineCause();
assertEquals("Disconnected by someone@somewhere.com : original message", cause.toString());
assertEquals(someone, cause.getUser());
final User root = User.get("root@localhost");
ACL.impersonate(root.impersonate());
computer.doChangeOfflineCause("new message");
cause = (UserCause) computer.getOfflineCause();
assertEquals("Disconnected by root@localhost : new message", cause.toString());
assertEquals(root, cause.getUser());
computer.doToggleOffline(null);
assertNull(computer.getOfflineCause());
}
@Test
public void testGetLabelCloud() throws Exception {
Node node = j.createOnlineSlave();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册