Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
bdcb2fb2
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
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,发现更多精彩内容 >>
提交
bdcb2fb2
编写于
3月 30, 2020
作者:
J
James Nord
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master' into kill-jsr-305
上级
4d3e60a4
653243a0
变更
47
展开全部
隐藏空白更改
内联
并排
Showing
47 changed file
with
477 addition
and
2428 deletion
+477
-2428
core/pom.xml
core/pom.xml
+11
-0
core/src/main/java/hudson/FilePath.java
core/src/main/java/hudson/FilePath.java
+1
-1
core/src/main/java/hudson/TcpSlaveAgentListener.java
core/src/main/java/hudson/TcpSlaveAgentListener.java
+1
-1
core/src/main/java/hudson/Util.java
core/src/main/java/hudson/Util.java
+69
-4
core/src/main/java/hudson/cli/CLIAction.java
core/src/main/java/hudson/cli/CLIAction.java
+1
-1
core/src/main/java/hudson/fsp/WorkspaceSnapshotSCM.java
core/src/main/java/hudson/fsp/WorkspaceSnapshotSCM.java
+1
-1
core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
.../src/main/java/hudson/lifecycle/WindowsInstallerLink.java
+1
-1
core/src/main/java/hudson/util/HistoricalSecrets.java
core/src/main/java/hudson/util/HistoricalSecrets.java
+9
-3
core/src/main/java/hudson/util/Secret.java
core/src/main/java/hudson/util/Secret.java
+6
-2
core/src/main/java/hudson/util/XStream2.java
core/src/main/java/hudson/util/XStream2.java
+1
-1
core/src/main/java/hudson/util/jna/DotNet.java
core/src/main/java/hudson/util/jna/DotNet.java
+199
-42
core/src/main/java/hudson/util/jna/RegistryKey.java
core/src/main/java/hudson/util/jna/RegistryKey.java
+7
-3
core/src/main/java/jenkins/FilePathFilterAggregator.java
core/src/main/java/jenkins/FilePathFilterAggregator.java
+1
-1
core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java
...java/jenkins/model/GlobalBuildDiscarderConfiguration.java
+4
-0
core/src/main/java/jenkins/security/ConfidentialStore.java
core/src/main/java/jenkins/security/ConfidentialStore.java
+63
-3
core/src/main/java/jenkins/security/DefaultConfidentialStore.java
.../main/java/jenkins/security/DefaultConfidentialStore.java
+5
-0
core/src/main/java/jenkins/security/RSAConfidentialKey.java
core/src/main/java/jenkins/security/RSAConfidentialKey.java
+1
-2
core/src/main/java/jenkins/util/AntClassLoader.java
core/src/main/java/jenkins/util/AntClassLoader.java
+28
-28
core/src/main/resources/hudson/ProxyConfiguration/config.groovy
...rc/main/resources/hudson/ProxyConfiguration/config.groovy
+1
-1
core/src/test/java/hudson/BulkChangeTest.java
core/src/test/java/hudson/BulkChangeTest.java
+1
-1
core/src/test/java/hudson/model/AbstractItemTest.java
core/src/test/java/hudson/model/AbstractItemTest.java
+2
-2
core/src/test/java/hudson/model/EnvironmentContributingActionTest.java
.../java/hudson/model/EnvironmentContributingActionTest.java
+3
-3
core/src/test/java/hudson/model/FingerprintCleanupThreadTest.java
.../test/java/hudson/model/FingerprintCleanupThreadTest.java
+2
-3
core/src/test/java/hudson/model/LoadStatisticsTest.java
core/src/test/java/hudson/model/LoadStatisticsTest.java
+1
-1
core/src/test/java/hudson/util/CyclicGraphDetectorTest.java
core/src/test/java/hudson/util/CyclicGraphDetectorTest.java
+2
-2
core/src/test/java/hudson/util/IsOverriddenTest.java
core/src/test/java/hudson/util/IsOverriddenTest.java
+1
-1
core/src/test/java/hudson/util/MockSecretRule.java
core/src/test/java/hudson/util/MockSecretRule.java
+0
-33
core/src/test/java/hudson/util/SecretRewriterTest.java
core/src/test/java/hudson/util/SecretRewriterTest.java
+0
-3
core/src/test/java/hudson/util/SecretTest.java
core/src/test/java/hudson/util/SecretTest.java
+0
-3
core/src/test/java/hudson/util/io/TarArchiverTest.java
core/src/test/java/hudson/util/io/TarArchiverTest.java
+1
-1
core/src/test/java/jenkins/security/ConfidentialStoreRule.java
...src/test/java/jenkins/security/ConfidentialStoreRule.java
+2
-15
core/src/test/java/jenkins/util/MarkFindingOutputStreamTest.java
...c/test/java/jenkins/util/MarkFindingOutputStreamTest.java
+1
-1
pom.xml
pom.xml
+1
-1
test/src/test/java/hudson/ExtensionListListenerTest.java
test/src/test/java/hudson/ExtensionListListenerTest.java
+1
-1
test/src/test/java/hudson/model/ApiSEC1704Test.java
test/src/test/java/hudson/model/ApiSEC1704Test.java
+1
-1
test/src/test/java/hudson/model/UpdateCenterConnectionStatusTest.java
...t/java/hudson/model/UpdateCenterConnectionStatusTest.java
+1
-1
test/src/test/java/hudson/security/SecurityRealmTest.java
test/src/test/java/hudson/security/SecurityRealmTest.java
+1
-1
test/src/test/java/hudson/security/WhoAmITest.java
test/src/test/java/hudson/security/WhoAmITest.java
+1
-1
test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java
...rc/test/java/hudson/tools/ZipExtractionInstallerTest.java
+1
-1
test/src/test/java/jenkins/agents/WebSocketAgentsTest.java
test/src/test/java/jenkins/agents/WebSocketAgentsTest.java
+1
-1
test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java
...src/test/java/jenkins/model/GlobalBuildDiscarderTest.java
+20
-0
test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java
...st/java/jenkins/security/RekeySecretAdminMonitorTest.java
+4
-1
test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java
...est/java/jenkins/security/stapler/DoActionFilterTest.java
+1
-1
test/src/test/resources/jenkins/model/GlobalBuildDiscarderTest/testLoading/jenkins.model.GlobalBuildDiscarderConfiguration.xml
...ading/jenkins.model.GlobalBuildDiscarderConfiguration.xml
+4
-0
test/src/test/resources/jenkins/model/GlobalBuildDiscarderTest/testLoadingWithDiscarders/jenkins.model.GlobalBuildDiscarderConfiguration.xml
...rders/jenkins.model.GlobalBuildDiscarderConfiguration.xml
+14
-0
war/src/main/webapp/css/layout-common.css
war/src/main/webapp/css/layout-common.css
+0
-152
war/src/main/webapp/css/style.css
war/src/main/webapp/css/style.css
+0
-2102
未找到文件。
core/pom.xml
浏览文件 @
bdcb2fb2
...
...
@@ -895,5 +895,16 @@ THE SOFTWARE.
<findbugs.failOnError>
true
</findbugs.failOnError>
</properties>
</profile>
<profile>
<id>
all-tests
</id>
<activation>
<property>
<name>
!test
</name>
</property>
</activation>
<properties>
<maven.test.redirectTestOutputToFile>
true
</maven.test.redirectTestOutputToFile>
</properties>
</profile>
</profiles>
</project>
core/src/main/java/hudson/FilePath.java
浏览文件 @
bdcb2fb2
...
...
@@ -3279,7 +3279,7 @@ public final class FilePath implements SerializableOnlyOverRemoting {
return
act
(
new
IsDescendant
(
potentialChildRelativePath
));
}
private
class
IsDescendant
extends
SecureFileCallable
<
Boolean
>
{
private
static
class
IsDescendant
extends
SecureFileCallable
<
Boolean
>
{
private
static
final
long
serialVersionUID
=
1L
;
private
String
potentialChildRelativePath
;
...
...
core/src/main/java/hudson/TcpSlaveAgentListener.java
浏览文件 @
bdcb2fb2
...
...
@@ -360,7 +360,7 @@ public final class TcpSlaveAgentListener extends Thread {
}
// This is essentially just to be able to pass the parent thread into the callback, as it can't access it otherwise
private
abstract
class
ConnectionHandlerFailureCallback
{
private
static
abstract
class
ConnectionHandlerFailureCallback
{
private
Thread
parentThread
;
public
ConnectionHandlerFailureCallback
(
Thread
parentThread
)
{
...
...
core/src/main/java/hudson/Util.java
浏览文件 @
bdcb2fb2
...
...
@@ -86,6 +86,7 @@ import java.util.regex.Matcher;
import
java.util.regex.Pattern
;
import
edu.umd.cs.findbugs.annotations.CheckForNull
;
import
edu.umd.cs.findbugs.annotations.CheckReturnValue
;
import
edu.umd.cs.findbugs.annotations.NonNull
;
import
edu.umd.cs.findbugs.annotations.Nullable
;
import
javax.crypto.SecretKey
;
...
...
@@ -1205,6 +1206,65 @@ public class Util {
return
createFileSet
(
baseDir
,
includes
,
null
);
}
private
static
void
tryToDeleteSymlink
(
@NonNull
File
symlink
)
{
if
(!
symlink
.
delete
())
{
LogRecord
record
=
new
LogRecord
(
Level
.
FINE
,
"Failed to delete temporary symlink {0}"
);
record
.
setParameters
(
new
Object
[]{
symlink
.
getAbsolutePath
()});
LOGGER
.
log
(
record
);
}
}
private
static
void
reportAtomicFailure
(
@NonNull
Path
pathForSymlink
,
@NonNull
Exception
ex
)
{
LogRecord
record
=
new
LogRecord
(
Level
.
FINE
,
"Failed to atomically create/replace symlink {0}"
);
record
.
setParameters
(
new
Object
[]{
pathForSymlink
.
toAbsolutePath
().
toString
()});
record
.
setThrown
(
ex
);
LOGGER
.
log
(
record
);
}
/**
* Creates a symlink to targetPath at baseDir+symlinkPath.
*
* @param pathForSymlink
* The absolute path of the symlink itself as a path object.
* @param fileForSymlink
* The absolute path of the symlink itself as a file object.
* @param target
* The path that the symlink should point to. Usually relative to the directory of the symlink but may instead be an absolute path.
* @param symlinkPath
* Where to create a symlink in (relative to {@code baseDir})
*
* Returns true on success
*/
@CheckReturnValue
private
static
boolean
createSymlinkAtomic
(
@NonNull
Path
pathForSymlink
,
@NonNull
File
fileForSymlink
,
@NonNull
Path
target
,
@NonNull
String
symlinkPath
)
{
try
{
File
symlink
=
File
.
createTempFile
(
"symtmp"
,
null
,
fileForSymlink
);
tryToDeleteSymlink
(
symlink
);
Path
tempSymlinkPath
=
symlink
.
toPath
();
Files
.
createSymbolicLink
(
tempSymlinkPath
,
target
);
try
{
Files
.
move
(
tempSymlinkPath
,
pathForSymlink
,
java
.
nio
.
file
.
StandardCopyOption
.
ATOMIC_MOVE
);
return
true
;
}
catch
(
UnsupportedOperationException
|
SecurityException
|
IOException
ex
)
{
// If we couldn't perform an atomic move or the setup, we fall through to another approach
reportAtomicFailure
(
pathForSymlink
,
ex
);
}
// If we didn't return after our atomic move, then we want to clean up our symlink
tryToDeleteSymlink
(
symlink
);
}
catch
(
SecurityException
|
InvalidPathException
|
UnsupportedOperationException
|
IOException
ex
)
{
// We couldn't perform an atomic move or the setup.
reportAtomicFailure
(
pathForSymlink
,
ex
);
}
return
false
;
}
/**
* Creates a symlink to targetPath at baseDir+symlinkPath.
* <p>
...
...
@@ -1219,16 +1279,21 @@ public class Util {
*/
public
static
void
createSymlink
(
@NonNull
File
baseDir
,
@NonNull
String
targetPath
,
@NonNull
String
symlinkPath
,
@NonNull
TaskListener
listener
)
throws
InterruptedException
{
File
fileForSymlink
=
new
File
(
baseDir
,
symlinkPath
);
try
{
Path
path
=
fileToPath
(
new
File
(
baseDir
,
symlinkPath
)
);
Path
path
ForSymlink
=
fileToPath
(
fileForSymlink
);
Path
target
=
Paths
.
get
(
targetPath
,
MemoryReductionUtil
.
EMPTY_STRING_ARRAY
);
if
(
createSymlinkAtomic
(
pathForSymlink
,
fileForSymlink
,
target
,
symlinkPath
))
{
return
;
}
final
int
maxNumberOfTries
=
4
;
final
int
timeInMillis
=
100
;
for
(
int
tryNumber
=
1
;
tryNumber
<=
maxNumberOfTries
;
tryNumber
++)
{
Files
.
deleteIfExists
(
path
);
Files
.
deleteIfExists
(
path
ForSymlink
);
try
{
Files
.
createSymbolicLink
(
path
,
target
);
Files
.
createSymbolicLink
(
path
ForSymlink
,
target
);
break
;
}
catch
(
FileAlreadyExistsException
fileAlreadyExistsException
)
{
if
(
tryNumber
<
maxNumberOfTries
)
{
...
...
@@ -1249,7 +1314,7 @@ public class Util {
return
;
}
PrintStream
log
=
listener
.
getLogger
();
log
.
printf
(
"ln %s %s failed%n"
,
targetPath
,
new
File
(
baseDir
,
symlinkPath
)
);
log
.
printf
(
"ln %s %s failed%n"
,
targetPath
,
fileForSymlink
);
Functions
.
printStackTrace
(
e
,
log
);
}
}
...
...
core/src/main/java/hudson/cli/CLIAction.java
浏览文件 @
bdcb2fb2
...
...
@@ -190,7 +190,7 @@ public class CLIAction implements UnprotectedRootAction, StaplerProxy {
}
}
class
ServerSideImpl
extends
PlainCLIProtocol
.
ServerSide
{
static
class
ServerSideImpl
extends
PlainCLIProtocol
.
ServerSide
{
private
Thread
runningThread
;
private
boolean
ready
;
private
final
List
<
String
>
args
=
new
ArrayList
<>();
...
...
core/src/main/java/hudson/fsp/WorkspaceSnapshotSCM.java
浏览文件 @
bdcb2fb2
...
...
@@ -69,7 +69,7 @@ public class WorkspaceSnapshotSCM extends SCM {
/**
* {@link Exception} indicating that the resolution of the job/permalink failed.
*/
private
final
class
ResolvedFailedException
extends
Exception
{
private
static
final
class
ResolvedFailedException
extends
Exception
{
private
ResolvedFailedException
(
String
message
)
{
super
(
message
);
}
...
...
core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
浏览文件 @
bdcb2fb2
...
...
@@ -127,7 +127,7 @@ public class WindowsInstallerLink extends ManagementLink {
sendError
(
"Installation is already complete"
,
req
,
rsp
);
return
;
}
if
(!
DotNet
.
isInstalled
(
2
,
0
))
{
if
(!
DotNet
.
isInstalled
(
4
,
0
)
&&
!
DotNet
.
isInstalled
(
2
,
0
))
{
sendError
(
".NET Framework 2.0 or later is required for this feature"
,
req
,
rsp
);
return
;
}
...
...
core/src/main/java/hudson/util/HistoricalSecrets.java
浏览文件 @
bdcb2fb2
...
...
@@ -81,9 +81,15 @@ public class HistoricalSecrets {
*/
@Deprecated
/*package*/
static
SecretKey
getLegacyKey
()
throws
GeneralSecurityException
{
String
secret
=
Secret
.
SECRET
;
if
(
secret
==
null
)
return
Jenkins
.
get
().
getSecretKeyAsAES128
();
return
Util
.
toAes128Key
(
secret
);
if
(
Secret
.
SECRET
!=
null
)
{
return
Util
.
toAes128Key
(
Secret
.
SECRET
);
}
Jenkins
j
=
Jenkins
.
getInstanceOrNull
();
if
(
j
!=
null
)
{
return
j
.
getSecretKeyAsAES128
();
}
else
{
return
Util
.
toAes128Key
(
"mock"
);
}
}
static
final
String
MAGIC
=
"::::MAGIC::::"
;
...
...
core/src/main/java/hudson/util/Secret.java
浏览文件 @
bdcb2fb2
...
...
@@ -31,7 +31,6 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import
com.thoughtworks.xstream.io.HierarchicalStreamWriter
;
import
jenkins.util.SystemProperties
;
import
java.util.Arrays
;
import
jenkins.model.Jenkins
;
import
hudson.Util
;
import
jenkins.security.CryptoConfidentialKey
;
import
org.kohsuke.stapler.Stapler
;
...
...
@@ -289,8 +288,10 @@ public final class Secret implements Serializable {
private
static
final
String
PROVIDER
=
SystemProperties
.
getString
(
Secret
.
class
.
getName
()+
".provider"
);
/**
* For testing only. Override the secret key so that we can test this class without {@link Jenkins}.
* For testing only.
* @deprecated Normally unnecessary.
*/
@Deprecated
/*package*/
static
String
SECRET
=
null
;
/**
...
...
@@ -303,6 +304,9 @@ public final class Secret implements Serializable {
static
{
Stapler
.
CONVERT_UTILS
.
register
(
new
org
.
apache
.
commons
.
beanutils
.
Converter
()
{
public
Secret
convert
(
Class
type
,
Object
value
)
{
if
(
value
==
null
)
{
return
null
;
}
if
(
value
instanceof
Secret
)
{
return
(
Secret
)
value
;
}
...
...
core/src/main/java/hudson/util/XStream2.java
浏览文件 @
bdcb2fb2
...
...
@@ -327,7 +327,7 @@ public class XStream2 extends XStream {
mapperInjectionPoint
.
setDelegate
(
m
);
}
final
class
MapperInjectionPoint
extends
MapperDelegate
{
final
static
class
MapperInjectionPoint
extends
MapperDelegate
{
public
MapperInjectionPoint
(
Mapper
wrapped
)
{
super
(
wrapped
);
}
...
...
core/src/main/java/hudson/util/jna/DotNet.java
浏览文件 @
bdcb2fb2
...
...
@@ -30,8 +30,6 @@ import org.jinterop.winreg.JIPolicyHandle;
import
org.jinterop.winreg.JIWinRegFactory
;
import
java.net.UnknownHostException
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* .NET related code.
...
...
@@ -39,74 +37,233 @@ import java.util.regex.Pattern;
* @author Kohsuke Kawaguchi
*/
public
class
DotNet
{
private
static
final
String
PATH10
=
"SOFTWARE\\Microsoft\\.NETFramework\\Policy\\v1.0\\3705"
;
private
static
final
String
PATH11
=
"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322"
;
private
static
final
String
PATH20
=
"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727"
;
private
static
final
String
PATH30
=
"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0\\Setup"
;
private
static
final
String
PATH35
=
"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5"
;
private
static
final
String
PATH4
=
"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full"
;
private
static
final
String
VALUE_INSTALL
=
"Install"
;
private
static
final
String
VALUE_INSTALL_SUCCESS
=
"InstallSuccess"
;
private
static
final
String
VALUE_RELEASE
=
"Release"
;
/**
* Returns true if the .NET framework of
the given version (or greater)
is installed.
* Returns true if the .NET framework of
a compatible version
is installed.
*/
public
static
boolean
isInstalled
(
int
major
,
int
minor
)
{
try
{
// see http://support.microsoft.com/?scid=kb;en-us;315291 for the basic algorithm
// observation in my registry shows that the actual key name can be things like "v2.0 SP1"
// or "v2.0.50727", so the regexp is written to accommodate this.
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
"SOFTWARE\\Microsoft\\.NETFramework"
);
try
{
for
(
String
keyName
:
key
.
getSubKeys
()
)
{
if
(
matches
(
keyName
,
major
,
minor
))
return
true
;
}
if
(
major
==
4
&&
minor
>=
5
)
{
return
isV45PlusInstalled
(
minor
);
}
else
if
(
major
==
4
&&
minor
==
0
)
{
return
isV40Installed
();
}
else
if
(
major
==
3
&&
minor
==
5
)
{
return
isV35Installed
();
}
else
if
(
major
==
3
&&
minor
==
0
)
{
return
isV35Installed
()
||
isV30Installed
();
}
else
if
(
major
==
2
&&
minor
==
0
)
{
return
isV35Installed
()
||
isV30Installed
()
||
isV20Installed
();
}
else
if
(
major
==
1
&&
minor
==
1
)
{
return
isV11Installed
();
}
else
if
(
major
==
1
&&
minor
==
0
)
{
return
isV11Installed
()
||
isV10Installed
();
}
else
{
return
false
;
}
finally
{
key
.
dispose
();
}
}
catch
(
JnaException
e
)
{
if
(
e
.
getErrorCode
()==
2
)
// thrown when openReadonly fails because the key doesn't exist.
if
(
e
.
getErrorCode
()
==
2
)
{
// thrown when openReadonly fails because the key doesn't exist.
return
false
;
}
throw
e
;
}
}
private
static
boolean
isV45PlusInstalled
(
int
minor
)
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH4
))
{
return
key
.
getIntValue
(
VALUE_RELEASE
)
>=
GetV45PlusMinRelease
(
minor
);
}
}
private
static
boolean
isV40Installed
()
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH4
))
{
return
key
.
getIntValue
(
VALUE_INSTALL
)
==
1
;
}
}
private
static
boolean
isV35Installed
()
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH35
))
{
return
key
.
getIntValue
(
VALUE_INSTALL
)
==
1
;
}
}
private
static
boolean
isV30Installed
()
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH30
))
{
return
key
.
getIntValue
(
VALUE_INSTALL_SUCCESS
)
==
1
;
}
}
private
static
boolean
isV20Installed
()
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH20
))
{
return
key
.
getIntValue
(
VALUE_INSTALL
)
==
1
;
}
}
private
static
boolean
isV11Installed
()
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH11
))
{
return
key
.
getIntValue
(
VALUE_INSTALL
)
==
1
;
}
}
private
static
boolean
isV10Installed
()
{
try
(
RegistryKey
key
=
RegistryKey
.
LOCAL_MACHINE
.
openReadonly
(
PATH10
))
{
return
key
.
getStringValue
(
VALUE_INSTALL
)
==
"1"
;
}
}
/**
* Returns true if the .NET framework of the given version (or grater) is installed
* on a remote machine.
* Returns true if the .NET framework of a compatible version is installed on a remote machine.
*/
public
static
boolean
isInstalled
(
int
major
,
int
minor
,
String
targetMachine
,
IJIAuthInfo
session
)
throws
JIException
,
UnknownHostException
{
IJIWinReg
registry
=
JIWinRegFactory
.
getSingleTon
().
getWinreg
(
session
,
targetMachine
,
true
);
JIPolicyHandle
hklm
=
null
;
JIPolicyHandle
key
=
null
;
IJIWinReg
registry
=
JIWinRegFactory
.
getSingleTon
().
getWinreg
(
session
,
targetMachine
,
true
);
JIPolicyHandle
hklm
=
null
;
try
{
hklm
=
registry
.
winreg_OpenHKLM
();
key
=
registry
.
winreg_OpenKey
(
hklm
,
"SOFTWARE\\Microsoft\\.NETFramework"
,
IJIWinReg
.
KEY_READ
);
for
(
int
i
=
0
;
;
i
++
)
{
String
keyName
=
registry
.
winreg_EnumKey
(
key
,
i
)[
0
];
if
(
matches
(
keyName
,
major
,
minor
))
return
true
;
if
(
major
==
4
&&
minor
>=
5
)
{
return
isV45PlusInstalled
(
minor
,
registry
,
hklm
);
}
else
if
(
major
==
4
&&
minor
==
0
)
{
return
isV40Installed
(
registry
,
hklm
);
}
else
if
(
major
==
3
&&
minor
==
5
)
{
return
isV35Installed
(
registry
,
hklm
);
}
else
if
(
major
==
3
&&
minor
==
0
)
{
return
isV35Installed
(
registry
,
hklm
)
||
isV30Installed
(
registry
,
hklm
);
}
else
if
(
major
==
2
&&
minor
==
0
)
{
return
isV35Installed
(
registry
,
hklm
)
||
isV30Installed
(
registry
,
hklm
)
||
isV20Installed
(
registry
,
hklm
);
}
else
if
(
major
==
1
&&
minor
==
1
)
{
return
isV11Installed
(
registry
,
hklm
);
}
else
if
(
major
==
1
&&
minor
==
0
)
{
return
isV11Installed
(
registry
,
hklm
)
||
isV10Installed
(
registry
,
hklm
);
}
else
{
return
false
;
}
}
catch
(
JIException
e
)
{
if
(
e
.
getErrorCode
()==
2
)
return
false
;
// not found
if
(
e
.
getErrorCode
()
==
2
)
{
// not found
return
false
;
}
throw
e
;
}
finally
{
if
(
hklm
!=
null
)
if
(
hklm
!=
null
)
{
registry
.
winreg_CloseKey
(
hklm
);
if
(
key
!=
null
)
registry
.
winreg_CloseKey
(
key
);
}
registry
.
closeConnection
();
}
}
private
static
boolean
matches
(
String
keyName
,
int
major
,
int
minor
)
{
Matcher
m
=
VERSION_PATTERN
.
matcher
(
keyName
);
if
(
m
.
matches
())
{
int
mj
=
Integer
.
parseInt
(
m
.
group
(
1
));
if
(
mj
>=
major
)
{
int
mn
=
Integer
.
parseInt
(
m
.
group
(
2
));
if
(
mn
>=
minor
)
return
true
;
private
static
boolean
isV45PlusInstalled
(
int
minor
,
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH4
,
IJIWinReg
.
KEY_READ
);
return
GetIntValue
(
registry
,
key
,
VALUE_RELEASE
)
>=
GetV45PlusMinRelease
(
minor
);
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
}
private
static
boolean
isV40Installed
(
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH4
,
IJIWinReg
.
KEY_READ
);
return
GetIntValue
(
registry
,
key
,
VALUE_INSTALL
)
==
1
;
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
}
private
static
boolean
isV35Installed
(
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH35
,
IJIWinReg
.
KEY_READ
);
return
GetIntValue
(
registry
,
key
,
VALUE_INSTALL
)
==
1
;
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
}
private
static
boolean
isV30Installed
(
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH30
,
IJIWinReg
.
KEY_READ
);
return
GetIntValue
(
registry
,
key
,
VALUE_INSTALL_SUCCESS
)
==
1
;
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
}
private
static
boolean
isV20Installed
(
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH20
,
IJIWinReg
.
KEY_READ
);
return
GetIntValue
(
registry
,
key
,
VALUE_INSTALL
)
==
1
;
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
return
false
;
}
private
static
final
Pattern
VERSION_PATTERN
=
Pattern
.
compile
(
"v(\\d+)\\.(\\d+).*"
);
private
static
boolean
isV11Installed
(
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH11
,
IJIWinReg
.
KEY_READ
);
return
GetIntValue
(
registry
,
key
,
VALUE_INSTALL
)
==
1
;
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
}
private
static
boolean
isV10Installed
(
IJIWinReg
registry
,
JIPolicyHandle
hklm
)
throws
JIException
{
JIPolicyHandle
key
=
null
;
try
{
key
=
registry
.
winreg_OpenKey
(
hklm
,
PATH10
,
IJIWinReg
.
KEY_READ
);
return
GetStringValue
(
registry
,
key
,
VALUE_INSTALL
)
==
"1"
;
}
finally
{
if
(
key
!=
null
)
{
registry
.
winreg_CloseKey
(
key
);
}
}
}
private
static
int
GetIntValue
(
IJIWinReg
registry
,
JIPolicyHandle
key
,
String
name
)
throws
JIException
{
return
RegistryKey
.
convertBufferToInt
((
byte
[])
registry
.
winreg_QueryValue
(
key
,
name
,
Integer
.
BYTES
)[
1
]);
}
private
static
String
GetStringValue
(
IJIWinReg
registry
,
JIPolicyHandle
key
,
String
name
)
throws
JIException
{
return
RegistryKey
.
convertBufferToString
((
byte
[])
registry
.
winreg_QueryValue
(
key
,
name
,
Character
.
BYTES
*
2
)[
1
]);
}
private
static
int
GetV45PlusMinRelease
(
int
minor
)
{
switch
(
minor
)
{
case
5
:
return
378389
;
case
6
:
return
393295
;
case
7
:
return
460798
;
case
8
:
return
528040
;
default
:
return
Integer
.
MAX_VALUE
;
}
}
}
core/src/main/java/hudson/util/jna/RegistryKey.java
浏览文件 @
bdcb2fb2
...
...
@@ -27,7 +27,7 @@ import java.util.TreeSet;
*
* @author Kohsuke Kawaguchi
*/
public
class
RegistryKey
{
public
class
RegistryKey
implements
AutoCloseable
{
/**
* 32bit Windows key value.
*/
...
...
@@ -64,7 +64,7 @@ public class RegistryKey {
* @throws java.io.UnsupportedEncodingException on error
* @return String
*/
private
static
String
convertBufferToString
(
byte
[]
buf
)
{
static
String
convertBufferToString
(
byte
[]
buf
)
{
return
new
String
(
buf
,
0
,
buf
.
length
-
2
,
StandardCharsets
.
UTF_16LE
);
}
...
...
@@ -74,7 +74,7 @@ public class RegistryKey {
* @param buf buffer
* @return int
*/
private
static
int
convertBufferToInt
(
byte
[]
buf
)
{
static
int
convertBufferToInt
(
byte
[]
buf
)
{
return
((
buf
[
0
]
&
0xff
)
+
((
buf
[
1
]
&
0xff
)
<<
8
)
+
((
buf
[
2
]
&
0xff
)
<<
16
)
+
((
buf
[
3
]
&
0xff
)
<<
24
));
}
...
...
@@ -287,6 +287,10 @@ public class RegistryKey {
handle
=
0
;
}
public
void
close
()
{
dispose
();
}
//
// Root keys
//
...
...
core/src/main/java/jenkins/FilePathFilterAggregator.java
浏览文件 @
bdcb2fb2
...
...
@@ -20,7 +20,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
class
FilePathFilterAggregator
extends
FilePathFilter
{
private
final
CopyOnWriteArrayList
<
Entry
>
all
=
new
CopyOnWriteArrayList
<>();
private
class
Entry
implements
Comparable
<
Entry
>
{
private
static
class
Entry
implements
Comparable
<
Entry
>
{
final
FilePathFilter
filter
;
final
double
ordinal
;
...
...
core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java
浏览文件 @
bdcb2fb2
...
...
@@ -48,6 +48,10 @@ public class GlobalBuildDiscarderConfiguration extends GlobalConfiguration {
return
ExtensionList
.
lookupSingleton
(
GlobalBuildDiscarderConfiguration
.
class
);
}
public
GlobalBuildDiscarderConfiguration
()
{
load
();
}
private
final
DescribableList
<
GlobalBuildDiscarderStrategy
,
GlobalBuildDiscarderStrategyDescriptor
>
configuredBuildDiscarders
=
new
DescribableList
<>(
this
,
Collections
.
singletonList
(
new
JobGlobalBuildDiscarderStrategy
()));
...
...
core/src/main/java/jenkins/security/ConfidentialStore.java
浏览文件 @
bdcb2fb2
...
...
@@ -10,10 +10,14 @@ import org.kohsuke.MetaInfServices;
import
edu.umd.cs.findbugs.annotations.CheckForNull
;
import
edu.umd.cs.findbugs.annotations.NonNull
;
import
java.io.IOException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.SecureRandom
;
import
java.util.Iterator
;
import
java.util.Map
;
import
java.util.Random
;
import
java.util.ServiceConfigurationError
;
import
java.util.ServiceLoader
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
...
...
@@ -51,6 +55,9 @@ public abstract class ConfidentialStore {
*/
protected
abstract
@CheckForNull
byte
[]
load
(
ConfidentialKey
key
)
throws
IOException
;
// TODO consider promoting to public, and offering a default implementation of randomBytes (via the usual Util.isOverridden binary compat trick)
abstract
SecureRandom
secureRandom
();
/**
* Works like {@link SecureRandom#nextBytes(byte[])}.
*
...
...
@@ -64,7 +71,10 @@ public abstract class ConfidentialStore {
public
static
@NonNull
ConfidentialStore
get
()
{
if
(
TEST
!=
null
)
return
TEST
.
get
();
Jenkins
j
=
Jenkins
.
get
();
Jenkins
j
=
Jenkins
.
getInstanceOrNull
();
if
(
j
==
null
)
{
return
Mock
.
INSTANCE
;
}
Lookup
lookup
=
j
.
lookup
;
ConfidentialStore
cs
=
lookup
.
get
(
ConfidentialStore
.
class
);
if
(
cs
==
null
)
{
...
...
@@ -91,10 +101,60 @@ public abstract class ConfidentialStore {
return
cs
;
}
/**
*
Testing only. Used for testing {@link ConfidentialKey} without {@link Jenkins}
/**
*
@deprecated No longer needed.
*/
@Deprecated
/*package*/
static
ThreadLocal
<
ConfidentialStore
>
TEST
=
null
;
static
final
class
Mock
extends
ConfidentialStore
{
static
final
Mock
INSTANCE
=
new
Mock
();
private
final
SecureRandom
rand
;
private
final
Map
<
String
,
byte
[]>
data
=
new
ConcurrentHashMap
<>();
Mock
()
{
// Use a predictable seed to make tests more reproducible.
try
{
rand
=
SecureRandom
.
getInstance
(
"SHA1PRNG"
);
}
catch
(
NoSuchAlgorithmException
x
)
{
throw
new
AssertionError
(
"https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecureRandom"
,
x
);
}
rand
.
setSeed
(
new
byte
[]
{
1
,
2
,
3
,
4
});
}
void
clear
()
{
data
.
clear
();
}
@Override
protected
void
store
(
ConfidentialKey
key
,
byte
[]
payload
)
throws
IOException
{
LOGGER
.
fine
(()
->
"storing "
+
key
.
getId
()
+
" "
+
hudson
.
Util
.
getDigestOf
(
hudson
.
Util
.
toHexString
(
payload
)));
data
.
put
(
key
.
getId
(),
payload
);
}
@Override
protected
byte
[]
load
(
ConfidentialKey
key
)
throws
IOException
{
byte
[]
payload
=
data
.
get
(
key
.
getId
());
LOGGER
.
fine
(()
->
"loading "
+
key
.
getId
()
+
" "
+
(
payload
!=
null
?
hudson
.
Util
.
getDigestOf
(
hudson
.
Util
.
toHexString
(
payload
))
:
"null"
));
return
payload
;
}
@Override
SecureRandom
secureRandom
()
{
return
rand
;
}
@Override
public
byte
[]
randomBytes
(
int
size
)
{
byte
[]
random
=
new
byte
[
size
];
rand
.
nextBytes
(
random
);
return
random
;
}
}
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
ConfidentialStore
.
class
.
getName
());
}
core/src/main/java/jenkins/security/DefaultConfidentialStore.java
浏览文件 @
bdcb2fb2
...
...
@@ -140,6 +140,11 @@ public class DefaultConfidentialStore extends ConfidentialStore {
return
new
File
(
rootDir
,
key
.
getId
());
}
@Override
SecureRandom
secureRandom
()
{
return
sr
;
}
public
byte
[]
randomBytes
(
int
size
)
{
byte
[]
random
=
new
byte
[
size
];
sr
.
nextBytes
(
random
);
...
...
core/src/main/java/jenkins/security/RSAConfidentialKey.java
浏览文件 @
bdcb2fb2
...
...
@@ -30,7 +30,6 @@ import java.security.KeyFactory;
import
java.security.KeyPair
;
import
java.security.KeyPairGenerator
;
import
java.security.PrivateKey
;
import
java.security.SecureRandom
;
import
java.security.interfaces.RSAPrivateCrtKey
;
import
java.security.interfaces.RSAPrivateKey
;
import
java.security.interfaces.RSAPublicKey
;
...
...
@@ -79,7 +78,7 @@ public abstract class RSAConfidentialKey extends ConfidentialKey {
byte
[]
payload
=
load
();
if
(
payload
==
null
)
{
KeyPairGenerator
gen
=
KeyPairGenerator
.
getInstance
(
"RSA"
);
gen
.
initialize
(
2048
,
new
S
ecureRandom
());
// going beyond 2048 requires crypto extension
gen
.
initialize
(
2048
,
cs
.
s
ecureRandom
());
// going beyond 2048 requires crypto extension
KeyPair
keys
=
gen
.
generateKeyPair
();
priv
=
(
RSAPrivateKey
)
keys
.
getPrivate
();
pub
=
(
RSAPublicKey
)
keys
.
getPublic
();
...
...
core/src/main/java/jenkins/util/AntClassLoader.java
浏览文件 @
bdcb2fb2
...
...
@@ -33,6 +33,7 @@ import org.kohsuke.accmod.Restricted;
import
org.kohsuke.accmod.restrictions.NoExternalUse
;
import
edu.umd.cs.findbugs.annotations.CheckForNull
;
import
edu.umd.cs.findbugs.annotations.NonNull
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.IOException
;
...
...
@@ -766,6 +767,30 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
return
parent
==
null
?
super
.
getResourceAsStream
(
name
)
:
parent
.
getResourceAsStream
(
name
);
}
@FunctionalInterface
private
interface
Converter
<
T
>
{
T
convert
(
@NonNull
JarFile
jarFile
,
@NonNull
JarEntry
entry
)
throws
IOException
;
}
@CheckForNull
private
<
T
>
T
storeAndConvert
(
JarFile
jarFile
,
File
file
,
String
resourceName
,
Converter
<
T
>
converter
)
throws
IOException
{
if
(
jarFile
==
null
)
{
if
(
file
.
exists
())
{
jarFile
=
new
JarFile
(
file
);
jarFiles
.
put
(
file
,
jarFile
);
}
else
{
return
null
;
}
//to eliminate a race condition, retrieve the entry
//that is in the hash table under that filename
jarFile
=
(
JarFile
)
jarFiles
.
get
(
file
);
}
JarEntry
entry
=
jarFile
.
getJarEntry
(
resourceName
);
if
(
entry
==
null
)
return
null
;
return
converter
.
convert
(
jarFile
,
entry
);
}
/**
* Returns an inputstream to a given resource in the given file which may
* either be a directory or a zip file.
...
...
@@ -787,21 +812,7 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
return
Files
.
newInputStream
(
resource
.
toPath
());
}
}
else
{
if
(
jarFile
==
null
)
{
if
(
file
.
exists
())
{
jarFile
=
new
JarFile
(
file
);
jarFiles
.
put
(
file
,
jarFile
);
}
else
{
return
null
;
}
//to eliminate a race condition, retrieve the entry
//that is in the hash table under that filename
jarFile
=
(
JarFile
)
jarFiles
.
get
(
file
);
}
JarEntry
entry
=
jarFile
.
getJarEntry
(
resourceName
);
if
(
entry
!=
null
)
{
return
jarFile
.
getInputStream
(
entry
);
}
return
storeAndConvert
(
jarFile
,
file
,
resourceName
,
JarFile:
:
getInputStream
);
}
}
catch
(
Exception
e
)
{
log
(
"Ignoring Exception "
+
e
.
getClass
().
getName
()
+
": "
+
e
.
getMessage
()
...
...
@@ -1019,24 +1030,13 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
}
}
}
else
{
if
(
jarFile
==
null
)
{
if
(
file
.
exists
())
{
jarFile
=
new
JarFile
(
file
);
jarFiles
.
put
(
file
,
jarFile
);
}
else
{
return
null
;
}
// potential race-condition
jarFile
=
(
JarFile
)
jarFiles
.
get
(
file
);
}
JarEntry
entry
=
jarFile
.
getJarEntry
(
resourceName
);
if
(
entry
!=
null
)
{
return
storeAndConvert
(
jarFile
,
file
,
resourceName
,
(
jar
,
entry
)
->
{
try
{
return
new
URL
(
"jar:"
+
FILE_UTILS
.
getFileURL
(
file
)
+
"!/"
+
entry
);
}
catch
(
MalformedURLException
ex
)
{
return
null
;
}
}
}
);
}
}
catch
(
Exception
e
)
{
String
msg
=
"Unable to obtain resource from "
+
file
+
": "
;
...
...
core/src/main/resources/hudson/ProxyConfiguration/config.groovy
浏览文件 @
bdcb2fb2
...
...
@@ -22,5 +22,5 @@ f.advanced(){
f
.
textbox
()
}
f
.
validateButton
(
title:
_
(
"Validate Proxy"
),
method:
"validateProxy"
,
with:
"testUrl,name,port,userName,
p
assword,noProxyHost"
)
method:
"validateProxy"
,
with:
"testUrl,name,port,userName,
secretP
assword,noProxyHost"
)
}
core/src/test/java/hudson/BulkChangeTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -37,7 +37,7 @@ import java.io.IOException;
*/
public
class
BulkChangeTest
{
private
class
Point
implements
Saveable
{
private
static
class
Point
implements
Saveable
{
/**
* Don't actually do any save, but just remember how many the actual I/O would have happened.
*/
...
...
core/src/test/java/hudson/model/AbstractItemTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -16,7 +16,7 @@ import org.jvnet.hudson.test.Issue;
@SuppressWarnings
(
"unchecked"
)
public
class
AbstractItemTest
{
private
class
StubAbstractItem
extends
AbstractItem
{
private
static
class
StubAbstractItem
extends
AbstractItem
{
protected
StubAbstractItem
()
{
// sending in null as parent as I don't care for my current tests
...
...
@@ -91,7 +91,7 @@ public class AbstractItemTest {
assertEquals
(
displayName
,
i
.
getDisplayName
());
}
private
class
NameNotEditableItem
extends
AbstractItem
{
private
static
class
NameNotEditableItem
extends
AbstractItem
{
protected
NameNotEditableItem
(
ItemGroup
parent
,
String
name
){
super
(
parent
,
name
);
...
...
core/src/test/java/hudson/model/EnvironmentContributingActionTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -11,7 +11,7 @@ import static org.mockito.Mockito.when;
public
class
EnvironmentContributingActionTest
{
class
OverrideRun
extends
InvisibleAction
implements
EnvironmentContributingAction
{
static
class
OverrideRun
extends
InvisibleAction
implements
EnvironmentContributingAction
{
private
boolean
wasCalled
=
false
;
@Override
...
...
@@ -24,7 +24,7 @@ public class EnvironmentContributingActionTest {
}
}
class
OverrideAbstractBuild
extends
InvisibleAction
implements
EnvironmentContributingAction
{
static
class
OverrideAbstractBuild
extends
InvisibleAction
implements
EnvironmentContributingAction
{
private
boolean
wasCalled
=
false
;
@Override
...
...
@@ -38,7 +38,7 @@ public class EnvironmentContributingActionTest {
}
}
class
OverrideBoth
extends
InvisibleAction
implements
EnvironmentContributingAction
{
static
class
OverrideBoth
extends
InvisibleAction
implements
EnvironmentContributingAction
{
private
boolean
wasCalledAbstractBuild
=
false
;
private
boolean
wasCalledRun
=
false
;
...
...
core/src/test/java/hudson/model/FingerprintCleanupThreadTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -107,7 +107,7 @@ public class FingerprintCleanupThreadTest {
tempDirectory
.
toFile
().
deleteOnExit
();
}
private
class
TestTaskListener
implements
TaskListener
{
private
static
class
TestTaskListener
implements
TaskListener
{
private
ByteArrayOutputStream
outputStream
=
new
ByteArrayOutputStream
();
private
PrintStream
logStream
=
new
PrintStream
(
outputStream
);
...
...
@@ -126,7 +126,6 @@ public class FingerprintCleanupThreadTest {
public
TestFingerprintCleanupThread
(
Fingerprint
fingerprintToLoad
)
throws
IOException
{
this
.
fingerprintToLoad
=
fingerprintToLoad
;
return
;
}
@Override
...
...
@@ -146,7 +145,7 @@ public class FingerprintCleanupThreadTest {
}
private
class
TestFingerprint
extends
Fingerprint
{
private
static
class
TestFingerprint
extends
Fingerprint
{
private
boolean
isAlive
=
true
;
...
...
core/src/test/java/hudson/model/LoadStatisticsTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -101,7 +101,7 @@ public class LoadStatisticsTest {
assertThat
(
LoadStatistics
.
isModern
(
LoadStatistics
.
class
),
is
(
false
));
}
private
class
Modern
extends
LoadStatistics
{
private
static
class
Modern
extends
LoadStatistics
{
protected
Modern
(
int
initialOnlineExecutors
,
int
initialBusyExecutors
)
{
super
(
initialOnlineExecutors
,
initialBusyExecutors
);
...
...
core/src/test/java/hudson/util/CyclicGraphDetectorTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -16,7 +16,7 @@ import java.util.Set;
*/
public
class
CyclicGraphDetectorTest
{
private
class
Edge
{
private
static
class
Edge
{
String
src
,
dst
;
private
Edge
(
String
src
,
String
dst
)
{
...
...
@@ -25,7 +25,7 @@ public class CyclicGraphDetectorTest {
}
}
private
class
Graph
extends
ArrayList
<
Edge
>
{
private
static
class
Graph
extends
ArrayList
<
Edge
>
{
Graph
e
(
String
src
,
String
dst
)
{
add
(
new
Edge
(
src
,
dst
));
return
this
;
...
...
core/src/test/java/hudson/util/IsOverriddenTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -62,7 +62,7 @@ public class IsOverriddenTest {
Util
.
isOverridden
(
Base
.
class
,
Intermediate
.
class
,
"aPrivateMethod"
);
}
public
abstract
class
Base
<
T
>
{
public
static
abstract
class
Base
<
T
>
{
protected
abstract
void
method
();
private
void
aPrivateMethod
()
{}
public
void
setX
(
T
t
)
{}
...
...
core/src/test/java/hudson/util/MockSecretRule.java
已删除
100644 → 0
浏览文件 @
4d3e60a4
package
hudson.util
;
import
hudson.Util
;
import
org.junit.rules.ExternalResource
;
import
java.security.SecureRandom
;
/**
* JUnit rule that cleans that sets a temporary {@link Secret#SECRET} value.
*
* @author Kohsuke Kawaguchi
*/
public
class
MockSecretRule
extends
ExternalResource
{
private
String
value
;
@Override
protected
void
before
()
throws
Throwable
{
byte
[]
random
=
new
byte
[
32
];
sr
.
nextBytes
(
random
);
value
=
Util
.
toHexString
(
random
);
Secret
.
SECRET
=
value
;
}
@Override
protected
void
after
()
{
if
(!
Secret
.
SECRET
.
equals
(
value
))
throw
new
IllegalStateException
(
"Someone tinkered with Secret.SECRET"
);
Secret
.
SECRET
=
null
;
}
private
static
final
SecureRandom
sr
=
new
SecureRandom
();
}
core/src/test/java/hudson/util/SecretRewriterTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -22,9 +22,6 @@ import org.junit.rules.TemporaryFolder;
public
class
SecretRewriterTest
{
@Rule
public
MockSecretRule
mockSecretRule
=
new
MockSecretRule
();
@Rule
public
ConfidentialStoreRule
confidentialStoreRule
=
new
ConfidentialStoreRule
();
...
...
core/src/test/java/hudson/util/SecretTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -43,9 +43,6 @@ public class SecretTest {
@Rule
public
ConfidentialStoreRule
confidentialStore
=
new
ConfidentialStoreRule
();
@Rule
public
MockSecretRule
mockSecretRule
=
new
MockSecretRule
();
private
static
final
Pattern
ENCRYPTED_VALUE_PATTERN
=
Pattern
.
compile
(
"\\{?[A-Za-z0-9+/]+={0,2}}?"
);
@Test
...
...
core/src/test/java/hudson/util/io/TarArchiverTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -136,7 +136,7 @@ public class TarArchiverTest {
t1
.
join
();
}
private
class
GrowingFileRunnable
implements
Runnable
{
private
static
class
GrowingFileRunnable
implements
Runnable
{
private
boolean
finish
=
false
;
private
Exception
ex
=
null
;
private
File
file
;
...
...
core/src/test/java/jenkins/security/ConfidentialStoreRule.java
浏览文件 @
bdcb2fb2
...
...
@@ -2,28 +2,15 @@ package jenkins.security;
import
org.junit.rules.ExternalResource
;
import
org.junit.rules.TemporaryFolder
;
/**
* Test rule that injects a temporary {@link DefaultConfidentialStore}
* @author Kohsuke Kawaguchi
* Test rule that makes {@link ConfidentialStore#get} be reset for each test.
*/
public
class
ConfidentialStoreRule
extends
ExternalResource
{
private
final
TemporaryFolder
tmp
=
new
TemporaryFolder
();
@Override
protected
void
before
()
throws
Throwable
{
tmp
.
create
();
ConfidentialStore
.
TEST
.
set
(
new
DefaultConfidentialStore
(
tmp
.
getRoot
()));
ConfidentialStore
.
Mock
.
INSTANCE
.
clear
();
}
@Override
protected
void
after
()
{
ConfidentialStore
.
TEST
.
set
(
null
);
tmp
.
delete
();
}
static
{
ConfidentialStore
.
TEST
=
new
ThreadLocal
<>();
}
}
core/src/test/java/jenkins/util/MarkFindingOutputStreamTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -84,7 +84,7 @@ public class MarkFindingOutputStreamTest {
m
.
write
(
s
.
charAt
(
i
));
}
class
MarkCountingOutputStream
extends
MarkFindingOutputStream
{
static
class
MarkCountingOutputStream
extends
MarkFindingOutputStream
{
int
count
=
0
;
MarkCountingOutputStream
(
OutputStream
base
)
{
...
...
pom.xml
浏览文件 @
bdcb2fb2
...
...
@@ -76,7 +76,7 @@ THE SOFTWARE.
</issueManagement>
<properties>
<revision>
2.2
29
</revision>
<revision>
2.2
30
</revision>
<changelist>
-SNAPSHOT
</changelist>
<!-- *.html files are in UTF-8, and *.properties are in iso-8859-1, so this configuration is actually incorrect,
...
...
test/src/test/java/hudson/ExtensionListListenerTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -56,7 +56,7 @@ public class ExtensionListListenerTest {
Assert
.
assertEquals
(
1
,
listListener
.
onChangeCallCount
);
}
private
class
MyExtensionListListener
extends
ExtensionListListener
{
private
static
class
MyExtensionListListener
extends
ExtensionListListener
{
private
int
onChangeCallCount
=
0
;
@Override
public
void
onChange
()
{
...
...
test/src/test/java/hudson/model/ApiSEC1704Test.java
浏览文件 @
bdcb2fb2
...
...
@@ -99,7 +99,7 @@ public class ApiSEC1704Test {
}
@ExportedBean
class
CustomData
{
static
class
CustomData
{
private
String
secret
;
CustomData
(
String
secret
){
this
.
secret
=
secret
;
...
...
test/src/test/java/hudson/model/UpdateCenterConnectionStatusTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -124,7 +124,7 @@ public class UpdateCenterConnectionStatusTest {
Assert
.
assertEquals
(
ConnectionStatus
.
FAILED
,
job
.
connectionStates
.
get
(
ConnectionStatus
.
UPDATE_SITE
));
}
private
class
TestConfig
extends
UpdateCenter
.
UpdateCenterConfiguration
{
private
static
class
TestConfig
extends
UpdateCenter
.
UpdateCenterConfiguration
{
private
IOException
checkConnectionException
;
private
IOException
checkUpdateCenterException
;
...
...
test/src/test/java/hudson/security/SecurityRealmTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -72,7 +72,7 @@ public class SecurityRealmTest {
assertThat
(
response
.
getResponseHeaderValue
(
"Expires"
),
is
(
"0"
));
}
private
class
DummyCaptcha
extends
CaptchaSupport
{
private
static
class
DummyCaptcha
extends
CaptchaSupport
{
@Override
public
boolean
validateCaptcha
(
String
id
,
String
text
)
{
return
false
;
...
...
test/src/test/java/hudson/security/WhoAmITest.java
浏览文件 @
bdcb2fb2
...
...
@@ -201,7 +201,7 @@ public class WhoAmITest {
)));
}
private
class
SecurityRealmImpl
extends
AbstractPasswordBasedSecurityRealm
{
private
static
class
SecurityRealmImpl
extends
AbstractPasswordBasedSecurityRealm
{
@Override
protected
UserDetails
authenticate
(
String
username
,
String
password
)
throws
AuthenticationException
{
...
...
test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -136,7 +136,7 @@ public class ZipExtractionInstallerTest {
assertThat
(
lastRequest
.
getResponseText
(),
containsString
(
Messages
.
ZipExtractionInstaller_malformed_url
()));
}
private
class
SpyingJavaScriptEngine
extends
JavaScriptEngine
{
private
static
class
SpyingJavaScriptEngine
extends
JavaScriptEngine
{
private
List
<
XMLHttpRequest
>
storedRequests
=
new
ArrayList
<>();
private
String
urlToMatch
;
private
HttpMethod
method
;
...
...
test/src/test/java/jenkins/agents/WebSocketAgentsTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -103,7 +103,7 @@ public class WebSocketAgentsTest {
assertNotNull
(
s
.
getChannel
().
call
(
new
FatTask
()));
FreeStyleProject
p
=
r
.
createFreeStyleProject
();
p
.
setAssignedNode
(
s
);
p
.
getBuildersList
().
add
(
Functions
.
isWindows
()
?
new
BatchFile
(
"echo hello"
)
:
new
Shell
(
"
dd if=/dev/random count=1024 bs=200
"
));
p
.
getBuildersList
().
add
(
Functions
.
isWindows
()
?
new
BatchFile
(
"echo hello"
)
:
new
Shell
(
"
echo hello
"
));
r
.
buildAndAssertSuccess
(
p
);
s
.
toComputer
().
getLogText
().
writeLogTo
(
0
,
System
.
out
);
}
finally
{
...
...
test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -5,15 +5,35 @@ import hudson.model.FreeStyleProject;
import
hudson.model.Run
;
import
hudson.model.TaskListener
;
import
hudson.tasks.LogRotator
;
import
hudson.util.DescribableList
;
import
org.junit.Assert
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.jvnet.hudson.test.Issue
;
import
org.jvnet.hudson.test.JenkinsRule
;
import
org.jvnet.hudson.test.recipes.LocalData
;
public
class
GlobalBuildDiscarderTest
{
@Rule
public
JenkinsRule
j
=
new
JenkinsRule
();
@Test
@LocalData
@Issue
(
"JENKINS-61688"
)
public
void
testLoading
()
throws
Exception
{
Assert
.
assertEquals
(
0
,
GlobalBuildDiscarderConfiguration
.
get
().
getConfiguredBuildDiscarders
().
size
());
}
@Test
@LocalData
@Issue
(
"JENKINS-61688"
)
public
void
testLoadingWithDiscarders
()
throws
Exception
{
final
DescribableList
<
GlobalBuildDiscarderStrategy
,
GlobalBuildDiscarderStrategyDescriptor
>
configuredBuildDiscarders
=
GlobalBuildDiscarderConfiguration
.
get
().
getConfiguredBuildDiscarders
();
Assert
.
assertEquals
(
2
,
configuredBuildDiscarders
.
size
());
Assert
.
assertNotNull
(
configuredBuildDiscarders
.
get
(
JobGlobalBuildDiscarderStrategy
.
class
));
Assert
.
assertEquals
(
5
,
((
LogRotator
)
configuredBuildDiscarders
.
get
(
SimpleGlobalBuildDiscarderStrategy
.
class
).
getDiscarder
()).
getNumToKeep
());
}
@Test
public
void
testJobBuildDiscarder
()
throws
Exception
{
FreeStyleProject
p
=
j
.
createFreeStyleProject
();
...
...
test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -19,9 +19,12 @@ import javax.inject.Inject;
import
java.io.File
;
import
java.io.IOException
;
import
java.lang.annotation.Annotation
;
import
java.nio.charset.StandardCharsets
;
import
java.util.Base64
;
import
java.util.regex.Pattern
;
import
java.util.stream.Stream
;
import
org.hamcrest.MatcherAssert
;
import
org.hamcrest.Matchers
;
/**
* @author Kohsuke Kawaguchi
...
...
@@ -81,7 +84,7 @@ public class RekeySecretAdminMonitorTest extends HudsonTestCase {
private
void
verifyRewrite
(
File
dir
)
throws
Exception
{
File
xml
=
new
File
(
dir
,
"foo.xml"
);
Pattern
pattern
=
Pattern
.
compile
(
"<foo>"
+
plain_regex_match
+
"</foo>"
);
assertTrue
(
pattern
.
matcher
(
FileUtils
.
readFileToString
(
xml
).
trim
()).
matches
(
));
MatcherAssert
.
assertThat
(
FileUtils
.
readFileToString
(
xml
,
StandardCharsets
.
UTF_8
).
trim
(),
Matchers
.
matchesRegex
(
pattern
));
}
// TODO sometimes fails: "Invalid request submission: {json=[Ljava.lang.String;@2c46358e, .crumb=[Ljava.lang.String;@35661457}"
...
...
test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java
浏览文件 @
bdcb2fb2
...
...
@@ -73,7 +73,7 @@ public class DoActionFilterTest extends StaplerAbstractTest {
private
TestAccessModifier
getPrivate
()
{
return
new
TestAccessModifier
();}
public
class
TestAccessModifier
{
public
static
class
TestAccessModifier
{
@GET
public
String
doValue
()
{
return
"hello"
;
...
...
test/src/test/resources/jenkins/model/GlobalBuildDiscarderTest/testLoading/jenkins.model.GlobalBuildDiscarderConfiguration.xml
0 → 100644
浏览文件 @
bdcb2fb2
<?xml version='1.1' encoding='UTF-8'?>
<jenkins.model.GlobalBuildDiscarderConfiguration>
<configuredBuildDiscarders/>
</jenkins.model.GlobalBuildDiscarderConfiguration>
\ No newline at end of file
test/src/test/resources/jenkins/model/GlobalBuildDiscarderTest/testLoadingWithDiscarders/jenkins.model.GlobalBuildDiscarderConfiguration.xml
0 → 100644
浏览文件 @
bdcb2fb2
<?xml version='1.1' encoding='UTF-8'?>
<jenkins.model.GlobalBuildDiscarderConfiguration>
<configuredBuildDiscarders>
<jenkins.model.JobGlobalBuildDiscarderStrategy/>
<jenkins.model.SimpleGlobalBuildDiscarderStrategy>
<discarder
class=
"hudson.tasks.LogRotator"
>
<daysToKeep>
-1
</daysToKeep>
<numToKeep>
5
</numToKeep>
<artifactDaysToKeep>
-1
</artifactDaysToKeep>
<artifactNumToKeep>
-1
</artifactNumToKeep>
</discarder>
</jenkins.model.SimpleGlobalBuildDiscarderStrategy>
</configuredBuildDiscarders>
</jenkins.model.GlobalBuildDiscarderConfiguration>
\ No newline at end of file
war/src/main/webapp/css/layout-common.css
已删除
100644 → 0
浏览文件 @
4d3e60a4
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, 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.
*/
html
{
position
:
relative
;
min-height
:
100%
;
}
body
{
margin
:
0
;
padding
:
0
0
40px
0
;
}
/* --------------- header --------------- */
#header
{
background-color
:
#000000
;
height
:
40px
;
}
#header
div
{
display
:
inline-block
;
height
:
inherit
;
}
#header
.logo
{
margin-left
:
16px
;
}
#jenkins-home-link
{
position
:
absolute
;
height
:
40px
;
}
#jenkins-head-icon
{
position
:
absolute
;
bottom
:
0px
;
}
#jenkins-name-icon
{
position
:
absolute
;
bottom
:
3px
;
left
:
32px
;
}
#header
.searchbox
,
#header
.login
{
float
:
right
;
padding
:
6px
11px
;
}
#breadcrumbBar
,
#footer-container
,
.top-sticker-inner
{
background-color
:
#f6faf2
;
}
/* -------------------------------------- */
#page-body
.clear
:after
{
clear
:
both
;
content
:
""
;
display
:
table
;
}
#side-panel
{
padding
:
15px
15px
40px
15px
;
float
:
left
;
width
:
320px
;
}
#main-panel
{
padding
:
15px
15px
40px
15px
;
}
body
.two-column
#main-panel
{
margin-left
:
320px
;
display
:
block
;
}
body
.full-screen
{
padding
:
0
;
}
body
.full-screen
#main-panel
{
padding
:
0
;
}
@media
(
max-width
:
970px
)
{
body
.two-column
#side-panel
{
width
:
100%
;
float
:
none
;
padding-bottom
:
20px
;
}
body
.two-column
#main-panel
{
margin-left
:
0
;
display
:
block
;
}
}
@media
(
min-width
:
1170px
)
{
body
.two-column
#side-panel
{
width
:
360px
;
}
body
.two-column
#main-panel
{
margin-left
:
360px
;
display
:
block
;
}
}
/* --------------- footer --------------- */
footer
{
padding
:
11px
0
;
background-color
:
#f6faf2
;
border-top
:
1px
solid
#d3d7cf
;
border-bottom
:
1px
solid
#f6faf2
;
width
:
100%
;
position
:
absolute
;
bottom
:
0
;
left
:
0
;
clear
:
both
;
font-size
:
12px
;
text-align
:
right
;
}
footer
span
{
margin-left
:
15px
;
line-height
:
14px
;
}
/* -------------------------------------- */
war/src/main/webapp/css/style.css
已删除
100644 → 0
浏览文件 @
4d3e60a4
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录