Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
LinuxSuRen
jenkins
提交
492dbbed
J
jenkins
项目概览
LinuxSuRen
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
492dbbed
编写于
3月 10, 2017
作者:
J
Jesse Glick
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[JENKINS-41745] Make jenkins-cli.jar connect to the SSH port by default.
上级
6e39dd35
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
135 addition
and
5 deletion
+135
-5
cli/pom.xml
cli/pom.xml
+11
-0
cli/src/main/java/hudson/cli/CLI.java
cli/src/main/java/hudson/cli/CLI.java
+111
-0
cli/src/main/java/hudson/util/QuotedStringTokenizer.java
cli/src/main/java/hudson/util/QuotedStringTokenizer.java
+0
-0
cli/src/main/resources/hudson/cli/client/Messages.properties
cli/src/main/resources/hudson/cli/client/Messages.properties
+2
-0
test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy
...est/groovy/hudson/cli/SetBuildParameterCommandTest.groovy
+11
-5
未找到文件。
cli/pom.xml
浏览文件 @
492dbbed
...
...
@@ -50,6 +50,17 @@
<version>
1.24
</version>
</dependency>
<dependency>
<groupId>
org.apache.sshd
</groupId>
<artifactId>
sshd-core
</artifactId>
<version>
1.2.0
</version>
<!-- TODO 1.3.0 requires Java 8 -->
<optional>
true
</optional>
<!-- do not expose to core -->
</dependency>
<dependency>
<groupId>
org.slf4j
</groupId>
<artifactId>
slf4j-nop
</artifactId>
<optional>
true
</optional>
<!-- ditto -->
</dependency>
<dependency>
<!-- TODO remove and replace PrivateKeyProvider with SecurityUtils.createFileKeyPairProvider() as in SshClient -->
<groupId>
org.jenkins-ci
</groupId>
<artifactId>
trilead-ssh2
</artifactId>
<version>
build214-jenkins-1
</version>
...
...
cli/src/main/java/hudson/cli/CLI.java
浏览文件 @
492dbbed
...
...
@@ -32,6 +32,7 @@ import hudson.remoting.RemoteInputStream;
import
hudson.remoting.RemoteOutputStream
;
import
hudson.remoting.SocketChannelStream
;
import
hudson.remoting.SocketOutputStream
;
import
hudson.util.QuotedStringTokenizer
;
import
javax.crypto.SecretKey
;
import
javax.crypto.spec.SecretKeySpec
;
...
...
@@ -57,6 +58,8 @@ import java.io.StringReader;
import
java.net.HttpURLConnection
;
import
java.net.InetSocketAddress
;
import
java.net.Socket
;
import
java.net.SocketAddress
;
import
java.net.SocketTimeoutException
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.security.GeneralSecurityException
;
...
...
@@ -70,11 +73,23 @@ import java.util.Collections;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Properties
;
import
java.util.Set
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
static
java
.
util
.
logging
.
Level
.*;
import
org.apache.sshd.client.SshClient
;
import
org.apache.sshd.client.channel.ClientChannel
;
import
org.apache.sshd.client.channel.ClientChannelEvent
;
import
org.apache.sshd.client.future.ConnectFuture
;
import
org.apache.sshd.client.keyverifier.DefaultKnownHostsServerKeyVerifier
;
import
org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier
;
import
org.apache.sshd.client.keyverifier.ServerKeyVerifier
;
import
org.apache.sshd.client.session.ClientSession
;
import
org.apache.sshd.common.future.WaitableFuture
;
import
org.apache.sshd.common.util.io.NoCloseInputStream
;
import
org.apache.sshd.common.util.io.NoCloseOutputStream
;
/**
* CLI entry point to Jenkins.
...
...
@@ -403,12 +418,21 @@ public class CLI implements AutoCloseable {
boolean
tryLoadPKey
=
true
;
boolean
useRemoting
=
false
;
String
user
=
null
;
while
(!
args
.
isEmpty
())
{
String
head
=
args
.
get
(
0
);
if
(
head
.
equals
(
"-version"
))
{
System
.
out
.
println
(
"Version: "
+
computeVersion
());
return
0
;
}
if
(
head
.
equals
(
"-remoting"
))
{
useRemoting
=
true
;
args
=
args
.
subList
(
1
,
args
.
size
());
continue
;
}
if
(
head
.
equals
(
"-s"
)
&&
args
.
size
()>=
2
)
{
url
=
args
.
get
(
1
);
args
=
args
.
subList
(
2
,
args
.
size
());
...
...
@@ -446,6 +470,11 @@ public class CLI implements AutoCloseable {
sshAuthRequestedExplicitly
=
true
;
continue
;
}
if
(
head
.
equals
(
"-user"
)
&&
args
.
size
()
>=
2
)
{
user
=
args
.
get
(
1
);
args
=
args
.
subList
(
2
,
args
.
size
());
continue
;
}
if
(
head
.
equals
(
"-p"
)
&&
args
.
size
()>=
2
)
{
httpProxy
=
args
.
get
(
1
);
args
=
args
.
subList
(
2
,
args
.
size
());
...
...
@@ -465,6 +494,19 @@ public class CLI implements AutoCloseable {
if
(
tryLoadPKey
&&
!
provider
.
hasKeys
())
provider
.
readFromDefaultLocations
();
if
(!
useRemoting
)
{
if
(
user
==
null
)
{
// TODO SshCliAuthenticator already autodetects the user based on public key; why cannot AsynchronousCommand.getCurrentUser do the same?
System
.
err
.
println
(
"-user required when not using -remoting"
);
return
-
1
;
}
return
sshConnection
(
url
,
user
,
args
,
provider
);
}
if
(
user
!=
null
)
{
System
.
err
.
println
(
"Warning: -user ignored when using -remoting"
);
}
CLIConnectionFactory
factory
=
new
CLIConnectionFactory
().
url
(
url
).
httpsProxyTunnel
(
httpProxy
);
String
userInfo
=
new
URL
(
url
).
getUserInfo
();
if
(
userInfo
!=
null
)
{
...
...
@@ -507,6 +549,75 @@ public class CLI implements AutoCloseable {
}
}
private
static
int
sshConnection
(
String
jenkinsUrl
,
String
user
,
List
<
String
>
args
,
PrivateKeyProvider
provider
)
throws
IOException
{
URL
url
=
new
URL
(
jenkinsUrl
+
"/login"
);
URLConnection
conn
=
url
.
openConnection
();
String
endpointDescription
=
conn
.
getHeaderField
(
"X-SSH-Endpoint"
);
if
(
endpointDescription
==
null
)
{
System
.
err
.
println
(
"No header 'X-SSH-Endpoint' returned by Jenkins"
);
return
-
1
;
}
System
.
err
.
println
(
"Connecting to: "
+
endpointDescription
);
int
sshPort
=
Integer
.
valueOf
(
endpointDescription
.
split
(
":"
)[
1
]);
String
sshHost
=
endpointDescription
.
split
(
":"
)[
0
];
StringBuilder
command
=
new
StringBuilder
();
for
(
String
arg
:
args
)
{
command
.
append
(
QuotedStringTokenizer
.
quote
(
arg
));
command
.
append
(
' '
);
}
try
(
SshClient
client
=
SshClient
.
setUpDefaultClient
())
{
KnownHostsServerKeyVerifier
verifier
=
new
DefaultKnownHostsServerKeyVerifier
(
new
ServerKeyVerifier
()
{
@Override
public
boolean
verifyServerKey
(
ClientSession
clientSession
,
SocketAddress
remoteAddress
,
PublicKey
serverKey
)
{
/** unknown key is okay, but log */
LOGGER
.
log
(
Level
.
WARNING
,
"Unknown host key for {0}"
,
remoteAddress
.
toString
());
// TODO should not trust unknown hosts by default; this should be opt-in
return
true
;
}
},
true
);
client
.
setServerKeyVerifier
(
verifier
);
client
.
start
();
ConnectFuture
cf
=
client
.
connect
(
user
,
sshHost
,
sshPort
);
cf
.
await
();
try
(
ClientSession
session
=
cf
.
getSession
())
{
for
(
KeyPair
pair
:
provider
.
getKeys
())
{
System
.
err
.
println
(
"Offering "
+
pair
.
getPrivate
().
getAlgorithm
()
+
" private key"
);
session
.
addPublicKeyIdentity
(
pair
);
}
session
.
auth
().
verify
(
10000L
);
try
(
ClientChannel
channel
=
session
.
createExecChannel
(
command
.
toString
()))
{
channel
.
setIn
(
new
NoCloseInputStream
(
System
.
in
));
channel
.
setOut
(
new
NoCloseOutputStream
(
System
.
out
));
channel
.
setErr
(
new
NoCloseOutputStream
(
System
.
err
));
WaitableFuture
wf
=
channel
.
open
();
wf
.
await
();
Set
waitMask
=
channel
.
waitFor
(
Collections
.
singletonList
(
ClientChannelEvent
.
CLOSED
),
0L
);
if
(
waitMask
.
contains
(
ClientChannelEvent
.
TIMEOUT
))
{
throw
new
SocketTimeoutException
(
"Failed to retrieve command result in time: "
+
command
);
}
Integer
exitStatus
=
channel
.
getExitStatus
();
return
exitStatus
;
}
}
finally
{
client
.
stop
();
}
}
}
private
static
String
computeVersion
()
{
Properties
props
=
new
Properties
();
try
{
...
...
c
ore
/src/main/java/hudson/util/QuotedStringTokenizer.java
→
c
li
/src/main/java/hudson/util/QuotedStringTokenizer.java
浏览文件 @
492dbbed
文件已移动
cli/src/main/resources/hudson/cli/client/Messages.properties
浏览文件 @
492dbbed
...
...
@@ -6,6 +6,8 @@ CLI.Usage=Jenkins CLI\n\
-p HOST:PORT : HTTP proxy host and port for HTTPS proxy tunneling. See https://jenkins.io/redirect/cli-https-proxy-tunnel
\n\
-noCertificateCheck : bypass HTTPS certificate check entirely. Use with caution
\n\
-noKeyAuth : don't try to load the SSH authentication private key. Conflicts with -i
\n\
-remoting : use deprecated Remoting channel protocol (if enabled on server; for compatibility with legacy commands or command modes only)
\n\
-user : specify user (for SSH mode, not -remoting)
\n\
\n\
The available commands depend on the server. Run the 'help' command to
\n\
see the list.
...
...
test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy
浏览文件 @
492dbbed
...
...
@@ -14,8 +14,10 @@ import hudson.tasks.Builder
import
hudson.tasks.Shell
import
jenkins.model.JenkinsLocationConfiguration
import
org.junit.Assert
import
org.junit.ClassRule
import
org.junit.Rule
import
org.junit.Test
import
org.jvnet.hudson.test.BuildWatcher
import
org.jvnet.hudson.test.JenkinsRule
import
org.jvnet.hudson.test.TestBuilder
...
...
@@ -26,6 +28,9 @@ public class SetBuildParameterCommandTest {
@Rule
public
JenkinsRule
j
=
new
JenkinsRule
();
@ClassRule
public
static
BuildWatcher
buildWatcher
=
new
BuildWatcher
();
@Test
public
void
cli
()
{
JenkinsLocationConfiguration
.
get
().
url
=
j
.
URL
;
...
...
@@ -42,9 +47,9 @@ public class SetBuildParameterCommandTest {
});
List
<
ParameterDefinition
>
pd
=
[
new
StringParameterDefinition
(
"a"
,
""
),
new
StringParameterDefinition
(
"b"
,
""
)];
p
.
addProperty
(
new
ParametersDefinitionProperty
(
pd
))
p
.
buildersList
.
add
(
createScriptBuilder
(
"java -jar cli.jar set-build-parameter a b"
))
p
.
buildersList
.
add
(
createScriptBuilder
(
"java -jar cli.jar set-build-parameter a x"
))
p
.
buildersList
.
add
(
createScriptBuilder
(
"java -jar cli.jar set-build-parameter b y"
))
p
.
buildersList
.
add
(
createScriptBuilder
(
"java -jar cli.jar
-remoting -noKeyAuth
set-build-parameter a b"
))
p
.
buildersList
.
add
(
createScriptBuilder
(
"java -jar cli.jar
-remoting -noKeyAuth
set-build-parameter a x"
))
p
.
buildersList
.
add
(
createScriptBuilder
(
"java -jar cli.jar
-remoting -noKeyAuth
set-build-parameter b y"
))
def
r
=
[:];
...
...
@@ -54,11 +59,12 @@ public class SetBuildParameterCommandTest {
assert
r
.
equals
([
"a"
:
"x"
,
"b"
:
"y"
]);
if
(
Functions
.
isWindows
())
{
p
.
buildersList
.
add
(
new
BatchFile
(
"set BUILD_NUMBER=1\r\njava -jar cli.jar set-build-parameter a b"
))
p
.
buildersList
.
add
(
new
BatchFile
(
"set BUILD_NUMBER=1\r\njava -jar cli.jar
-remoting -noKeyAuth
set-build-parameter a b"
))
}
else
{
p
.
buildersList
.
add
(
new
Shell
(
"BUILD_NUMBER=1 java -jar cli.jar set-build-parameter a b"
))
p
.
buildersList
.
add
(
new
Shell
(
"BUILD_NUMBER=1 java -jar cli.jar
-remoting -noKeyAuth
set-build-parameter a b"
))
}
def
b2
=
j
.
assertBuildStatus
(
Result
.
FAILURE
,
p
.
scheduleBuild2
(
0
).
get
());
j
.
assertLogContains
(
"#1 is not currently being built"
,
b2
)
r
=
[:];
b
.
getAction
(
ParametersAction
.
class
).
parameters
.
each
{
v
->
r
[
v
.
name
]=
v
.
value
}
assert
r
.
equals
([
"a"
:
"x"
,
"b"
:
"y"
]);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录