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 @@
...
@@ -50,6 +50,17 @@
<version>
1.24
</version>
<version>
1.24
</version>
</dependency>
</dependency>
<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>
<groupId>
org.jenkins-ci
</groupId>
<artifactId>
trilead-ssh2
</artifactId>
<artifactId>
trilead-ssh2
</artifactId>
<version>
build214-jenkins-1
</version>
<version>
build214-jenkins-1
</version>
...
...
cli/src/main/java/hudson/cli/CLI.java
浏览文件 @
492dbbed
...
@@ -32,6 +32,7 @@ import hudson.remoting.RemoteInputStream;
...
@@ -32,6 +32,7 @@ import hudson.remoting.RemoteInputStream;
import
hudson.remoting.RemoteOutputStream
;
import
hudson.remoting.RemoteOutputStream
;
import
hudson.remoting.SocketChannelStream
;
import
hudson.remoting.SocketChannelStream
;
import
hudson.remoting.SocketOutputStream
;
import
hudson.remoting.SocketOutputStream
;
import
hudson.util.QuotedStringTokenizer
;
import
javax.crypto.SecretKey
;
import
javax.crypto.SecretKey
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.crypto.spec.SecretKeySpec
;
...
@@ -57,6 +58,8 @@ import java.io.StringReader;
...
@@ -57,6 +58,8 @@ import java.io.StringReader;
import
java.net.HttpURLConnection
;
import
java.net.HttpURLConnection
;
import
java.net.InetSocketAddress
;
import
java.net.InetSocketAddress
;
import
java.net.Socket
;
import
java.net.Socket
;
import
java.net.SocketAddress
;
import
java.net.SocketTimeoutException
;
import
java.net.URL
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.net.URLConnection
;
import
java.security.GeneralSecurityException
;
import
java.security.GeneralSecurityException
;
...
@@ -70,11 +73,23 @@ import java.util.Collections;
...
@@ -70,11 +73,23 @@ import java.util.Collections;
import
java.util.List
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Locale
;
import
java.util.Properties
;
import
java.util.Properties
;
import
java.util.Set
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Executors
;
import
java.util.logging.Level
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
java.util.logging.Logger
;
import
static
java
.
util
.
logging
.
Level
.*;
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.
* CLI entry point to Jenkins.
...
@@ -403,12 +418,21 @@ public class CLI implements AutoCloseable {
...
@@ -403,12 +418,21 @@ public class CLI implements AutoCloseable {
boolean
tryLoadPKey
=
true
;
boolean
tryLoadPKey
=
true
;
boolean
useRemoting
=
false
;
String
user
=
null
;
while
(!
args
.
isEmpty
())
{
while
(!
args
.
isEmpty
())
{
String
head
=
args
.
get
(
0
);
String
head
=
args
.
get
(
0
);
if
(
head
.
equals
(
"-version"
))
{
if
(
head
.
equals
(
"-version"
))
{
System
.
out
.
println
(
"Version: "
+
computeVersion
());
System
.
out
.
println
(
"Version: "
+
computeVersion
());
return
0
;
return
0
;
}
}
if
(
head
.
equals
(
"-remoting"
))
{
useRemoting
=
true
;
args
=
args
.
subList
(
1
,
args
.
size
());
continue
;
}
if
(
head
.
equals
(
"-s"
)
&&
args
.
size
()>=
2
)
{
if
(
head
.
equals
(
"-s"
)
&&
args
.
size
()>=
2
)
{
url
=
args
.
get
(
1
);
url
=
args
.
get
(
1
);
args
=
args
.
subList
(
2
,
args
.
size
());
args
=
args
.
subList
(
2
,
args
.
size
());
...
@@ -446,6 +470,11 @@ public class CLI implements AutoCloseable {
...
@@ -446,6 +470,11 @@ public class CLI implements AutoCloseable {
sshAuthRequestedExplicitly
=
true
;
sshAuthRequestedExplicitly
=
true
;
continue
;
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
)
{
if
(
head
.
equals
(
"-p"
)
&&
args
.
size
()>=
2
)
{
httpProxy
=
args
.
get
(
1
);
httpProxy
=
args
.
get
(
1
);
args
=
args
.
subList
(
2
,
args
.
size
());
args
=
args
.
subList
(
2
,
args
.
size
());
...
@@ -465,6 +494,19 @@ public class CLI implements AutoCloseable {
...
@@ -465,6 +494,19 @@ public class CLI implements AutoCloseable {
if
(
tryLoadPKey
&&
!
provider
.
hasKeys
())
if
(
tryLoadPKey
&&
!
provider
.
hasKeys
())
provider
.
readFromDefaultLocations
();
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
);
CLIConnectionFactory
factory
=
new
CLIConnectionFactory
().
url
(
url
).
httpsProxyTunnel
(
httpProxy
);
String
userInfo
=
new
URL
(
url
).
getUserInfo
();
String
userInfo
=
new
URL
(
url
).
getUserInfo
();
if
(
userInfo
!=
null
)
{
if
(
userInfo
!=
null
)
{
...
@@ -507,6 +549,75 @@ public class CLI implements AutoCloseable {
...
@@ -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
()
{
private
static
String
computeVersion
()
{
Properties
props
=
new
Properties
();
Properties
props
=
new
Properties
();
try
{
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\
...
@@ -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\
-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\
-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\
-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\
\n\
The available commands depend on the server. Run the 'help' command to
\n\
The available commands depend on the server. Run the 'help' command to
\n\
see the list.
see the list.
...
...
test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy
浏览文件 @
492dbbed
...
@@ -14,8 +14,10 @@ import hudson.tasks.Builder
...
@@ -14,8 +14,10 @@ import hudson.tasks.Builder
import
hudson.tasks.Shell
import
hudson.tasks.Shell
import
jenkins.model.JenkinsLocationConfiguration
import
jenkins.model.JenkinsLocationConfiguration
import
org.junit.Assert
import
org.junit.Assert
import
org.junit.ClassRule
import
org.junit.Rule
import
org.junit.Rule
import
org.junit.Test
import
org.junit.Test
import
org.jvnet.hudson.test.BuildWatcher
import
org.jvnet.hudson.test.JenkinsRule
import
org.jvnet.hudson.test.JenkinsRule
import
org.jvnet.hudson.test.TestBuilder
import
org.jvnet.hudson.test.TestBuilder
...
@@ -26,6 +28,9 @@ public class SetBuildParameterCommandTest {
...
@@ -26,6 +28,9 @@ public class SetBuildParameterCommandTest {
@Rule
@Rule
public
JenkinsRule
j
=
new
JenkinsRule
();
public
JenkinsRule
j
=
new
JenkinsRule
();
@ClassRule
public
static
BuildWatcher
buildWatcher
=
new
BuildWatcher
();
@Test
@Test
public
void
cli
()
{
public
void
cli
()
{
JenkinsLocationConfiguration
.
get
().
url
=
j
.
URL
;
JenkinsLocationConfiguration
.
get
().
url
=
j
.
URL
;
...
@@ -42,9 +47,9 @@ public class SetBuildParameterCommandTest {
...
@@ -42,9 +47,9 @@ public class SetBuildParameterCommandTest {
});
});
List
<
ParameterDefinition
>
pd
=
[
new
StringParameterDefinition
(
"a"
,
""
),
new
StringParameterDefinition
(
"b"
,
""
)];
List
<
ParameterDefinition
>
pd
=
[
new
StringParameterDefinition
(
"a"
,
""
),
new
StringParameterDefinition
(
"b"
,
""
)];
p
.
addProperty
(
new
ParametersDefinitionProperty
(
pd
))
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
-remoting -noKeyAuth
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
-remoting -noKeyAuth
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 b y"
))
def
r
=
[:];
def
r
=
[:];
...
@@ -54,11 +59,12 @@ public class SetBuildParameterCommandTest {
...
@@ -54,11 +59,12 @@ public class SetBuildParameterCommandTest {
assert
r
.
equals
([
"a"
:
"x"
,
"b"
:
"y"
]);
assert
r
.
equals
([
"a"
:
"x"
,
"b"
:
"y"
]);
if
(
Functions
.
isWindows
())
{
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
{
}
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
());
def
b2
=
j
.
assertBuildStatus
(
Result
.
FAILURE
,
p
.
scheduleBuild2
(
0
).
get
());
j
.
assertLogContains
(
"#1 is not currently being built"
,
b2
)
r
=
[:];
r
=
[:];
b
.
getAction
(
ParametersAction
.
class
).
parameters
.
each
{
v
->
r
[
v
.
name
]=
v
.
value
}
b
.
getAction
(
ParametersAction
.
class
).
parameters
.
each
{
v
->
r
[
v
.
name
]=
v
.
value
}
assert
r
.
equals
([
"a"
:
"x"
,
"b"
:
"y"
]);
assert
r
.
equals
([
"a"
:
"x"
,
"b"
:
"y"
]);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录