Add command to close SSH connection
show-connections command display all the SSH connections but there was no command to close one. Change-Id: Ib90502892901428bd5c1a540266f359daafcbfd2
This commit is contained in:
parent
b49af60c23
commit
641fc788e3
38
Documentation/cmd-close-connection.txt
Normal file
38
Documentation/cmd-close-connection.txt
Normal file
@ -0,0 +1,38 @@
|
||||
= gerrit close-connection
|
||||
|
||||
== NAME
|
||||
gerrit close-connection - Close the specified SSH connection
|
||||
|
||||
== SYNOPSIS
|
||||
--
|
||||
'ssh' -p <port> <host> 'gerrit close-connection' <SESSION_ID>
|
||||
[--wait]
|
||||
--
|
||||
|
||||
== DESCRIPTION
|
||||
Close an SSH connection.
|
||||
|
||||
The connection closing is done asynchronously by default. Use `--wait` option to
|
||||
wait for connection to close.
|
||||
|
||||
An error message will be displayed if no connection with the specified session
|
||||
ID is found.
|
||||
|
||||
== ACCESS
|
||||
Caller must be a member of the privileged 'Administrators' group.
|
||||
|
||||
== SCRIPTING
|
||||
Intended for interactive use only.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
`--wait`
|
||||
: Wait for connection to close before exiting.
|
||||
|
||||
GERRIT
|
||||
------
|
||||
Part of link:index.html[Gerrit Code Review]
|
||||
|
||||
SEARCHBOX
|
||||
---------
|
@ -96,6 +96,9 @@ git upload-pack::
|
||||
[[admin_commands]]Administrator Commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
link:cmd-close-connection.html[gerrit close-connection]::
|
||||
Close the specified SSH connection.
|
||||
|
||||
link:cmd-create-account.html[gerrit create-account]::
|
||||
Create a new user account.
|
||||
|
||||
|
@ -0,0 +1,97 @@
|
||||
// Copyright (C) 2015 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.sshd.commands;
|
||||
|
||||
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
|
||||
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.extensions.annotations.RequiresCapability;
|
||||
import com.google.gerrit.sshd.AdminHighPriorityCommand;
|
||||
import com.google.gerrit.sshd.CommandMetaData;
|
||||
import com.google.gerrit.sshd.SshCommand;
|
||||
import com.google.gerrit.sshd.SshDaemon;
|
||||
import com.google.gerrit.sshd.SshSession;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.apache.sshd.common.io.IoAcceptor;
|
||||
import org.apache.sshd.common.io.IoCloseFuture;
|
||||
import org.apache.sshd.common.io.IoSession;
|
||||
import org.apache.sshd.server.session.ServerSession;
|
||||
import org.kohsuke.args4j.Argument;
|
||||
import org.kohsuke.args4j.Option;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Close specified SSH connections */
|
||||
@AdminHighPriorityCommand
|
||||
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
|
||||
@CommandMetaData(name = "close-connection",
|
||||
description = "Close the specified SSH connection", runsAt = MASTER_OR_SLAVE)
|
||||
final class CloseConnection extends SshCommand {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CloseConnection.class);
|
||||
|
||||
@Inject
|
||||
private SshDaemon sshDaemon;
|
||||
|
||||
@Argument(index = 0, multiValued = true, required = true,
|
||||
metaVar = "SESSION_ID", usage = "List of SSH session IDs to be closed")
|
||||
private final List<String> sessionIds = new ArrayList<>();
|
||||
|
||||
@Option(name = "--wait",
|
||||
usage = "wait for connection to close before exiting")
|
||||
private boolean wait;
|
||||
|
||||
@Override
|
||||
protected void run() throws Failure {
|
||||
IoAcceptor acceptor = sshDaemon.getIoAcceptor();
|
||||
if (acceptor == null) {
|
||||
throw new Failure(1, "fatal: sshd no longer running");
|
||||
}
|
||||
for (String sessionId : sessionIds) {
|
||||
boolean connectionFound = false;
|
||||
int id = (int) Long.parseLong(sessionId, 16);
|
||||
for (IoSession io : acceptor.getManagedSessions().values()) {
|
||||
ServerSession serverSession =
|
||||
(ServerSession) ServerSession.getSession(io, true);
|
||||
SshSession sshSession =
|
||||
serverSession != null
|
||||
? serverSession.getAttribute(SshSession.KEY)
|
||||
: null;
|
||||
if (sshSession != null && sshSession.getSessionId() == id) {
|
||||
connectionFound = true;
|
||||
stdout.println("closing connection " + sessionId + "...");
|
||||
IoCloseFuture future = io.close(true);
|
||||
if (wait) {
|
||||
try {
|
||||
future.await();
|
||||
stdout.println("closed connection " + sessionId);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Wait for connection to close interrupted: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!connectionFound) {
|
||||
stderr.print("close connection " + sessionId + ": no such connection\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ public class DefaultCommandModule extends CommandModule {
|
||||
command(gerrit).toProvider(new DispatchCommandProvider(gerrit));
|
||||
command(gerrit, AproposCommand.class);
|
||||
command(gerrit, BanCommitCommand.class);
|
||||
command(gerrit, CloseConnection.class);
|
||||
command(gerrit, FlushCaches.class);
|
||||
command(gerrit, ListProjectsCommand.class);
|
||||
command(gerrit, ListMembersCommand.class);
|
||||
|
Loading…
Reference in New Issue
Block a user