提交 92a74104 编写于 作者: O Oliver Gondža

[JENKINS-18282] Introduce update-node CLI command

上级 548e9b8b
/*
* The MIT License
*
* Copyright 2013 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 java.io.IOException;
import javax.servlet.ServletException;
import hudson.Extension;
import hudson.model.Node;
import org.kohsuke.args4j.Argument;
/**
* @author ogondza
* @since XXX
*/
@Extension
public class UpdateNodeCommand extends CLICommand {
@Argument(metaVar="NODE", usage="Name of the node", required=true)
public Node node;
@Override
public String getShortDescription() {
return Messages.UpdateNodeCommand_ShortDescription();
}
@Override
protected int run() throws IOException, ServletException {
node.toComputer().updateByXml(stdin);
return 0;
}
}
......@@ -77,6 +77,7 @@ import javax.servlet.ServletException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
......@@ -1194,9 +1195,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
}
if (req.getMethod().equals("POST")) {
// submission
Node result = (Node)Jenkins.XSTREAM2.fromXML(req.getReader());
replaceBy(result);
updateByXml(req.getInputStream());
return;
}
......@@ -1223,6 +1222,17 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
}
}
/**
* Updates Job by its XML definition.
*
* @since XXX
*/
public void updateByXml(final InputStream source) throws IOException, ServletException {
checkPermission(Jenkins.ADMINISTER);
Node result = (Node)Jenkins.XSTREAM2.fromXML(source);
replaceBy(result);
}
/**
* Really deletes the slave.
*/
......
......@@ -52,4 +52,6 @@ WhoAmICommand.ShortDescription=\
Reports your credential and permissions
UpdateJobCommand.ShortDescription=\
Updates the job definition XML from stdin. The opposite of the get-job command
UpdateNodeCommand.ShortDescription=\
Updates the node definition XML from stdin. The opposite of the get-node command
BuildCommand.CLICause.ShortDescription=Started by command line by {0}
/*
* The MIT License
*
* Copyright 2013 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.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.text.IsEmptyString.isEmptyString;
import hudson.model.Node;
import hudson.model.User;
import hudson.security.Permission;
import hudson.security.GlobalMatrixAuthorizationStrategy;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Locale;
import jenkins.model.Jenkins;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
public class UpdateNodeCommandTest {
private final ByteArrayOutputStream out = new ByteArrayOutputStream();
private final ByteArrayOutputStream err = new ByteArrayOutputStream();
private InputStream in;
private UpdateNodeCommand command;
@Rule public final JenkinsRule j = new JenkinsRule();
@Before public void setUp() {
command = new UpdateNodeCommand();
}
@Test public void updateNodeShouldFailWithoutAdministerPermision() throws Exception {
forUser("user");
j.createSlave("MySlave", null, null);
final int result = execute("MySlave");
assertThat(err.toString(), containsString("user is missing the Administer permission"));
assertThat("No output expected", out.toString(), isEmptyString());
assertThat("Command is expected to fail", result, equalTo(-1));
}
@Test public void updateNodeShouldModifyNodeConfiguration() throws Exception {
forUser("administrator");
j.createSlave("MySlave", null, null);
in = getClass().getResourceAsStream("node.xml");
final int result = execute("MySlave");
assertThat("No error output expected", err.toString(), isEmptyString());
assertThat("Command is expected to succeed", result, equalTo(0));
assertThat("A slave with old name should not exist", j.jenkins.getNode("MySlave"), nullValue());
final Node updatedSlave = j.jenkins.getNode("SlaveFromXML");
assertThat(updatedSlave.getNodeName(), equalTo("SlaveFromXML"));
assertThat(updatedSlave.getNumExecutors(), equalTo(42));
}
@Test public void updateNodeShouldFailIfNodeDoesNotExist() throws Exception {
forUser("administrator");
final int result = execute("MySlave");
assertThat(err.toString(), containsString("No such node 'MySlave'"));
assertThat("No output expected", out.toString(), isEmptyString());
assertThat("Command is expected to fail", result, equalTo(-1));
}
private void forUser(final String user) {
JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm();
realm.addGroups("user", "group");
realm.addGroups("administrator", "administrator");
j.jenkins.setSecurityRealm(realm);
GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy();
auth.add(Permission.READ, "group");
auth.add(Jenkins.ADMINISTER, "administrator");
j.jenkins.setAuthorizationStrategy(auth);
command.setTransportAuth(User.get(user).impersonate());
}
private int execute(final String... args) {
return command.main(
Arrays.asList(args), Locale.ENGLISH, in, new PrintStream(out), new PrintStream(err)
);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<slave>
<name>SlaveFromXML</name>
<description>XML slave description</description>
<remoteFS>/user/hudson/wokspace</remoteFS>
<numExecutors>42</numExecutors>
<mode>NORMAL</mode>
<retentionStrategy class="hudson.slaves.RetentionStrategy$1">
<DESCRIPTOR>
<outer-class reference="../.."/>
</DESCRIPTOR>
</retentionStrategy>
<launcher class="hudson.slaves.CommandLauncher">
<agentCommand>&quot;/opt/java6/jre/bin/java&quot; -jar &quot;slave.jar&quot;</agentCommand>
</launcher>
<label></label>
<nodeProperties/>
<userId>SYSTEM</userId>
</slave>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册