Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
380b7269
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,发现更多精彩内容 >>
提交
380b7269
编写于
1月 13, 2011
作者:
O
Olivier Lamy
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of github.com:hudson/hudson
上级
520900ae
5b8f4723
变更
65
隐藏空白更改
内联
并排
Showing
65 changed file
with
1638 addition
and
302 deletion
+1638
-302
changelog.html
changelog.html
+15
-7
cli/pom.xml
cli/pom.xml
+1
-1
core/pom.xml
core/pom.xml
+4
-4
core/src/main/java/hudson/Functions.java
core/src/main/java/hudson/Functions.java
+5
-0
core/src/main/java/hudson/cli/CLICommand.java
core/src/main/java/hudson/cli/CLICommand.java
+21
-0
core/src/main/java/hudson/cli/GroovyCommand.java
core/src/main/java/hudson/cli/GroovyCommand.java
+14
-0
core/src/main/java/hudson/matrix/MatrixProject.java
core/src/main/java/hudson/matrix/MatrixProject.java
+19
-10
core/src/main/java/hudson/model/AbstractItem.java
core/src/main/java/hudson/model/AbstractItem.java
+18
-2
core/src/main/java/hudson/model/Computer.java
core/src/main/java/hudson/model/Computer.java
+2
-2
core/src/main/java/hudson/model/DescriptorVisibilityFilter.java
...rc/main/java/hudson/model/DescriptorVisibilityFilter.java
+54
-0
core/src/main/java/hudson/model/EnvironmentContributingAction.java
...main/java/hudson/model/EnvironmentContributingAction.java
+9
-5
core/src/main/java/hudson/model/ExternalJob.java
core/src/main/java/hudson/model/ExternalJob.java
+5
-6
core/src/main/java/hudson/model/FreeStyleProject.java
core/src/main/java/hudson/model/FreeStyleProject.java
+9
-7
core/src/main/java/hudson/model/Hudson.java
core/src/main/java/hudson/model/Hudson.java
+94
-155
core/src/main/java/hudson/model/ItemGroup.java
core/src/main/java/hudson/model/ItemGroup.java
+5
-0
core/src/main/java/hudson/model/ItemGroupMixIn.java
core/src/main/java/hudson/model/ItemGroupMixIn.java
+186
-3
core/src/main/java/hudson/model/Items.java
core/src/main/java/hudson/model/Items.java
+4
-2
core/src/main/java/hudson/model/Job.java
core/src/main/java/hudson/model/Job.java
+1
-0
core/src/main/java/hudson/model/ListView.java
core/src/main/java/hudson/model/ListView.java
+1
-1
core/src/main/java/hudson/model/TopLevelItem.java
core/src/main/java/hudson/model/TopLevelItem.java
+5
-7
core/src/main/java/hudson/model/TopLevelItemDescriptor.java
core/src/main/java/hudson/model/TopLevelItemDescriptor.java
+14
-2
core/src/main/java/hudson/model/User.java
core/src/main/java/hudson/model/User.java
+9
-6
core/src/main/java/hudson/model/ViewJob.java
core/src/main/java/hudson/model/ViewJob.java
+7
-0
core/src/main/java/hudson/security/FederatedLoginService.java
.../src/main/java/hudson/security/FederatedLoginService.java
+256
-0
core/src/main/java/hudson/security/FederatedLoginServiceUserProperty.java
...va/hudson/security/FederatedLoginServiceUserProperty.java
+59
-0
core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java
...main/java/hudson/security/HudsonPrivateSecurityRealm.java
+59
-8
core/src/main/java/hudson/security/SecurityRealm.java
core/src/main/java/hudson/security/SecurityRealm.java
+24
-0
core/src/main/java/hudson/slaves/RetentionStrategy.java
core/src/main/java/hudson/slaves/RetentionStrategy.java
+1
-1
core/src/main/resources/hudson/model/ComputerSet/index.jelly
core/src/main/resources/hudson/model/ComputerSet/index.jelly
+1
-1
core/src/main/resources/hudson/model/Hudson/login.jelly
core/src/main/resources/hudson/model/Hudson/login.jelly
+6
-0
core/src/main/resources/hudson/model/User/configure.jelly
core/src/main/resources/hudson/model/User/configure.jelly
+10
-8
core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error.jelly
...eratedLoginService/UnclaimedIdentityException/error.jelly
+36
-0
core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error.properties
...dLoginService/UnclaimedIdentityException/error.properties
+6
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly
...dson/security/HudsonPrivateSecurityRealm/_entryForm.jelly
+1
-1
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly
...sonPrivateSecurityRealm/signupWithFederatedIdentity.jelly
+30
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_da.properties
...teSecurityRealm/signupWithFederatedIdentity_da.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_de.properties
...teSecurityRealm/signupWithFederatedIdentity_de.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_es.properties
...teSecurityRealm/signupWithFederatedIdentity_es.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_fr.properties
...teSecurityRealm/signupWithFederatedIdentity_fr.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_ja.properties
...teSecurityRealm/signupWithFederatedIdentity_ja.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_pt_BR.properties
...ecurityRealm/signupWithFederatedIdentity_pt_BR.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_tr.properties
...teSecurityRealm/signupWithFederatedIdentity_tr.properties
+23
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_zh_CN.properties
...ecurityRealm/signupWithFederatedIdentity_zh_CN.properties
+23
-0
core/src/main/resources/hudson/security/Messages.properties
core/src/main/resources/hudson/security/Messages.properties
+1
-0
core/src/main/resources/hudson/views/BuildButtonColumn/column.jelly
...ain/resources/hudson/views/BuildButtonColumn/column.jelly
+1
-1
core/src/main/resources/lib/hudson/newFromList/form.jelly
core/src/main/resources/lib/hudson/newFromList/form.jelly
+3
-1
maven-agent/pom.xml
maven-agent/pom.xml
+1
-1
maven-interceptor/pom.xml
maven-interceptor/pom.xml
+1
-1
maven-plugin/pom.xml
maven-plugin/pom.xml
+1
-1
maven-plugin/src/main/java/hudson/maven/Maven3Builder.java
maven-plugin/src/main/java/hudson/maven/Maven3Builder.java
+31
-16
maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java
maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java
+10
-6
maven-plugin/src/main/java/hudson/maven/MavenModuleSetBuild.java
...lugin/src/main/java/hudson/maven/MavenModuleSetBuild.java
+21
-14
maven-plugin/src/main/java/hudson/maven/MavenUtil.java
maven-plugin/src/main/java/hudson/maven/MavenUtil.java
+14
-11
maven-plugin/src/main/java/hudson/maven/util/ExecutionEventLogger.java
...src/main/java/hudson/maven/util/ExecutionEventLogger.java
+339
-0
maven3-agent/pom.xml
maven3-agent/pom.xml
+1
-1
maven3-interceptor/pom.xml
maven3-interceptor/pom.xml
+1
-1
pom.xml
pom.xml
+1
-1
remoting/pom.xml
remoting/pom.xml
+1
-1
test/pom.xml
test/pom.xml
+1
-1
test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
+4
-0
test/src/test/java/hudson/maven/Maven3BuildTest.java
test/src/test/java/hudson/maven/Maven3BuildTest.java
+13
-0
test/src/test/java/hudson/maven/MavenMultiModuleTest.java
test/src/test/java/hudson/maven/MavenMultiModuleTest.java
+12
-0
test/src/test/java/hudson/model/QueueTest.java
test/src/test/java/hudson/model/QueueTest.java
+3
-3
ui-samples-plugin/pom.xml
ui-samples-plugin/pom.xml
+1
-1
war/pom.xml
war/pom.xml
+2
-2
未找到文件。
changelog.html
浏览文件 @
380b7269
...
...
@@ -39,6 +39,15 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div
id=
"trunk"
style=
"display:none"
>
<!--=TRUNK-BEGIN=-->
<ul
class=
image
>
<li
class=
rfe
>
Added a new extension point to support external login mechanisms.
</ul>
</div>
<!--=TRUNK-END=-->
<!-- these changes are controlled by the release process. DO NOT MODIFY -->
<div
id=
"rc"
style=
"display:none;"
>
<!--=BEGIN=-->
<h3><a
name=
v1.394
>
What's new in 1.394
</a>
<!--=DATE=-->
</h3>
<ul
class=
image
>
<li
class=
bug
>
Parsing poms fails if a module is a path to a pom (and not to a directory)
(
<a
href=
"http://issues.hudson-ci.org/browse/HUDSON-8445"
>
issue 8445
</a>
)
...
...
@@ -54,14 +63,13 @@ Upcoming changes</a>
(
<a
href=
"http://issues.hudson-ci.org/browse/HUDSON-8462"
>
issue 8462
</a>
)
<li
class=
rfe
>
Block build when downstream projects are building.
(
<a
href=
"http://issues.hudson-ci.org/browse/HUDSON-7046"
>
issue 7046
</a>
)
(
<a
href=
"http://issues.hudson-ci.org/browse/HUDSON-7046"
>
issue 7046
</a>
)
<li
class=
bug
>
nonRecursive option is not honored anymore when parsing pom
(
<a
href=
"http://issues.hudson-ci.org/browse/HUDSON-8484"
>
issue 8484
</a>
)
<li
class=
ref
>
Maven 3 support : display same logging output as a maven build with the cli
(
<a
href=
"http://issues.hudson-ci.org/browse/HUDSON-8490"
>
issue 8490
</a>
)
</ul>
</div>
<!--=TRUNK-END=-->
<!-- these changes are controlled by the release process. DO NOT MODIFY -->
<div
id=
"rc"
style=
"display:none;"
>
<!--=BEGIN=-->
<h3><a
name=
v1.394
>
What's new in 1.394
</a>
<!--=DATE=-->
</h3>
<!--=RC-CHANGES=-->
</div>
<!--=END=-->
<h3><a
name=
v1.393
>
What's new in 1.393
</a>
(2011/01/09)
</h3>
<ul
class=
image
>
...
...
cli/pom.xml
浏览文件 @
380b7269
...
...
@@ -4,7 +4,7 @@
<parent>
<artifactId>
pom
</artifactId>
<groupId>
org.jvnet.hudson.main
</groupId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
</parent>
<artifactId>
cli
</artifactId>
<name>
Hudson CLI
</name>
...
...
core/pom.xml
浏览文件 @
380b7269
...
...
@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
<relativePath>
../pom.xml
</relativePath>
</parent>
...
...
@@ -61,7 +61,7 @@ THE SOFTWARE.
<plugin>
<groupId>
com.infradna.tool
</groupId>
<artifactId>
bridge-method-injector
</artifactId>
<version>
1.
3
</version>
<version>
1.
4
</version>
<executions>
<execution>
<goals>
...
...
@@ -410,7 +410,7 @@ THE SOFTWARE.
<dependency>
<groupId>
com.infradna.tool
</groupId>
<artifactId>
bridge-method-annotation
</artifactId>
<version>
1.
2
</version>
<version>
1.
4
</version>
</dependency>
<dependency>
<!-- until we get this version through Stapler -->
...
...
@@ -730,7 +730,7 @@ THE SOFTWARE.
<dependency>
<groupId>
org.jvnet.hudson
</groupId>
<artifactId>
jmdns
</artifactId>
<version>
3.
1.6-hudson-2
</version>
<version>
3.
2.1-hudson-1
</version>
</dependency>
<dependency>
<groupId>
com.sun.winsw
</groupId>
...
...
core/src/main/java/hudson/Functions.java
浏览文件 @
380b7269
...
...
@@ -30,6 +30,7 @@ import hudson.model.AbstractProject;
import
hudson.model.Action
;
import
hudson.model.Describable
;
import
hudson.model.Descriptor
;
import
hudson.model.DescriptorVisibilityFilter
;
import
hudson.model.Hudson
;
import
hudson.model.Item
;
import
hudson.model.ItemGroup
;
...
...
@@ -1273,6 +1274,10 @@ public class Functions {
if
(
o
instanceof
Secret
)
return
((
Secret
)
o
).
getEncryptedValue
();
return
o
.
toString
();
}
public
List
filterDescriptors
(
Object
context
,
Iterable
descriptors
)
{
return
DescriptorVisibilityFilter
.
apply
(
context
,
descriptors
);
}
private
static
final
Pattern
SCHEME
=
Pattern
.
compile
(
"[a-z]+://.+"
);
...
...
core/src/main/java/hudson/cli/CLICommand.java
浏览文件 @
380b7269
...
...
@@ -303,6 +303,27 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable {
private
static
final
long
serialVersionUID
=
1L
;
}
/**
* Convenience method for subtypes to obtain environment variables of the client.
*/
protected
String
getClientEnvironmentVariable
(
String
name
)
throws
IOException
,
InterruptedException
{
return
channel
.
call
(
new
GetEnvironmentVariable
(
name
));
}
private
static
final
class
GetEnvironmentVariable
implements
Callable
<
String
,
IOException
>
{
private
final
String
name
;
private
GetEnvironmentVariable
(
String
name
)
{
this
.
name
=
name
;
}
public
String
call
()
throws
IOException
{
return
System
.
getenv
(
name
);
}
private
static
final
long
serialVersionUID
=
1L
;
}
/**
* Creates a clone to be used to execute a command.
*/
...
...
core/src/main/java/hudson/cli/GroovyCommand.java
浏览文件 @
380b7269
...
...
@@ -25,7 +25,10 @@ package hudson.cli;
import
groovy.lang.GroovyShell
;
import
groovy.lang.Binding
;
import
hudson.model.AbstractProject
;
import
hudson.model.Hudson
;
import
hudson.model.Item
;
import
hudson.model.Run
;
import
hudson.remoting.Callable
;
import
hudson.AbortException
;
import
hudson.Extension
;
...
...
@@ -71,6 +74,17 @@ public class GroovyCommand extends CLICommand implements Serializable {
Binding
binding
=
new
Binding
();
binding
.
setProperty
(
"out"
,
new
PrintWriter
(
stdout
,
true
));
String
j
=
getClientEnvironmentVariable
(
"JOB_NAME"
);
if
(
j
!=
null
)
{
Item
job
=
Hudson
.
getInstance
().
getItemByFullName
(
j
);
binding
.
setProperty
(
"currentJob"
,
job
);
String
b
=
getClientEnvironmentVariable
(
"BUILD_NUMBER"
);
if
(
b
!=
null
&&
job
instanceof
AbstractProject
)
{
Run
r
=
((
AbstractProject
)
job
).
getBuildByNumber
(
Integer
.
parseInt
(
b
));
binding
.
setProperty
(
"currentBuild"
,
r
);
}
}
GroovyShell
groovy
=
new
GroovyShell
(
binding
);
groovy
.
run
(
loadScript
(),
"RemoteClass"
,
remaining
.
toArray
(
new
String
[
remaining
.
size
()]));
return
0
;
...
...
core/src/main/java/hudson/matrix/MatrixProject.java
浏览文件 @
380b7269
...
...
@@ -40,6 +40,7 @@ import hudson.model.Items;
import
hudson.model.JDK
;
import
hudson.model.Job
;
import
hudson.model.Label
;
import
hudson.model.Node
;
import
hudson.model.Queue.FlyweightTask
;
import
hudson.model.ResourceController
;
import
hudson.model.Result
;
...
...
@@ -55,6 +56,8 @@ import hudson.tasks.Publisher;
import
hudson.triggers.Trigger
;
import
hudson.util.CopyOnWriteMap
;
import
hudson.util.DescribableList
;
import
hudson.util.FormValidation
;
import
hudson.util.FormValidation.Kind
;
import
net.sf.json.JSONObject
;
import
org.kohsuke.stapler.HttpResponse
;
import
org.kohsuke.stapler.StaplerRequest
;
...
...
@@ -93,7 +96,7 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
private
volatile
AxisList
axes
=
new
AxisList
();
/**
* The filter that is applied to combinatios. It is a Groovy if condition.
* The filter that is applied to combinatio
n
s. It is a Groovy if condition.
* This can be null, which means "true".
*
* @see #getCombinationFilter()
...
...
@@ -148,7 +151,11 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
private
String
customWorkspace
;
public
MatrixProject
(
String
name
)
{
super
(
Hudson
.
getInstance
(),
name
);
this
(
Hudson
.
getInstance
(),
name
);
}
public
MatrixProject
(
ItemGroup
parent
,
String
name
)
{
super
(
parent
,
name
);
}
public
AxisList
getAxes
()
{
...
...
@@ -460,6 +467,10 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
throw
new
UnsupportedOperationException
();
}
public
void
onDeleted
(
MatrixConfiguration
item
)
throws
IOException
{
// noop
}
public
File
getRootDirFor
(
Combination
combination
)
{
File
f
=
getConfigurationsDir
();
for
(
Entry
<
String
,
String
>
e
:
combination
.
entrySet
())
...
...
@@ -468,11 +479,6 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
return
f
;
}
@Override
public
Hudson
getParent
()
{
return
Hudson
.
getInstance
();
}
/**
* @see #getJDKs()
*/
...
...
@@ -617,7 +623,10 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
private
void
checkAxisNames
(
Iterable
<
Axis
>
newAxes
)
throws
FormException
{
HashSet
<
String
>
axisNames
=
new
HashSet
<
String
>();
for
(
Axis
a
:
newAxes
)
{
a
.
getDescriptor
().
doCheckName
(
a
.
getName
());
FormValidation
fv
=
a
.
getDescriptor
().
doCheckName
(
a
.
getName
());
if
(
fv
.
kind
!=
Kind
.
OK
)
throw
new
FormException
(
Messages
.
MatrixProject_DuplicateAxisName
(),
fv
,
"axis.name"
);
if
(
axisNames
.
contains
(
a
.
getName
()))
throw
new
FormException
(
Messages
.
MatrixProject_DuplicateAxisName
(),
"axis.name"
);
axisNames
.
add
(
a
.
getName
());
...
...
@@ -648,8 +657,8 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
return
Messages
.
MatrixProject_DisplayName
();
}
public
MatrixProject
newInstance
(
String
name
)
{
return
new
MatrixProject
(
name
);
public
MatrixProject
newInstance
(
ItemGroup
parent
,
String
name
)
{
return
new
MatrixProject
(
parent
,
name
);
}
/**
...
...
core/src/main/java/hudson/model/AbstractItem.java
浏览文件 @
380b7269
...
...
@@ -24,6 +24,7 @@
*/
package
hudson.model
;
import
com.infradna.tool.bridge_method_injector.WithBridgeMethods
;
import
hudson.XmlFile
;
import
hudson.Util
;
import
hudson.Functions
;
...
...
@@ -115,6 +116,10 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
return
parent
.
getRootDirFor
(
this
);
}
/**
* This bridge method is to maintain binary compatibility with {@link TopLevelItem#getParent()}.
*/
@WithBridgeMethods
(
value
=
Hudson
.
class
,
castRequired
=
true
)
public
ItemGroup
getParent
()
{
assert
parent
!=
null
;
return
parent
;
...
...
@@ -407,12 +412,23 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
checkPermission
(
DELETE
);
performDelete
();
if
(
this
instanceof
TopLevelItem
)
Hudson
.
getInstance
().
deleteJob
((
TopLevelItem
)
this
);
try
{
invokeOnDeleted
();
}
catch
(
AbstractMethodError
e
)
{
// ignore
}
Hudson
.
getInstance
().
rebuildDependencyGraph
();
}
/**
* A pointless function to work around what appears to be a HotSpot problem. See HUDSON-5756 and bug 6933067
* on BugParade for more details.
*/
private
void
invokeOnDeleted
()
throws
IOException
{
getParent
().
onDeleted
(
this
);
}
/**
* Does the real job of deleting the item.
*/
...
...
core/src/main/java/hudson/model/Computer.java
浏览文件 @
380b7269
...
...
@@ -511,9 +511,9 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
@Exported
public
String
getIcon
()
{
if
(
isOffline
())
return
"computer-x.
gif
"
;
return
"computer-x.
png
"
;
else
return
"computer.
gif
"
;
return
"computer.
png
"
;
}
public
String
getIconAltText
()
{
...
...
core/src/main/java/hudson/model/DescriptorVisibilityFilter.java
0 → 100644
浏览文件 @
380b7269
package
hudson.model
;
import
hudson.ExtensionList
;
import
hudson.ExtensionPoint
;
import
hudson.scm.SCMDescriptor
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* Hides {@link Descriptor}s from users.
*
* @author Kohsuke Kawaguchi
* @since 1.393
*/
public
abstract
class
DescriptorVisibilityFilter
implements
ExtensionPoint
{
/**
* Decides if the given descriptor should be visible to the user.
*
* @param context
* The object that indicates where the visibility of a descriptor is evaluated.
* For example, if Hudson is deciding whether a {@link FreeStyleProject} should gets a
* {@link SCMDescriptor}, the context object will be the {@link FreeStyleProject}.
* The caller can pass in null if there's no context.
* @param descriptor
* Descriptor whose visibility is evaluated. Never null.
*
* @return
* true to allow the descriptor to be visible. false to hide it.
* If any of the installed {@link DescriptorVisibilityFilter} returns false,
* the descriptor is not shown.
*/
public
abstract
boolean
filter
(
Object
context
,
Descriptor
descriptor
);
public
static
ExtensionList
<
DescriptorVisibilityFilter
>
all
()
{
return
Hudson
.
getInstance
().
getExtensionList
(
DescriptorVisibilityFilter
.
class
);
}
public
static
<
T
extends
Descriptor
>
List
<
T
>
apply
(
Object
context
,
Iterable
<
T
>
source
)
{
ExtensionList
<
DescriptorVisibilityFilter
>
filters
=
all
();
List
<
T
>
r
=
new
ArrayList
<
T
>();
OUTER:
for
(
T
d
:
source
)
{
for
(
DescriptorVisibilityFilter
f
:
filters
)
{
if
(!
f
.
filter
(
context
,
d
))
continue
OUTER
;
// veto-ed. not shown
}
r
.
add
(
d
);
}
return
r
;
}
}
core/src/main/java/hudson/model/EnvironmentContributingAction.java
浏览文件 @
380b7269
...
...
@@ -24,12 +24,20 @@
package
hudson.model
;
import
hudson.EnvVars
;
import
hudson.model.Queue.Task
;
import
hudson.tasks.Builder
;
import
hudson.tasks.BuildWrapper
;
/**
* {@link Action} that contributes environment variables during a build.
*
* <p>
* For example, your {@link Builder} can add an {@link EnvironmentContributingAction} so that
* the rest of the builders or publishers see some behavior changes.
*
* Another use case is for you to {@linkplain Queue#schedule(Task, int, Action...) submit a job} with
* {@link EnvironmentContributingAction}s.
*
* @author Kohsuke Kawaguchi
* @since 1.318
* @see AbstractBuild#getEnvironment(TaskListener)
...
...
@@ -39,14 +47,10 @@ public interface EnvironmentContributingAction extends Action {
/**
* Called by {@link AbstractBuild} to allow plugins to contribute environment variables.
*
* <p>
* For example, your {@link Builder} can add an {@link EnvironmentContributingAction} so that
* the rest of the builders or publishers see some behavior changes.
*
* @param build
* The calling build. Never null.
* @param env
* Evironment variables should be added to this map.
* E
n
vironment variables should be added to this map.
*/
public
void
buildEnvVars
(
AbstractBuild
<?,?>
build
,
EnvVars
env
);
}
core/src/main/java/hudson/model/ExternalJob.java
浏览文件 @
380b7269
...
...
@@ -42,12 +42,11 @@ import java.io.IOException;
*/
public
class
ExternalJob
extends
ViewJob
<
ExternalJob
,
ExternalRun
>
implements
TopLevelItem
{
public
ExternalJob
(
String
name
)
{
super
(
Hudson
.
getInstance
(),
name
);
this
(
Hudson
.
getInstance
(),
name
);
}
@Override
public
Hudson
getParent
()
{
return
(
Hudson
)
super
.
getParent
();
public
ExternalJob
(
ItemGroup
parent
,
String
name
)
{
super
(
parent
,
name
);
}
@Override
...
...
@@ -119,8 +118,8 @@ public class ExternalJob extends ViewJob<ExternalJob,ExternalRun> implements Top
return
Messages
.
ExternalJob_DisplayName
();
}
public
ExternalJob
newInstance
(
String
name
)
{
return
new
ExternalJob
(
name
);
public
ExternalJob
newInstance
(
ItemGroup
parent
,
String
name
)
{
return
new
ExternalJob
(
parent
,
name
);
}
}
}
core/src/main/java/hudson/model/FreeStyleProject.java
浏览文件 @
380b7269
...
...
@@ -46,18 +46,20 @@ public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> i
*/
private
String
customWorkspace
;
/**
* @deprecated as of 1.390
*/
public
FreeStyleProject
(
Hudson
parent
,
String
name
)
{
super
(
parent
,
name
);
}
@Override
protected
Class
<
FreeStyleBuild
>
getBuildClass
()
{
return
FreeStyleBuild
.
class
;
public
FreeStyleProject
(
ItemGroup
parent
,
String
name
)
{
super
(
parent
,
name
);
}
@Override
p
ublic
Hudson
getParent
()
{
return
Hudson
.
getInstance
()
;
p
rotected
Class
<
FreeStyleBuild
>
getBuildClass
()
{
return
FreeStyleBuild
.
class
;
}
public
String
getCustomWorkspace
()
{
...
...
@@ -109,8 +111,8 @@ public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> i
return
Messages
.
FreeStyleProject_DisplayName
();
}
public
FreeStyleProject
newInstance
(
String
name
)
{
return
new
FreeStyleProject
(
Hudson
.
getInstance
()
,
name
);
public
FreeStyleProject
newInstance
(
ItemGroup
parent
,
String
name
)
{
return
new
FreeStyleProject
(
parent
,
name
);
}
}
}
core/src/main/java/hudson/model/Hudson.java
浏览文件 @
380b7269
/*
* The MIT License
*
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Erik Ramfelt, Koichi Fujikawa, Red Hat, Inc., Seiji Sogabe,
* Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Alan Harder
*
*
* 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
...
...
@@ -81,6 +81,7 @@ import hudson.security.ACL;
import
hudson.security.AccessControlled
;
import
hudson.security.AuthorizationStrategy
;
import
hudson.security.BasicAuthenticationFilter
;
import
hudson.security.FederatedLoginService
;
import
hudson.security.HudsonFilter
;
import
hudson.security.LegacyAuthorizationStrategy
;
import
hudson.security.LegacySecurityRealm
;
...
...
@@ -125,7 +126,6 @@ import hudson.util.TextFile;
import
hudson.util.VersionNumber
;
import
hudson.util.XStream2
;
import
hudson.util.Service
;
import
hudson.util.IOUtils
;
import
hudson.views.DefaultMyViewsTabBar
;
import
hudson.views.DefaultViewsTabBar
;
import
hudson.views.MyViewsTabBar
;
...
...
@@ -263,7 +263,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*/
// this field needs to be at the very top so that other components can look at this value even during unmarshalling
private
String
version
=
"1.0"
;
/**
* Number of executors of the master node.
*/
...
...
@@ -419,9 +419,9 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* This is {@link Integer} so that we can initialize it to '5' for upgrading users.
*/
/*package*/
Integer
quietPeriod
;
/**
* Global default for {@link AbstractProject#getScmCheckoutRetryCount()}
* Global default for {@link AbstractProject#getScmCheckoutRetryCount()}
*/
/*package*/
int
scmCheckoutRetryCount
;
...
...
@@ -483,7 +483,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* {@link hudson.security.csrf.CrumbIssuer}
*/
private
volatile
CrumbIssuer
crumbIssuer
;
/**
* All labels known to Hudson. This allows us to reuse the same label instances
* as much as possible, even though that's not a strict requirement.
...
...
@@ -538,6 +538,39 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*/
private
transient
final
AdjunctManager
adjuncts
;
/**
* Code that handles {@link ItemGroup} work.
*/
private
transient
final
ItemGroupMixIn
itemGroupMixIn
=
new
ItemGroupMixIn
(
this
,
this
)
{
@Override
protected
void
add
(
TopLevelItem
item
)
{
items
.
put
(
item
.
getName
(),
item
);
}
@Override
protected
File
getRootDirFor
(
String
name
)
{
return
Hudson
.
this
.
getRootDirFor
(
name
);
}
/**
*send the browser to the config page
* use View to trim view/{default-view} from URL if possible
*/
@Override
protected
String
redirectAfterCreateItem
(
StaplerRequest
req
,
TopLevelItem
result
)
throws
IOException
{
String
redirect
=
result
.
getUrl
()+
"configure"
;
List
<
Ancestor
>
ancestors
=
req
.
getAncestors
();
for
(
int
i
=
ancestors
.
size
()
-
1
;
i
>=
0
;
i
--)
{
Object
o
=
ancestors
.
get
(
i
).
getObject
();
if
(
o
instanceof
View
)
{
redirect
=
req
.
getContextPath
()
+
'/'
+
((
View
)
o
).
getUrl
()
+
redirect
;
break
;
}
}
return
redirect
;
}
};
@CLIResolver
public
static
Hudson
getInstance
()
{
return
theInstance
;
...
...
@@ -586,12 +619,12 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
throw
new
IllegalStateException
(
"second instance"
);
theInstance
=
this
;
// doing this early allows InitStrategy to set environment upfront
// doing this early allows InitStrategy to set environment upfront
final
InitStrategy
is
=
InitStrategy
.
get
(
Thread
.
currentThread
().
getContextClassLoader
());
Trigger
.
timer
=
new
Timer
(
"Hudson cron thread"
);
queue
=
new
Queue
(
CONSISTENT_HASH
?
LoadBalancer
.
CONSISTENT_HASH
:
LoadBalancer
.
DEFAULT
);
try
{
dependencyGraph
=
DependencyGraph
.
EMPTY
;
}
catch
(
InternalError
e
)
{
...
...
@@ -725,7 +758,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*
* <p>
* At this point plugins are not loaded yet, so we fall back to the META-INF/services look up to discover implementations.
* As such there's no way for plugins to participate into this process.
* As such there's no way for plugins to participate into this process.
*/
private
ReactorListener
buildReactorListener
()
throws
IOException
{
List
<
ReactorListener
>
r
=
(
List
)
Service
.
loadInstances
(
Thread
.
currentThread
().
getContextClassLoader
(),
InitReactorListener
.
class
);
...
...
@@ -959,7 +992,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
throw
new
AssertionError
(
type
+
" is missing its descriptor"
);
return
d
;
}
/**
* Gets the {@link Descriptor} instance in the current Hudson by its type.
*/
...
...
@@ -1099,6 +1132,18 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
save
();
}
public
FederatedLoginService
getFederatedLoginService
(
String
name
)
{
for
(
FederatedLoginService
fls
:
FederatedLoginService
.
all
())
{
if
(
fls
.
getUrlName
().
equals
(
name
))
return
fls
;
}
return
null
;
}
public
List
<
FederatedLoginService
>
getFederatedLoginServices
()
{
return
FederatedLoginService
.
all
();
}
public
Launcher
createLauncher
(
TaskListener
listener
)
{
return
new
LocalLauncher
(
listener
).
decorateFor
(
this
);
}
...
...
@@ -1214,7 +1259,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
if
(
item
.
hasPermission
(
Item
.
READ
))
viewableItems
.
add
(
item
);
}
return
viewableItems
;
}
...
...
@@ -1222,7 +1267,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Returns the read-only view of all the {@link TopLevelItem}s keyed by their names.
* <p>
* This method is efficient, as it doesn't involve any copying.
*
*
* @since 1.296
*/
public
Map
<
String
,
TopLevelItem
>
getItemMap
()
{
...
...
@@ -1336,7 +1381,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
views
.
remove
(
view
);
save
();
}
public
ViewsTabBar
getViewsTabBar
()
{
return
viewsTabBar
;
}
...
...
@@ -1659,15 +1704,15 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
public
int
getQuietPeriod
()
{
return
quietPeriod
!=
null
?
quietPeriod
:
5
;
}
/**
* Gets the global SCM check out retry count.
*/
public
int
getScmCheckoutRetryCount
()
{
return
scmCheckoutRetryCount
;
}
/**
* @deprecated
...
...
@@ -1822,7 +1867,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
public
boolean
isUseCrumbs
()
{
return
crumbIssuer
!=
null
;
}
/**
* Returns the constant that captures the three basic security modes
* in Hudson.
...
...
@@ -1954,7 +1999,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*
* @return
* {@link InitMilestone#STARTED} even if the initialization hasn't been started, so that this method
* never returns null.
* never returns null.
*/
public
InitMilestone
getInitLevel
()
{
return
initLevel
;
...
...
@@ -2072,25 +2117,8 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* @throws IllegalArgumentException
* if a project of the give name already exists.
*/
public
synchronized
TopLevelItem
createProject
(
TopLevelItemDescriptor
type
,
String
name
,
boolean
notify
)
throws
IOException
{
if
(
items
.
containsKey
(
name
))
throw
new
IllegalArgumentException
(
"Project of the name "
+
name
+
" already exists"
);
TopLevelItem
item
;
try
{
item
=
type
.
newInstance
(
name
);
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
e
);
}
item
.
onCreatedFromScratch
();
item
.
save
();
items
.
put
(
name
,
item
);
if
(
notify
)
ItemListener
.
fireOnCreated
(
item
);
return
item
;
public
synchronized
TopLevelItem
createProject
(
TopLevelItemDescriptor
type
,
String
name
,
boolean
notify
)
throws
IOException
{
return
itemGroupMixIn
.
createProject
(
type
,
name
,
notify
);
}
/**
...
...
@@ -2125,28 +2153,28 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
}
/**
* Called in response to {@link Job#doDoDelete(StaplerRequest, StaplerResponse)}
* Called by {@link Job#renameTo(String)} to update relevant data structure.
* assumed to be synchronized on Hudson by the caller.
*/
/*package*/
void
deleteJob
(
TopLevelItem
item
)
throws
IOException
{
for
(
ItemListener
l
:
ItemListener
.
all
())
l
.
onDeleted
(
item
);
public
void
onRenamed
(
TopLevelItem
job
,
String
oldName
,
String
newName
)
throws
IOException
{
items
.
remove
(
oldName
);
items
.
put
(
newName
,
job
);
items
.
remove
(
item
.
getName
());
for
(
View
v
:
views
)
v
.
onJobRenamed
(
item
,
item
.
getName
(),
null
);
v
.
onJobRenamed
(
job
,
oldName
,
newName
);
save
();
}
/**
* Called by {@link Job#renameTo(String)} to update relevant data structure.
* assumed to be synchronized on Hudson by the caller.
* Called in response to {@link Job#doDoDelete(StaplerRequest, StaplerResponse)}
*/
public
void
on
Renamed
(
TopLevelItem
job
,
String
oldName
,
String
newName
)
throws
IOException
{
items
.
remove
(
oldName
);
items
.
put
(
newName
,
job
);
public
void
on
Deleted
(
TopLevelItem
item
)
throws
IOException
{
for
(
ItemListener
l
:
ItemListener
.
all
())
l
.
onDeleted
(
item
);
items
.
remove
(
item
.
getName
());
for
(
View
v
:
views
)
v
.
onJobRenamed
(
job
,
oldName
,
newName
);
v
.
onJobRenamed
(
item
,
item
.
getName
(),
null
);
save
();
}
...
...
@@ -2463,7 +2491,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
label
=
json
.
optString
(
"labelString"
,
""
);
quietPeriod
=
json
.
getInt
(
"quiet_period"
);
scmCheckoutRetryCount
=
json
.
getInt
(
"retry_count"
);
systemMessage
=
Util
.
nullify
(
req
.
getParameter
(
"system_message"
));
...
...
@@ -2501,7 +2529,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
public
CrumbIssuer
getCrumbIssuer
()
{
return
crumbIssuer
;
}
public
void
setCrumbIssuer
(
CrumbIssuer
issuer
)
{
crumbIssuer
=
issuer
;
}
...
...
@@ -2600,67 +2628,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
}
public
synchronized
Item
doCreateItem
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
checkPermission
(
Job
.
CREATE
);
TopLevelItem
result
;
String
requestContentType
=
req
.
getContentType
();
if
(
requestContentType
==
null
)
{
rsp
.
sendError
(
HttpServletResponse
.
SC_BAD_REQUEST
,
"No Content-Type header set"
);
return
null
;
}
boolean
isXmlSubmission
=
requestContentType
.
startsWith
(
"application/xml"
)
||
requestContentType
.
startsWith
(
"text/xml"
);
String
name
=
req
.
getParameter
(
"name"
);
if
(
name
==
null
)
{
rsp
.
sendError
(
HttpServletResponse
.
SC_BAD_REQUEST
,
"Query parameter 'name' is required"
);
return
null
;
}
name
=
checkJobName
(
name
);
String
mode
=
req
.
getParameter
(
"mode"
);
if
(
mode
!=
null
&&
mode
.
equals
(
"copy"
))
{
String
from
=
req
.
getParameter
(
"from"
);
TopLevelItem
src
=
getItem
(
from
);
if
(
src
==
null
)
{
rsp
.
setStatus
(
SC_BAD_REQUEST
);
if
(
Util
.
fixEmpty
(
from
)==
null
)
sendError
(
"Specify which job to copy"
,
req
,
rsp
);
else
sendError
(
"No such job: "
+
from
,
req
,
rsp
);
return
null
;
}
result
=
copy
(
src
,
name
);
}
else
{
if
(
isXmlSubmission
)
{
result
=
createProjectFromXML
(
name
,
req
.
getInputStream
());
rsp
.
setStatus
(
HttpServletResponse
.
SC_OK
);
return
result
;
}
else
{
if
(
mode
==
null
)
{
rsp
.
sendError
(
SC_BAD_REQUEST
);
return
null
;
}
// create empty job and redirect to the project config screen
result
=
createProject
(
Items
.
getDescriptor
(
mode
),
name
);
}
}
// send the browser to the config page
// use View to trim view/{default-view} from URL if possible
String
redirect
=
result
.
getUrl
()+
"configure"
;
List
<
Ancestor
>
ancestors
=
req
.
getAncestors
();
for
(
int
i
=
ancestors
.
size
()
-
1
;
i
>=
0
;
i
--)
{
Object
o
=
ancestors
.
get
(
i
).
getObject
();
if
(
o
instanceof
View
)
{
redirect
=
req
.
getContextPath
()
+
'/'
+
((
View
)
o
).
getUrl
()
+
redirect
;
break
;
}
}
rsp
.
sendRedirect2
(
redirect
);
return
result
;
return
itemGroupMixIn
.
createTopLevelItem
(
req
,
rsp
);
}
/**
...
...
@@ -2669,25 +2637,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* @since 1.319
*/
public
TopLevelItem
createProjectFromXML
(
String
name
,
InputStream
xml
)
throws
IOException
{
// place it as config.xml
File
configXml
=
Items
.
getConfigFile
(
getRootDirFor
(
name
)).
getFile
();
configXml
.
getParentFile
().
mkdirs
();
try
{
IOUtils
.
copy
(
xml
,
configXml
);
// load it
TopLevelItem
result
=
(
TopLevelItem
)
Items
.
load
(
this
,
configXml
.
getParentFile
());
items
.
put
(
name
,
result
);
ItemListener
.
fireOnCreated
(
result
);
rebuildDependencyGraph
();
return
result
;
}
catch
(
IOException
e
)
{
// if anything fails, delete the config file to avoid further confusion
Util
.
deleteRecursive
(
configXml
.
getParentFile
());
throw
e
;
}
return
itemGroupMixIn
.
createProjectFromXML
(
name
,
xml
);
}
/**
...
...
@@ -2702,19 +2652,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*/
@SuppressWarnings
({
"unchecked"
})
public
<
T
extends
TopLevelItem
>
T
copy
(
T
src
,
String
name
)
throws
IOException
{
T
result
=
(
T
)
createProject
(
src
.
getDescriptor
(),
name
,
false
);
// copy config
Util
.
copyFile
(
Items
.
getConfigFile
(
src
).
getFile
(),
Items
.
getConfigFile
(
result
).
getFile
());
// reload from the new config
result
=
(
T
)
Items
.
load
(
this
,
result
.
getRootDir
());
result
.
onCopiedFrom
(
src
);
items
.
put
(
name
,
result
);
ItemListener
.
fireOnCopied
(
src
,
result
);
return
result
;
return
itemGroupMixIn
.
copy
(
src
,
name
);
}
// a little more convenient overloading that assumes the caller gives us the right type
...
...
@@ -2897,7 +2835,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
// Parse the request
MultipartFormDataParser
p
=
new
MultipartFormDataParser
(
req
);
if
(
Hudson
.
getInstance
().
isUseCrumbs
()
&&
!
Hudson
.
getInstance
().
getCrumbIssuer
().
validateCrumb
(
req
,
p
))
{
rsp
.
sendError
(
HttpServletResponse
.
SC_FORBIDDEN
,
"No crumb found"
);
rsp
.
sendError
(
HttpServletResponse
.
SC_FORBIDDEN
,
"No crumb found"
);
}
try
{
rsp
.
sendRedirect2
(
req
.
getContextPath
()+
"/fingerprint/"
+
...
...
@@ -2999,7 +2937,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Queues up a restart of Hudson for when there are no builds running, if we can.
*
* This first replaces "app" to {@link HudsonIsRestarting}
*
*
* @since 1.332
*/
@CLIMethod
(
name
=
"safe-restart"
)
...
...
@@ -3055,7 +2993,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
lifecycle
.
verifyRestartable
();
// verify that Hudson is restartable
// Quiet down so that we won't launch new builds.
isQuietingDown
=
true
;
new
Thread
(
"safe-restart thread"
)
{
final
String
exitUser
=
getAuthentication
().
getName
();
@Override
...
...
@@ -3105,7 +3043,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
System
.
exit
(
0
);
}
/**
* Shutdown the system safely.
* @since 1.332
...
...
@@ -3268,7 +3206,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
// this method can be used to check if a file exists anywhere in the file system,
// so it should be protected.
checkPermission
(
Item
.
CREATE
);
if
(
fixEmpty
(
value
)==
null
)
return
FormValidation
.
ok
();
...
...
@@ -3470,6 +3408,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
||
rest
.
startsWith
(
"/tcpSlaveAgentListener"
)
||
rest
.
startsWith
(
"/cli"
)
||
rest
.
startsWith
(
"/whoAmI"
)
||
rest
.
startsWith
(
"/federatedLoginService/"
)
||
rest
.
startsWith
(
"/securityRealm"
))
return
this
;
// URLs that are always visible without READ permission
throw
e
;
...
...
@@ -3588,7 +3527,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
public
static
<
T
>
T
lookup
(
Class
<
T
>
type
)
{
return
Hudson
.
getInstance
().
lookup
.
get
(
type
);
}
/**
* @deprecated since 2007-12-18.
* Use {@link #checkPermission(Permission)}
...
...
@@ -3764,7 +3703,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Automatically try to launch a slave when Hudson is initialized or a new slave is created.
*/
public
static
boolean
AUTOMATIC_SLAVE_LAUNCH
=
true
;
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
Hudson
.
class
.
getName
());
private
static
final
Pattern
ICON_SIZE
=
Pattern
.
compile
(
"\\d+x\\d+"
);
...
...
core/src/main/java/hudson/model/ItemGroup.java
浏览文件 @
380b7269
...
...
@@ -77,4 +77,9 @@ public interface ItemGroup<T extends Item> extends PersistenceRoot, ModelObject
* Internal method. Called by {@link Item}s when they are renamed by users.
*/
void
onRenamed
(
T
item
,
String
oldName
,
String
newName
)
throws
IOException
;
/**
* Internal method. Called by {@link Item}s when they are deleted by users.
*/
void
onDeleted
(
T
item
)
throws
IOException
;
}
core/src/main/java/hudson/model/ItemGroupMixIn.java
浏览文件 @
380b7269
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
, 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
...
...
@@ -23,21 +23,62 @@
*/
package
hudson.model
;
import
hudson.Util
;
import
hudson.model.listeners.ItemListener
;
import
hudson.security.AccessControlled
;
import
hudson.util.CopyOnWriteMap
;
import
hudson.util.Function1
;
import
hudson.util.IOUtils
;
import
org.kohsuke.stapler.Ancestor
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.File
;
import
java.io.FileFilter
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.List
;
import
java.util.Map
;
/**
* Defines a bunch of static methods to be used as a "mix-in" for {@link ItemGroup}
* implementations.
* implementations.
Not meant for a consumption from outside {@link ItemGroup}s.
*
* @author Kohsuke Kawaguchi
*/
public
class
ItemGroupMixIn
{
public
abstract
class
ItemGroupMixIn
{
/**
* {@link ItemGroup} for which we are working.
*/
private
final
ItemGroup
parent
;
private
final
AccessControlled
acl
;
protected
ItemGroupMixIn
(
ItemGroup
parent
,
AccessControlled
acl
)
{
this
.
parent
=
parent
;
this
.
acl
=
acl
;
}
/*
* Callback methods to be implemented by the ItemGroup implementation.
*/
/**
* Adds a newly created item to the parent.
*/
protected
abstract
void
add
(
TopLevelItem
item
);
/**
* Assigns the root directory for a prospective item.
*/
protected
abstract
File
getRootDirFor
(
String
name
);
/*
* The rest is the methods that provide meat.
*/
/**
* Loads all the child {@link Item}s.
*
...
...
@@ -73,4 +114,146 @@ public class ItemGroupMixIn {
return
item
.
getName
();
}
};
/**
* Creates a {@link TopLevelItem} from the submission of the '/lib/hudson/newFromList/formList'
* or throws an exception if it fails.
*/
public
synchronized
TopLevelItem
createTopLevelItem
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
acl
.
checkPermission
(
Job
.
CREATE
);
TopLevelItem
result
;
String
requestContentType
=
req
.
getContentType
();
if
(
requestContentType
==
null
)
throw
new
Failure
(
"No Content-Type header set"
);
boolean
isXmlSubmission
=
requestContentType
.
startsWith
(
"application/xml"
)
||
requestContentType
.
startsWith
(
"text/xml"
);
String
name
=
req
.
getParameter
(
"name"
);
if
(
name
==
null
)
throw
new
Failure
(
"Query parameter 'name' is required"
);
{
// check if the name looks good
Hudson
.
checkGoodName
(
name
);
name
=
name
.
trim
();
if
(
parent
.
getItem
(
name
)!=
null
)
throw
new
Failure
(
Messages
.
Hudson_JobAlreadyExists
(
name
));
}
String
mode
=
req
.
getParameter
(
"mode"
);
if
(
mode
!=
null
&&
mode
.
equals
(
"copy"
))
{
String
from
=
req
.
getParameter
(
"from"
);
// resolve a name to Item
Item
src
=
parent
.
getItem
(
from
);
if
(
src
==
null
)
src
=
Hudson
.
getInstance
().
getItemByFullName
(
from
);
if
(
src
==
null
)
{
if
(
Util
.
fixEmpty
(
from
)==
null
)
throw
new
Failure
(
"Specify which job to copy"
);
else
throw
new
Failure
(
"No such job: "
+
from
);
}
if
(!(
src
instanceof
TopLevelItem
))
throw
new
Failure
(
from
+
" cannot be copied"
);
result
=
copy
((
TopLevelItem
)
src
,
name
);
}
else
{
if
(
isXmlSubmission
)
{
result
=
createProjectFromXML
(
name
,
req
.
getInputStream
());
rsp
.
setStatus
(
HttpServletResponse
.
SC_OK
);
return
result
;
}
else
{
if
(
mode
==
null
)
throw
new
Failure
(
"No mode given"
);
// create empty job and redirect to the project config screen
result
=
createProject
(
Items
.
getDescriptor
(
mode
),
name
,
true
);
}
}
rsp
.
sendRedirect2
(
redirectAfterCreateItem
(
req
,
result
));
return
result
;
}
/**
* Computes the redirection target URL for the newly created {@link TopLevelItem}.
*/
protected
String
redirectAfterCreateItem
(
StaplerRequest
req
,
TopLevelItem
result
)
throws
IOException
{
return
req
.
getContextPath
()+
'/'
+
result
.
getUrl
()+
"configure"
;
}
/**
* Copies an existing {@link TopLevelItem} to a new name.
*
* The caller is responsible for calling {@link ItemListener#fireOnCopied(Item, Item)}. This method
* cannot do that because it doesn't know how to make the newly added item reachable from the parent.
*/
@SuppressWarnings
({
"unchecked"
})
public
synchronized
<
T
extends
TopLevelItem
>
T
copy
(
T
src
,
String
name
)
throws
IOException
{
acl
.
checkPermission
(
Job
.
CREATE
);
T
result
=
(
T
)
createProject
(
src
.
getDescriptor
(),
name
,
false
);
// copy config
Util
.
copyFile
(
Items
.
getConfigFile
(
src
).
getFile
(),
Items
.
getConfigFile
(
result
).
getFile
());
// reload from the new config
result
=
(
T
)
Items
.
load
(
parent
,
result
.
getRootDir
());
result
.
onCopiedFrom
(
src
);
add
(
result
);
ItemListener
.
fireOnCopied
(
src
,
result
);
return
result
;
}
public
synchronized
TopLevelItem
createProjectFromXML
(
String
name
,
InputStream
xml
)
throws
IOException
{
acl
.
checkPermission
(
Job
.
CREATE
);
// place it as config.xml
File
configXml
=
Items
.
getConfigFile
(
getRootDirFor
(
name
)).
getFile
();
configXml
.
getParentFile
().
mkdirs
();
try
{
IOUtils
.
copy
(
xml
,
configXml
);
// load it
TopLevelItem
result
=
(
TopLevelItem
)
Items
.
load
(
parent
,
configXml
.
getParentFile
());
add
(
result
);
ItemListener
.
fireOnCreated
(
result
);
Hudson
.
getInstance
().
rebuildDependencyGraph
();
return
result
;
}
catch
(
IOException
e
)
{
// if anything fails, delete the config file to avoid further confusion
Util
.
deleteRecursive
(
configXml
.
getParentFile
());
throw
e
;
}
}
public
synchronized
TopLevelItem
createProject
(
TopLevelItemDescriptor
type
,
String
name
,
boolean
notify
)
throws
IOException
{
acl
.
checkPermission
(
Job
.
CREATE
);
if
(
parent
.
getItem
(
name
)!=
null
)
throw
new
IllegalArgumentException
(
"Project of the name "
+
name
+
" already exists"
);
TopLevelItem
item
;
try
{
item
=
type
.
newInstance
(
parent
,
name
);
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
e
);
}
item
.
onCreatedFromScratch
();
item
.
save
();
add
(
item
);
if
(
notify
)
ItemListener
.
fireOnCreated
(
item
);
return
item
;
}
}
core/src/main/java/hudson/model/Items.java
浏览文件 @
380b7269
...
...
@@ -24,15 +24,17 @@
package
hudson.model
;
import
com.thoughtworks.xstream.XStream
;
import
hudson.XmlFile
;
import
hudson.DescriptorExtensionList
;
import
hudson.Extension
;
import
hudson.scm.RepositoryBrowser
;
import
hudson.matrix.MatrixProject
;
import
hudson.matrix.MatrixConfiguration
;
import
hudson.XmlFile
;
import
hudson.matrix.Axis
;
import
hudson.util.XStream2
;
import
hudson.matrix.MatrixConfiguration
;
import
hudson.matrix.MatrixProject
;
import
hudson.util.DescriptorList
;
import
hudson.util.XStream2
;
import
java.io.File
;
import
java.io.IOException
;
...
...
core/src/main/java/hudson/model/Job.java
浏览文件 @
380b7269
...
...
@@ -469,6 +469,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
/**
* Renames a job.
*/
@Override
public
void
renameTo
(
String
newName
)
throws
IOException
{
super
.
renameTo
(
newName
);
}
...
...
core/src/main/java/hudson/model/ListView.java
浏览文件 @
380b7269
...
...
@@ -123,7 +123,7 @@ public class ListView extends View implements Saveable {
return
!
ViewJobFilter
.
all
().
isEmpty
();
}
public
Iterable
<
ViewJobFilter
>
getJobFilters
()
{
public
DescribableList
<
ViewJobFilter
,
Descriptor
<
ViewJobFilter
>
>
getJobFilters
()
{
return
jobFilters
;
}
...
...
core/src/main/java/hudson/model/TopLevelItem.java
浏览文件 @
380b7269
...
...
@@ -23,11 +23,14 @@
*/
package
hudson.model
;
import
hudson.ExtensionPoint
;
import
hudson.Extension
;
import
hudson.ExtensionPoint
;
import
hudson.matrix.MatrixConfiguration
;
/**
* {@link Item} that can be directly displayed under {@link Hudson}.
* {@link Item} that can be directly displayed under {@link Hudson} or other containers.
* Ones that don't need to be under specific parent (say, unlike {@link MatrixConfiguration}),
* and thus can be freely moved, copied, etc.
*
* <p>
* To register a custom {@link TopLevelItem} class from a plugin, put {@link Extension} on your
...
...
@@ -36,11 +39,6 @@ import hudson.Extension;
* @author Kohsuke Kawaguchi
*/
public
interface
TopLevelItem
extends
Item
,
ExtensionPoint
,
Describable
<
TopLevelItem
>
{
/**
* By definition the parent of the top-level item is always {@link Hudson}.
*/
Hudson
getParent
();
/**
*
* @see Describable#getDescriptor()
...
...
core/src/main/java/hudson/model/TopLevelItemDescriptor.java
浏览文件 @
380b7269
...
...
@@ -81,9 +81,21 @@ public abstract class TopLevelItemDescriptor extends Descriptor<TopLevelItem> {
}
/**
* Creates a new {@link Job}.
* Creates a new {@link TopLevelItem}.
*
* @deprecated as of 1.390
* Use {@link #newInstance(ItemGroup, String)}
*/
public
TopLevelItem
newInstance
(
String
name
)
{
return
newInstance
(
Hudson
.
getInstance
(),
name
);
}
/**
* Creates a new {@link TopLevelItem} for the specified parent.
*
* @since 1.390
*/
public
abstract
TopLevelItem
newInstance
(
String
name
);
public
abstract
TopLevelItem
newInstance
(
ItemGroup
parent
,
String
name
);
/**
* Returns all the registered {@link TopLevelItem} descriptors.
...
...
core/src/main/java/hudson/model/User.java
浏览文件 @
380b7269
...
...
@@ -443,15 +443,18 @@ public class User extends AbstractModelObject implements AccessControlled, Savea
List
<
UserProperty
>
props
=
new
ArrayList
<
UserProperty
>();
int
i
=
0
;
for
(
UserPropertyDescriptor
d
:
UserProperty
.
all
())
{
JSONObject
o
=
json
.
getJSONObject
(
"userProperty"
+
(
i
++));
UserProperty
p
=
getProperty
(
d
.
clazz
);
if
(
p
!=
null
)
{
p
=
p
.
reconfigure
(
req
,
o
);
}
else
{
p
=
d
.
newInstance
(
req
,
o
);
JSONObject
o
=
json
.
optJSONObject
(
"userProperty"
+
(
i
++));
if
(
o
!=
null
)
{
if
(
p
!=
null
)
{
p
=
p
.
reconfigure
(
req
,
o
);
}
else
{
p
=
d
.
newInstance
(
req
,
o
);
}
p
.
setUser
(
this
);
}
p
.
setUser
(
this
);
props
.
add
(
p
);
}
this
.
properties
=
props
;
...
...
core/src/main/java/hudson/model/ViewJob.java
浏览文件 @
380b7269
...
...
@@ -76,10 +76,17 @@ public abstract class ViewJob<JobT extends ViewJob<JobT,RunT>, RunT extends Run<
reloadThread
.
start
();
}
/**
* @deprecated as of 1.390
*/
protected
ViewJob
(
Hudson
parent
,
String
name
)
{
super
(
parent
,
name
);
}
protected
ViewJob
(
ItemGroup
parent
,
String
name
)
{
super
(
parent
,
name
);
}
public
boolean
isBuildable
()
{
return
false
;
}
...
...
core/src/main/java/hudson/security/FederatedLoginService.java
0 → 100644
浏览文件 @
380b7269
/*
* The MIT License
*
* Copyright (c) 2010, 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.
*/
package
hudson.security
;
import
hudson.ExtensionList
;
import
hudson.ExtensionPoint
;
import
hudson.model.Hudson
;
import
hudson.model.User
;
import
hudson.model.UserProperty
;
import
org.acegisecurity.context.SecurityContextHolder
;
import
org.acegisecurity.providers.UsernamePasswordAuthenticationToken
;
import
org.acegisecurity.userdetails.UserDetails
;
import
org.kohsuke.stapler.HttpResponse
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
import
javax.servlet.ServletException
;
import
java.io.IOException
;
/**
* Abstraction for a login mechanism through external authenticator/identity provider
* (instead of username/password.)
*
* <p>
* This extension point adds additional login mechanism for {@link SecurityRealm}s that
* authenticate the user via username/password (which typically extends from {@link AbstractPasswordBasedSecurityRealm}.)
* The intended use case is protocols like OpenID, OAuth, and other SSO-like services.
*
* <p>
* The basic abstraction is that:
*
* <ul>
* <li>
* The user can have (possibly multiple, possibly zero) opaque strings to their {@linkplain User} object.
* Such opaque strings are called "identifiers."
* Think of them as OpenID URLs, twitter account names, etc.
* Identifiers are only comparable within the same {@link FederatedLoginService} implementation.
*
* <li>
* After getting authenticated by some means, the user can add additional identifiers to their account.
* Your implementation would do protocol specific thing to verify that the user indeed owns the claimed identifier,
* create a {@link FederatedIdentity} instance,
* then call {@link FederatedIdentity#addToCurrentUser()} to record such association.
*
* <li>
* In the login page, instead of entering the username and password, the user opts for authenticating
* via other services. Think of OpenID, OAuth, your corporate SSO service, etc.
* The user proves (by your protocol specific way) that they own some identifier, then
* create a {@link FederatedIdentity} instance, and invoke {@link FederatedIdentity#signin()} to sign in that user.
*
* </ul>
*
*
* <h2>Views</h2>
* <dl>
* <dt>loginFragment.jelly
* <dd>
* Injected into the login form page, after the default "login" button but before
* the "create account" link. Use this to generate a button or a link so that the user
* can initiate login via your federated login service.
* </dl>
*
* <h2>URL Binding</h2>
* <p>
* Each {@link FederatedLoginService} is exposed to the URL space via {@link Hudson#getFederatedLoginService(String)}.
* So for example if your {@linkplain #getUrlName() url name} is "openid", this object gets
* "/federatedLoginService/openid" as the URL.
*
* @author Kohsuke Kawaguchi
* @since 1.394
*/
public
abstract
class
FederatedLoginService
implements
ExtensionPoint
{
/**
* Returns the url name that determines where this {@link FederatedLoginService} is mapped to in the URL space.
*
* <p>
* The object is bound to /federatedLoginService/URLNAME/. The url name needs to be unique among all
* {@link FederatedLoginService}s.
*/
public
abstract
String
getUrlName
();
/**
* Returns your implementation of {@link FederatedLoginServiceUserProperty} that stores
* opaque identifiers.
*/
public
abstract
Class
<?
extends
FederatedLoginServiceUserProperty
>
getUserPropertyClass
();
/**
* Identity information as obtained from {@link FederatedLoginService}.
*/
public
abstract
class
FederatedIdentity
{
/**
* Gets the string representation of the identity in the form that makes sense to the enclosing
* {@link FederatedLoginService}, such as full OpenID URL.
*
* @return must not be null.
*/
public
abstract
String
getIdentifier
();
/**
* Gets a short ID of this user, as a suitable candidate for {@link User#getId()}.
* This should be Unix username like token.
*
* @return null if this information is not available.
*/
public
abstract
String
getNickname
();
/**
* Gets a human readable full name of this user. Maps to {@link User#getDisplayName()}
*
* @return null if this information is not available.
*/
public
abstract
String
getFullName
();
/**
* Gets the e-mail address of this user, like "abc@def.com"
*
* @return null if this information is not available.
*/
public
abstract
String
getEmailAddress
();
/**
* Returns a human-readable pronoun that describes this kind of identifier.
* This is used for rendering UI. For example, "OpenID", "Twitter ID", etc.
*/
public
abstract
String
getPronoun
();
/**
* Locates the user who owns this identifier.
*/
public
final
User
locateUser
()
{
Class
<?
extends
FederatedLoginServiceUserProperty
>
pt
=
getUserPropertyClass
();
String
id
=
getIdentifier
();
for
(
User
u
:
User
.
getAll
())
{
if
(
u
.
getProperty
(
pt
).
has
(
id
))
return
u
;
}
return
null
;
}
/**
* Call this method to authenticate the user when you confirmed (via your protocol specific work) that
* the current HTTP request indeed owns this identifier.
*
* <p>
* This method will locate the user who owns this identifier, associate the credential with
* the current session. IOW, it signs in the user.
*
* @throws UnclaimedIdentityException
* If this identifier is not claimed by anyone. If you just let this exception propagate
* to the caller of your "doXyz" method, it will either render an error page or initiate
* a user registration session (provided that {@link SecurityRealm} supports that.)
*/
public
User
signin
()
throws
UnclaimedIdentityException
{
User
u
=
locateUser
();
if
(
u
!=
null
)
{
// login as this user
UserDetails
d
=
Hudson
.
getInstance
().
getSecurityRealm
().
loadUserByUsername
(
u
.
getId
());
UsernamePasswordAuthenticationToken
token
=
new
UsernamePasswordAuthenticationToken
(
d
,
""
,
d
.
getAuthorities
());
token
.
setDetails
(
d
);
SecurityContextHolder
.
getContext
().
setAuthentication
(
token
);
return
u
;
}
else
{
// Unassociated identity.
throw
new
UnclaimedIdentityException
(
this
);
}
}
/**
* Your implementation will call this method to add this identifier to the current user
* of an already authenticated session.
*
* <p>
* This method will record the identifier in {@link FederatedLoginServiceUserProperty} so that
* in the future the user can login to Hudson with the identifier.
*/
public
void
addToCurrentUser
()
throws
IOException
{
User
u
=
User
.
current
();
if
(
u
==
null
)
throw
new
IllegalStateException
(
"Current request is unauthenticated"
);
addTo
(
u
);
}
/**
* Adds this identity to the specified user.
*/
public
void
addTo
(
User
u
)
throws
IOException
{
FederatedLoginServiceUserProperty
p
=
u
.
getProperty
(
getUserPropertyClass
());
if
(
p
==
null
)
{
p
=
(
FederatedLoginServiceUserProperty
)
UserProperty
.
all
().
find
(
getUserPropertyClass
()).
newInstance
(
u
);
u
.
addProperty
(
p
);
}
p
.
addIdentifier
(
getIdentifier
());
}
@Override
public
String
toString
()
{
return
getIdentifier
();
}
}
/**
* Used in {@link FederatedIdentity#signin()} to indicate that the identifier is not currently
* associated with anyone.
*/
public
static
class
UnclaimedIdentityException
extends
RuntimeException
implements
HttpResponse
{
public
final
FederatedIdentity
identity
;
public
UnclaimedIdentityException
(
FederatedIdentity
identity
)
{
this
.
identity
=
identity
;
}
public
void
generateResponse
(
StaplerRequest
req
,
StaplerResponse
rsp
,
Object
node
)
throws
IOException
,
ServletException
{
SecurityRealm
sr
=
Hudson
.
getInstance
().
getSecurityRealm
();
if
(
sr
.
allowsSignup
())
{
try
{
sr
.
commenceSignup
(
identity
).
generateResponse
(
req
,
rsp
,
node
);
return
;
}
catch
(
UnsupportedOperationException
e
)
{
// fall through
}
}
// this security realm doesn't support user registration.
// just report an error
req
.
getView
(
this
,
"error"
).
forward
(
req
,
rsp
);
}
}
public
static
ExtensionList
<
FederatedLoginService
>
all
()
{
return
Hudson
.
getInstance
().
getExtensionList
(
FederatedLoginService
.
class
);
}
}
core/src/main/java/hudson/security/FederatedLoginServiceUserProperty.java
0 → 100644
浏览文件 @
380b7269
/*
* The MIT License
*
* Copyright (c) 2010, 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.
*/
package
hudson.security
;
import
hudson.model.UserProperty
;
import
java.io.IOException
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.Set
;
/**
*
* @author Kohsuke Kawaguchi
* @since 1.394
* @see FederatedLoginService
*/
public
class
FederatedLoginServiceUserProperty
extends
UserProperty
{
protected
final
Set
<
String
>
identifiers
;
protected
FederatedLoginServiceUserProperty
(
Collection
<
String
>
identifiers
)
{
this
.
identifiers
=
new
HashSet
<
String
>(
identifiers
);
}
public
boolean
has
(
String
identifier
)
{
return
identifiers
.
contains
(
identifier
);
}
public
Collection
<
String
>
getIdentifiers
()
{
return
Collections
.
unmodifiableSet
(
identifiers
);
}
public
synchronized
void
addIdentifier
(
String
id
)
throws
IOException
{
identifiers
.
add
(
id
);
user
.
save
();
}
}
core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java
浏览文件 @
380b7269
...
...
@@ -34,6 +34,7 @@ import hudson.model.ModelObject;
import
hudson.model.User
;
import
hudson.model.UserProperty
;
import
hudson.model.UserPropertyDescriptor
;
import
hudson.security.FederatedLoginService.FederatedIdentity
;
import
hudson.tasks.Mailer
;
import
hudson.util.PluginServletFilter
;
import
hudson.util.Protector
;
...
...
@@ -51,6 +52,9 @@ import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
import
org.acegisecurity.userdetails.UserDetails
;
import
org.acegisecurity.userdetails.UsernameNotFoundException
;
import
org.kohsuke.stapler.DataBoundConstructor
;
import
org.kohsuke.stapler.ForwardToView
;
import
org.kohsuke.stapler.HttpResponse
;
import
org.kohsuke.stapler.HttpResponses
;
import
org.kohsuke.stapler.Stapler
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
...
...
@@ -147,21 +151,56 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea
return
u
;
}
/**
* Show the sign up page with the data from the identity.
*/
@Override
public
HttpResponse
commenceSignup
(
final
FederatedIdentity
identity
)
{
// store the identity in the session so that we can use this later
Stapler
.
getCurrentRequest
().
getSession
().
setAttribute
(
FEDERATED_IDENTITY_SESSION_KEY
,
identity
);
return
new
ForwardToView
(
this
,
"signupWithFederatedIdentity.jelly"
)
{
@Override
public
void
generateResponse
(
StaplerRequest
req
,
StaplerResponse
rsp
,
Object
node
)
throws
IOException
,
ServletException
{
SignupInfo
si
=
new
SignupInfo
(
identity
);
si
.
errorMessage
=
Messages
.
HudsonPrivateSecurityRealm_WouldYouLikeToSignUp
(
identity
.
getPronoun
(),
identity
.
getIdentifier
());
req
.
setAttribute
(
"data"
,
si
);
super
.
generateResponse
(
req
,
rsp
,
node
);
}
};
}
/**
* Creates an account and associates that with the given identity. Used in conjunction
* with {@link #commenceSignup(FederatedIdentity)}.
*/
public
User
doCreateAccountWithFederatedIdentity
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
User
u
=
_doCreateAccount
(
req
,
rsp
,
"signupWithFederatedIdentity.jelly"
);
if
(
u
!=
null
)
((
FederatedIdentity
)
req
.
getSession
().
getAttribute
(
FEDERATED_IDENTITY_SESSION_KEY
)).
addTo
(
u
);
return
u
;
}
private
static
final
String
FEDERATED_IDENTITY_SESSION_KEY
=
HudsonPrivateSecurityRealm
.
class
.
getName
()+
".federatedIdentity"
;
/**
* Creates an user account. Used for self-registration.
*/
public
void
doCreateAccount
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
if
(!
allowsSignup
())
{
rsp
.
sendError
(
SC_UNAUTHORIZED
,
"User sign up is prohibited"
);
return
;
}
public
User
doCreateAccount
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
return
_doCreateAccount
(
req
,
rsp
,
"signup.jelly"
);
}
private
User
_doCreateAccount
(
StaplerRequest
req
,
StaplerResponse
rsp
,
String
formView
)
throws
ServletException
,
IOException
{
if
(!
allowsSignup
())
throw
HttpResponses
.
error
(
SC_UNAUTHORIZED
,
new
Exception
(
"User sign up is prohibited"
));
boolean
firstUser
=
!
hasSomeUser
();
User
u
=
createAccount
(
req
,
rsp
,
true
,
"signup.jelly"
);
User
u
=
createAccount
(
req
,
rsp
,
true
,
formView
);
if
(
u
!=
null
)
{
if
(
firstUser
)
tryToMakeAdmin
(
u
);
// the first user should be admin, or else there's a risk of lock out
loginAndTakeBack
(
req
,
rsp
,
u
);
}
return
u
;
}
/**
...
...
@@ -227,8 +266,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea
private
User
createAccount
(
StaplerRequest
req
,
StaplerResponse
rsp
,
boolean
selfRegistration
,
String
formView
)
throws
ServletException
,
IOException
{
// form field validation
// this pattern needs to be generalized and moved to stapler
SignupInfo
si
=
new
SignupInfo
();
req
.
bindParameters
(
si
);
SignupInfo
si
=
new
SignupInfo
(
req
);
if
(
selfRegistration
&&
!
validateCaptcha
(
si
.
captcha
))
si
.
errorMessage
=
"Text didn't match the word shown in the image"
;
...
...
@@ -328,6 +366,19 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea
* To display an error message, set it here.
*/
public
String
errorMessage
;
public
SignupInfo
()
{
}
public
SignupInfo
(
StaplerRequest
req
)
{
req
.
bindParameters
(
this
);
}
public
SignupInfo
(
FederatedIdentity
i
)
{
this
.
username
=
i
.
getNickname
();
this
.
fullname
=
i
.
getFullName
();
this
.
email
=
i
.
getEmailAddress
();
}
}
/**
...
...
core/src/main/java/hudson/security/SecurityRealm.java
浏览文件 @
380b7269
...
...
@@ -33,6 +33,7 @@ import hudson.cli.CLICommand;
import
hudson.model.AbstractDescribableImpl
;
import
hudson.model.Descriptor
;
import
hudson.model.Hudson
;
import
hudson.security.FederatedLoginService.FederatedIdentity
;
import
hudson.util.DescriptorList
;
import
hudson.util.PluginServletFilter
;
import
hudson.util.spring.BeanBuilder
;
...
...
@@ -47,6 +48,7 @@ import static org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices.ACEGI
import
org.acegisecurity.userdetails.UserDetailsService
;
import
org.acegisecurity.userdetails.UserDetails
;
import
org.acegisecurity.userdetails.UsernameNotFoundException
;
import
org.kohsuke.stapler.HttpResponse
;
import
org.kohsuke.stapler.Stapler
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
...
...
@@ -299,6 +301,28 @@ public abstract class SecurityRealm extends AbstractDescribableImpl<SecurityReal
throw
new
UserMayOrMayNotExistException
(
groupname
);
}
/**
* Starts the user registration process for a new user that has the given verified identity.
*
* <p>
* If the user logs in through a {@link FederatedLoginService}, verified that the current user
* owns an {@linkplain FederatedIdentity identity}, but no existing user account has claimed that identity,
* then this method is invoked.
*
* <p>
* The expected behaviour is to confirm that the user would like to create a new account, and
* associate this federated identity to the newly created account (via {@link FederatedIdentity#addToCurrentUser()}.
*
* @throws UnsupportedOperationException
* If this implementation doesn't support the signup through this mechanism.
* This is the default implementation.
*
* @since 1.394
*/
public
HttpResponse
commenceSignup
(
FederatedIdentity
identity
)
{
throw
new
UnsupportedOperationException
();
}
/**
* {@link DefaultManageableImageCaptchaService} holder to defer initialization.
*/
...
...
core/src/main/java/hudson/slaves/RetentionStrategy.java
浏览文件 @
380b7269
...
...
@@ -140,7 +140,7 @@ public abstract class RetentionStrategy<T extends Computer> extends AbstractDesc
return
1
;
}
@Extension
@Extension
(
ordinal
=
100
)
public
static
class
DescriptorImpl
extends
Descriptor
<
RetentionStrategy
<?>>
{
public
String
getDisplayName
()
{
return
Messages
.
RetentionStrategy_Always_displayName
();
...
...
core/src/main/resources/hudson/model/ComputerSet/index.jelly
浏览文件 @
380b7269
...
...
@@ -66,7 +66,7 @@ THE SOFTWARE.
<td><!-- config link -->
<j:if test="${c.hasPermission(c.CONFIGURE)}">
<a href="${rootURL}/${c.url}configure">
<img src="${imagesURL}/32x32/setting.
gif
"
<img src="${imagesURL}/32x32/setting.
png
"
title="${%Configure}" alt="${%Configure}"
border="0"/>
</a>
...
...
core/src/main/resources/hudson/model/Hudson/login.jelly
浏览文件 @
380b7269
...
...
@@ -55,6 +55,12 @@ THE SOFTWARE.
</script>
</form>
<j:forEach var="fls" items="${it.getFederatedLoginServices()}">
<div>
<st:include page="loginFragment.jelly" it="${fls}"/>
</div>
</j:forEach>
<j:if test="${it.securityRealm.allowsSignup()}">
<div style="margin-top:2em">
${%signUp}
...
...
core/src/main/resources/hudson/model/User/configure.jelly
浏览文件 @
380b7269
...
...
@@ -42,14 +42,16 @@ THE SOFTWARE.
<j:invokeStatic var="descriptors" className="hudson.model.UserProperty" method="all" />
<j:set var="instances" value="${it.properties}" />
<j:forEach var="d" items="${descriptors}" varStatus="loop">
<f:section title="${d.displayName}">
<j:set var="descriptor" value="${d}" />
<j:set var="instance" value="${instances[d]}" />
<f:rowSet name="userProperty${loop.index}">
<st:include from="${d}" page="${d.configPage}"/>
</f:rowSet>
</f:section>
<j:if test="${d.enabled}">
<f:section title="${d.displayName}">
<j:set var="descriptor" value="${d}" />
<j:set var="instance" value="${instances[d]}" />
<f:rowSet name="userProperty${loop.index}">
<st:include from="${d}" page="${d.configPage}"/>
</f:rowSet>
</f:section>
</j:if>
</j:forEach>
<f:block>
...
...
core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error.jelly
0 → 100644
浏览文件 @
380b7269
<!--
The MIT License
Copyright (c) 2010, 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.
-->
<!--
This is used to create the first user.
-->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<st:statusCode value="403" />
<l:layout title="${%loginError(it.identifier.pronoun)}">
<l:main-panel>
<h1>${%loginError(it.identifier.pronoun)}</h1>
<p>${%blurb(it.identifier.pronoun, it.identifier.identifier)}</p>
</l:main-panel>
</l:layout>
</j:jelly>
\ No newline at end of file
core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error.properties
0 → 100644
浏览文件 @
380b7269
loginError
=
Login Error: unassociated {0}
blurb
=
{0} "{1}" is not associated with any of the Hudson user account.
\
Note that if you already have a user account and is trying to associate a {0} with your account,
\
this is a wrong place. To do so, <ol><li>Login <li>Click on your name <li>Click on the "Configure" link, and
\
then <li>associate a new {0} from that page</ol>
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly
浏览文件 @
380b7269
...
...
@@ -24,7 +24,7 @@ THE SOFTWARE.
<!-- tag file sed by both signup.jelly and addUser.jelly -->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:layout norefresh="true">
<l:layout norefresh="true"
title="${%Sign up}"
>
<l:header>
<style>
<!-- match width with captcha image -->
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly
0 → 100644
浏览文件 @
380b7269
<!--
The MIT License
Copyright (c) 2010, 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.
-->
<!--
User self sign up page.
-->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<local:_entryForm host="${app}" title="${%Sign up}" action="createAccountWithFederatedIdentity" captcha="${true}" xmlns:local="/hudson/security/HudsonPrivateSecurityRealm" />
</j:jelly>
\ No newline at end of file
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_da.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen.
#
# 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.
Sign\
up
=
Tilmelding
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_de.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest
#
# 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.
Sign\
up
=
Registrieren
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_es.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2010, Sun Microsystems, 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.
Sign\
up
=
Registrarse
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_fr.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant
#
# 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.
Sign\
up
=
S''inscrire
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_ja.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe
#
# 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.
Sign\
up
=
\u
30b5
\u
30a4
\u
30f3
\u
30a2
\u
30c3
\u
30d7
\ No newline at end of file
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_pt_BR.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva
#
# 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.
Sign\
up
=
Inscrever
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_tr.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Oguz Dag
#
# 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.
Sign\
up
=
Kay
\u0131
t ol
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_zh_CN.properties
0 → 100644
浏览文件 @
380b7269
# The MIT License
#
# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest
#
# 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.
Sign\
up
=
\u
6ce8
\u
518c
core/src/main/resources/hudson/security/Messages.properties
浏览文件 @
380b7269
...
...
@@ -22,6 +22,7 @@
GlobalMatrixAuthorizationStrategy.DisplayName
=
Matrix-based security
HudsonPrivateSecurityRealm.WouldYouLikeToSignUp
=
This {0} {1} is new to Hudson. Would you like to sign up?
LegacyAuthorizationStrategy.DisplayName
=
Legacy mode
HudsonPrivateSecurityRealm.DisplayName
=
Hudson''s own user database
...
...
core/src/main/resources/hudson/views/BuildButtonColumn/column.jelly
浏览文件 @
380b7269
...
...
@@ -26,7 +26,7 @@ THE SOFTWARE.
<td>
<j:if test="${job.buildable and job.hasPermission(job.BUILD)}">
<a href="${jobBaseUrl}${job.shortUrl}build?delay=0sec">
<img src="${imagesURL}/${subIconSize}/clock.
gif
"
<img src="${imagesURL}/${subIconSize}/clock.
png
"
title="${%Schedule a build}" alt="${%Schedule a build}"
border="0"/>
</a>
...
...
core/src/main/resources/lib/hudson/newFromList/form.jelly
浏览文件 @
380b7269
...
...
@@ -33,6 +33,8 @@ THE SOFTWARE.
@checkUrl : form field validation url
-->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:s="/lib/form">
<j:set var="descriptors" value="${h.filterDescriptors(it,attrs.descriptors)}" />
<s:form method="post" action="createItem">
<s:entry title="${attrs.nameTitle}">
<s:textbox id="name" name="name" checkUrl="'${rootURL}/${attrs.checkUrl}?value='+encodeURIComponent(this.value)"
...
...
@@ -40,7 +42,7 @@ THE SOFTWARE.
<script>$('name').focus();</script>
</s:entry>
<j:forEach var="descriptor" items="${
attrs.
descriptors}">
<j:forEach var="descriptor" items="${descriptors}">
<s:block>
<input type="radio" name="mode" value="${descriptor.class.name}" onchange="updateOk(this.form)" onclick="updateOk(this.form)" />
<st:nbsp/>
...
...
maven-agent/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
<relativePath>
../pom.xml
</relativePath>
</parent>
...
...
maven-interceptor/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
<relativePath>
../pom.xml
</relativePath>
</parent>
...
...
maven-plugin/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
</parent>
<artifactId>
maven-plugin
</artifactId>
...
...
maven-plugin/src/main/java/hudson/maven/Maven3Builder.java
浏览文件 @
380b7269
...
...
@@ -25,8 +25,8 @@ package hudson.maven;
import
hudson.Launcher
;
import
hudson.maven.MavenBuild.ProxyImpl2
;
import
hudson.maven.util.ExecutionEventLogger
;
import
hudson.model.BuildListener
;
import
hudson.model.FreeStyleProject
;
import
hudson.model.Hudson
;
import
hudson.model.Result
;
import
hudson.remoting.Channel
;
...
...
@@ -49,6 +49,7 @@ import java.util.concurrent.ConcurrentHashMap;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.concurrent.ExecutionException
;
import
org.apache.maven.cli.PrintStreamLogger
;
import
org.apache.maven.execution.AbstractExecutionListener
;
import
org.apache.maven.execution.ExecutionEvent
;
import
org.apache.maven.execution.ExecutionListener
;
...
...
@@ -251,6 +252,8 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
private
final
Map
<
ModuleName
,
List
<
MavenReporter
>>
reporters
=
new
HashMap
<
ModuleName
,
List
<
MavenReporter
>>();
private
final
Map
<
ModuleName
,
Long
>
currentMojoStartPerModuleName
=
new
ConcurrentHashMap
<
ModuleName
,
Long
>();
private
ExecutionEventLogger
eventLogger
;
public
MavenExecutionListener
(
Maven3Builder
maven3Builder
)
{
this
.
maven3Builder
=
maven3Builder
;
...
...
@@ -261,6 +264,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
executedMojosPerModule
.
put
(
e
.
getKey
(),
new
CopyOnWriteArrayList
<
ExecutedMojo
>()
);
}
this
.
reporters
.
putAll
(
new
HashMap
<
ModuleName
,
List
<
MavenReporter
>>(
maven3Builder
.
reporters
)
);
this
.
eventLogger
=
new
ExecutionEventLogger
(
new
PrintStreamLogger
(
maven3Builder
.
listener
.
getLogger
()
)
);
}
private
MavenBuildProxy2
getMavenBuildProxy2
(
MavenProject
mavenProject
)
{
...
...
@@ -302,14 +306,14 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
* @see org.apache.maven.execution.ExecutionListener#projectDiscoveryStarted(org.apache.maven.execution.ExecutionEvent)
*/
public
void
projectDiscoveryStarted
(
ExecutionEvent
event
)
{
// no op
this
.
eventLogger
.
projectDiscoveryStarted
(
event
);
}
/**
* @see org.apache.maven.execution.ExecutionListener#sessionStarted(org.apache.maven.execution.ExecutionEvent)
*/
public
void
sessionStarted
(
ExecutionEvent
event
)
{
// no op
this
.
eventLogger
.
sessionStarted
(
event
);
}
/**
...
...
@@ -317,6 +321,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
*/
public
void
sessionEnded
(
ExecutionEvent
event
)
{
maven3Builder
.
listener
.
getLogger
().
println
(
"sessionEnded"
);
this
.
eventLogger
.
sessionEnded
(
event
);
}
/**
...
...
@@ -325,16 +330,18 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
public
void
projectSkipped
(
ExecutionEvent
event
)
{
maven3Builder
.
listener
.
getLogger
().
println
(
"projectSkipped "
+
event
.
getProject
().
getGroupId
()
+
":"
+
event
.
getProject
().
getArtifactId
()
+
":"
+
event
.
getProject
().
getVersion
());
+
":"
+
event
.
getProject
().
getVersion
());
this
.
eventLogger
.
projectSkipped
(
event
);
}
/**
* @see org.apache.maven.execution.ExecutionListener#projectStarted(org.apache.maven.execution.ExecutionEvent)
*/
public
void
projectStarted
(
ExecutionEvent
event
)
{
maven3Builder
.
listener
.
getLogger
().
println
(
"projectStarted "
+
event
.
getProject
().
getGroupId
()
+
":"
+
event
.
getProject
().
getArtifactId
()
+
":"
+
event
.
getProject
().
getVersion
()
);
reccordProjectStarted
(
event
);
//maven3Builder.listener.getLogger().println( "projectStarted " + event.getProject().getGroupId() + ":"
// + event.getProject().getArtifactId() + ":" + event.getProject().getVersion() );
reccordProjectStarted
(
event
);
this
.
eventLogger
.
projectStarted
(
event
);
}
...
...
@@ -381,6 +388,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
+
event
.
getProject
().
getArtifactId
()
+
":"
+
event
.
getProject
().
getVersion
());
reccordProjectSucceeded
(
event
);
this
.
eventLogger
.
projectSucceeded
(
event
);
}
public
void
reccordProjectSucceeded
(
ExecutionEvent
event
)
{
...
...
@@ -425,6 +433,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
+
":"
+
event
.
getProject
().
getArtifactId
()
+
":"
+
event
.
getProject
().
getVersion
());
reccordProjectFailed
(
event
);
this
.
eventLogger
.
projectFailed
(
event
);
}
public
void
reccordProjectFailed
(
ExecutionEvent
event
)
{
...
...
@@ -467,17 +476,19 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
+
event
.
getMojoExecution
().
getArtifactId
()
+
":"
+
event
.
getMojoExecution
().
getVersion
()
+
"("
+
event
.
getMojoExecution
().
getExecutionId
()
+
")"
);
this
.
eventLogger
.
mojoSkipped
(
event
);
}
/**
* @see org.apache.maven.execution.ExecutionListener#mojoStarted(org.apache.maven.execution.ExecutionEvent)
*/
public
void
mojoStarted
(
ExecutionEvent
event
)
{
maven3Builder
.
listener
.
getLogger
().
println
(
"mojoStarted "
+
event
.
getMojoExecution
().
getGroupId
()
+
":"
+
event
.
getMojoExecution
().
getArtifactId
()
+
":"
+
event
.
getMojoExecution
().
getVersion
()
+
"("
+
event
.
getMojoExecution
().
getExecutionId
()
+
")"
);
//
maven3Builder.listener.getLogger().println("mojoStarted " + event.getMojoExecution().getGroupId() + ":"
//
+ event.getMojoExecution().getArtifactId() + ":"
//
+ event.getMojoExecution().getVersion()
//
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoStarted
(
event
);
this
.
eventLogger
.
mojoStarted
(
event
);
}
public
void
reccordMojoStarted
(
ExecutionEvent
event
)
{
...
...
@@ -513,11 +524,12 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
* @see org.apache.maven.execution.ExecutionListener#mojoSucceeded(org.apache.maven.execution.ExecutionEvent)
*/
public
void
mojoSucceeded
(
ExecutionEvent
event
)
{
maven3Builder
.
listener
.
getLogger
().
println
(
"mojoSucceeded "
+
event
.
getMojoExecution
().
getGroupId
()
+
":"
+
event
.
getMojoExecution
().
getArtifactId
()
+
":"
+
event
.
getMojoExecution
().
getVersion
()
+
"("
+
event
.
getMojoExecution
().
getExecutionId
()
+
")"
);
//
maven3Builder.listener.getLogger().println("mojoSucceeded " + event.getMojoExecution().getGroupId() + ":"
//
+ event.getMojoExecution().getArtifactId() + ":"
//
+ event.getMojoExecution().getVersion()
//
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoSucceeded
(
event
);
this
.
eventLogger
.
mojoSucceeded
(
event
);
}
public
void
reccordMojoSucceeded
(
ExecutionEvent
event
)
{
...
...
@@ -573,6 +585,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
+
event
.
getMojoExecution
().
getVersion
()
+
"("
+
event
.
getMojoExecution
().
getExecutionId
()
+
")"
);
reccordMojoFailed
(
event
);
this
.
eventLogger
.
mojoFailed
(
event
);
}
public
void
reccordMojoFailed
(
ExecutionEvent
event
)
{
...
...
@@ -660,7 +673,8 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
public
void
forkedProjectStarted
(
ExecutionEvent
event
)
{
maven3Builder
.
listener
.
getLogger
().
println
(
"forkedProjectStarted "
+
event
.
getProject
().
getGroupId
()
+
":"
+
event
.
getProject
().
getArtifactId
()
+
event
.
getProject
().
getVersion
()
);
reccordProjectStarted
(
event
);
reccordProjectStarted
(
event
);
this
.
eventLogger
.
forkedProjectStarted
(
event
);
}
/**
...
...
@@ -672,6 +686,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
+
event
.
getProject
().
getArtifactId
()
+
event
.
getProject
().
getVersion
());
reccordProjectSucceeded
(
event
);
this
.
eventLogger
.
forkedProjectSucceeded
(
event
);
}
/**
...
...
maven-plugin/src/main/java/hudson/maven/MavenModuleSet.java
浏览文件 @
380b7269
...
...
@@ -225,6 +225,10 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
new
DescribableList
<
BuildWrapper
,
Descriptor
<
BuildWrapper
>>(
this
);
public
MavenModuleSet
(
String
name
)
{
this
(
Hudson
.
getInstance
(),
name
);
}
public
MavenModuleSet
(
ItemGroup
parent
,
String
name
)
{
super
(
Hudson
.
getInstance
(),
name
);
}
...
...
@@ -233,10 +237,6 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
return
"."
;
}
public
Hudson
getParent
()
{
return
Hudson
.
getInstance
();
}
public
Collection
<
MavenModule
>
getItems
()
{
return
modules
.
values
();
}
...
...
@@ -449,6 +449,10 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
throw
new
UnsupportedOperationException
();
}
public
void
onDeleted
(
MavenModule
item
)
throws
IOException
{
// noop
}
public
Collection
<
Job
>
getAllJobs
()
{
Set
<
Job
>
jobs
=
new
HashSet
<
Job
>(
getItems
());
jobs
.
add
(
this
);
...
...
@@ -902,8 +906,8 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
return
Messages
.
MavenModuleSet_DiplayName
();
}
public
MavenModuleSet
newInstance
(
String
name
)
{
return
new
MavenModuleSet
(
name
);
public
MavenModuleSet
newInstance
(
ItemGroup
parent
,
String
name
)
{
return
new
MavenModuleSet
(
parent
,
name
);
}
public
Maven
.
DescriptorImpl
getMavenDescriptor
()
{
...
...
maven-plugin/src/main/java/hudson/maven/MavenModuleSetBuild.java
浏览文件 @
380b7269
...
...
@@ -877,7 +877,6 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
void
preBuild
(
MavenSession
session
,
ReactorManager
rm
,
EventDispatcher
dispatcher
)
throws
BuildFailureException
,
LifecycleExecutionException
,
IOException
,
InterruptedException
{
// set all modules which are not actually being build (in incremental builds) to NOT_BUILD
@SuppressWarnings
(
"unchecked"
)
List
<
MavenProject
>
projects
=
rm
.
getSortedProjects
();
Set
<
ModuleName
>
buildingProjects
=
new
HashSet
<
ModuleName
>();
for
(
MavenProject
p
:
projects
)
{
...
...
@@ -1146,7 +1145,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
List
<
MavenProject
>
mps
=
new
ArrayList
<
MavenProject
>(
0
);
if
(
maven3OrLater
)
{
mps
=
embedder
.
readProjects
(
pom
,
tru
e
);
mps
=
embedder
.
readProjects
(
pom
,
!
this
.
nonRecursiv
e
);
}
else
{
// http://issues.hudson-ci.org/browse/HUDSON-8390
...
...
@@ -1156,7 +1155,9 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
rootProject
=
mavenProject
;
mps
.
add
(
mavenProject
);
reactorReader
.
addProject
(
mavenProject
);
readChilds
(
mavenProject
,
embedder
,
mps
,
reactorReader
);
if
(!
this
.
nonRecursive
)
{
readChilds
(
mavenProject
,
embedder
,
mps
,
reactorReader
);
}
}
Map
<
String
,
MavenProject
>
canonicalPaths
=
new
HashMap
<
String
,
MavenProject
>(
mps
.
size
()
);
for
(
MavenProject
mp
:
mps
)
{
...
...
@@ -1215,18 +1216,24 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
PomInfo
pi
=
new
PomInfo
(
mp
,
parent
,
relPath
);
infos
.
add
(
pi
);
for
(
String
modulePath
:
mp
.
getModules
())
{
if
(
StringUtils
.
isBlank
(
modulePath
))
{
continue
;
if
(!
this
.
nonRecursive
)
{
for
(
String
modulePath
:
mp
.
getModules
())
{
if
(
StringUtils
.
isBlank
(
modulePath
))
{
continue
;
}
File
path
=
new
File
(
mp
.
getBasedir
(),
modulePath
);
// HUDSON-8391 : Modules are indexed by POM path thus
// by default we have to add the default pom.xml file
if
(
path
.
isDirectory
())
path
=
new
File
(
mp
.
getBasedir
(),
modulePath
+
"/pom.xml"
);
MavenProject
child
=
abslPath
.
get
(
path
.
getCanonicalPath
());
if
(
child
==
null
)
{
listener
.
getLogger
().
printf
(
"Found a module with path "
+
modulePath
+
" but no associated project"
);
continue
;
}
toPomInfo
(
child
,
pi
,
abslPath
,
infos
);
}
File
path
=
new
File
(
mp
.
getBasedir
(),
modulePath
);
// HUDSON-8391 : Modules are indexed by POM path thus
// by default we have to add the default pom.xml file
if
(
path
.
isDirectory
())
path
=
new
File
(
mp
.
getBasedir
(),
modulePath
+
"/pom.xml"
);
MavenProject
child
=
abslPath
.
get
(
path
.
getCanonicalPath
());
toPomInfo
(
child
,
pi
,
abslPath
,
infos
);
}
}
...
...
maven-plugin/src/main/java/hudson/maven/MavenUtil.java
浏览文件 @
380b7269
...
...
@@ -44,6 +44,7 @@ import java.util.Enumeration;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Properties
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
org.apache.commons.io.IOUtils
;
...
...
@@ -52,6 +53,8 @@ import org.apache.maven.artifact.versioning.ComparableVersion;
import
org.apache.maven.project.MavenProject
;
import
org.apache.maven.project.ProjectBuildingException
;
import
static
java
.
util
.
logging
.
Level
.
FINE
;
/**
* @author Kohsuke Kawaguchi
*/
...
...
@@ -185,25 +188,25 @@ public class MavenUtil {
:
org
.
codehaus
.
plexus
.
logging
.
Logger
.
LEVEL_INFO
);
mavenRequest
.
setMavenLoggerManager
(
logger
);
ClassLoader
cl
=
MavenUtil
.
class
.
getClassLoader
();
ClassLoader
mavenEmbedderClassLoader
=
mavenEmbedderRequest
.
getClassLoader
()
==
null
?
new
MaskingClassLoader
(
cl
)
mavenEmbedderRequest
.
getClassLoader
()
==
null
?
new
MaskingClassLoader
(
MavenUtil
.
class
.
getClassLoader
()
)
:
mavenEmbedderRequest
.
getClassLoader
();
{
// are we loading the right components.xml? (and not from Maven that's running Jetty, if we are running in "mvn hudson-dev:run" or "mvn hpi:run"?
Enumeration
<
URL
>
e
=
mavenEmbedderClassLoader
.
getResources
(
"META-INF/plexus/components.xml"
);
while
(
e
.
hasMoreElements
())
{
URL
url
=
e
.
nextElement
();
LOGGER
.
fine
(
"components.xml from "
+
url
);
}
}
mavenRequest
.
setProcessPlugins
(
mavenEmbedderRequest
.
isProcessPlugins
()
);
mavenRequest
.
setResolveDependencies
(
mavenEmbedderRequest
.
isResolveDependencies
()
);
mavenRequest
.
setValidationLevel
(
mavenEmbedderRequest
.
getValidationLevel
()
);
// TODO check this MaskingClassLoader with maven 3 artifacts
MavenEmbedder
maven
=
new
MavenEmbedder
(
mavenEmbedderClassLoader
,
mavenRequest
);
{
Enumeration
<
URL
>
e
=
cl
.
getResources
(
"META-INF/plexus/components.xml"
);
while
(
e
.
hasMoreElements
())
{
URL
url
=
e
.
nextElement
();
LOGGER
.
fine
(
"components.xml from "
+
url
);
}
}
return
maven
;
}
...
...
maven-plugin/src/main/java/hudson/maven/util/ExecutionEventLogger.java
0 → 100644
浏览文件 @
380b7269
package
hudson.maven.util
;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.TimeZone
;
import
org.apache.maven.execution.AbstractExecutionListener
;
import
org.apache.maven.execution.BuildFailure
;
import
org.apache.maven.execution.BuildSuccess
;
import
org.apache.maven.execution.BuildSummary
;
import
org.apache.maven.execution.ExecutionEvent
;
import
org.apache.maven.execution.MavenExecutionResult
;
import
org.apache.maven.execution.MavenSession
;
import
org.apache.maven.plugin.MojoExecution
;
import
org.apache.maven.project.MavenProject
;
import
org.codehaus.plexus.logging.Logger
;
/**
* Logs execution events to a user-supplied logger.
*
* @author Benjamin Bentmann
*/
public
class
ExecutionEventLogger
extends
AbstractExecutionListener
{
private
final
Logger
logger
;
private
static
final
int
LINE_LENGTH
=
72
;
public
ExecutionEventLogger
(
Logger
logger
)
{
if
(
logger
==
null
)
{
throw
new
IllegalArgumentException
(
"logger missing"
);
}
this
.
logger
=
logger
;
}
private
static
String
chars
(
char
c
,
int
count
)
{
StringBuilder
buffer
=
new
StringBuilder
(
count
);
for
(
int
i
=
count
;
i
>
0
;
i
--
)
{
buffer
.
append
(
c
);
}
return
buffer
.
toString
();
}
private
static
String
getFormattedTime
(
long
time
)
{
String
pattern
=
"s.SSS's'"
;
if
(
time
/
60000L
>
0
)
{
pattern
=
"m:s"
+
pattern
;
if
(
time
/
3600000L
>
0
)
{
pattern
=
"H:m"
+
pattern
;
}
}
DateFormat
fmt
=
new
SimpleDateFormat
(
pattern
);
fmt
.
setTimeZone
(
TimeZone
.
getTimeZone
(
"UTC"
)
);
return
fmt
.
format
(
new
Date
(
time
)
);
}
@Override
public
void
projectDiscoveryStarted
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
logger
.
info
(
"Scanning for projects..."
);
}
}
@Override
public
void
sessionStarted
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
&&
event
.
getSession
().
getProjects
().
size
()
>
1
)
{
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
logger
.
info
(
"Reactor Build Order:"
);
logger
.
info
(
""
);
for
(
MavenProject
project
:
event
.
getSession
().
getProjects
()
)
{
logger
.
info
(
project
.
getName
()
);
}
}
}
@Override
public
void
sessionEnded
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
if
(
event
.
getSession
().
getProjects
().
size
()
>
1
)
{
logReactorSummary
(
event
.
getSession
()
);
}
logResult
(
event
.
getSession
()
);
logStats
(
event
.
getSession
()
);
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
}
}
private
void
logReactorSummary
(
MavenSession
session
)
{
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
logger
.
info
(
"Reactor Summary:"
);
logger
.
info
(
""
);
MavenExecutionResult
result
=
session
.
getResult
();
for
(
MavenProject
project
:
session
.
getProjects
()
)
{
StringBuilder
buffer
=
new
StringBuilder
(
128
);
buffer
.
append
(
project
.
getName
()
);
buffer
.
append
(
' '
);
while
(
buffer
.
length
()
<
LINE_LENGTH
-
21
)
{
buffer
.
append
(
'.'
);
}
buffer
.
append
(
' '
);
BuildSummary
buildSummary
=
result
.
getBuildSummary
(
project
);
if
(
buildSummary
==
null
)
{
buffer
.
append
(
"SKIPPED"
);
}
else
if
(
buildSummary
instanceof
BuildSuccess
)
{
buffer
.
append
(
"SUCCESS ["
);
buffer
.
append
(
getFormattedTime
(
buildSummary
.
getTime
()
)
);
buffer
.
append
(
"]"
);
}
else
if
(
buildSummary
instanceof
BuildFailure
)
{
buffer
.
append
(
"FAILURE ["
);
buffer
.
append
(
getFormattedTime
(
buildSummary
.
getTime
()
)
);
buffer
.
append
(
"]"
);
}
logger
.
info
(
buffer
.
toString
()
);
}
}
private
void
logResult
(
MavenSession
session
)
{
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
if
(
session
.
getResult
().
hasExceptions
()
)
{
logger
.
info
(
"BUILD FAILURE"
);
}
else
{
logger
.
info
(
"BUILD SUCCESS"
);
}
}
private
void
logStats
(
MavenSession
session
)
{
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
Date
finish
=
new
Date
();
long
time
=
finish
.
getTime
()
-
session
.
getRequest
().
getStartTime
().
getTime
();
String
wallClock
=
session
.
getRequest
().
isThreadConfigurationPresent
()
?
" (Wall Clock)"
:
""
;
logger
.
info
(
"Total time: "
+
getFormattedTime
(
time
)
+
wallClock
);
logger
.
info
(
"Finished at: "
+
finish
);
System
.
gc
();
Runtime
r
=
Runtime
.
getRuntime
();
long
MB
=
1024
*
1024
;
logger
.
info
(
"Final Memory: "
+
(
r
.
totalMemory
()
-
r
.
freeMemory
()
)
/
MB
+
"M/"
+
r
.
totalMemory
()
/
MB
+
"M"
);
}
@Override
public
void
projectSkipped
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
logger
.
info
(
chars
(
' '
,
LINE_LENGTH
)
);
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
logger
.
info
(
"Skipping "
+
event
.
getProject
().
getName
()
);
logger
.
info
(
"This project has been banned from the build due to previous failures."
);
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
}
}
@Override
public
void
projectStarted
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
logger
.
info
(
chars
(
' '
,
LINE_LENGTH
)
);
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
logger
.
info
(
"Building "
+
event
.
getProject
().
getName
()
+
" "
+
event
.
getProject
().
getVersion
()
);
logger
.
info
(
chars
(
'-'
,
LINE_LENGTH
)
);
}
}
@Override
public
void
mojoSkipped
(
ExecutionEvent
event
)
{
if
(
logger
.
isWarnEnabled
()
)
{
logger
.
warn
(
"Goal "
+
event
.
getMojoExecution
().
getGoal
()
+
" requires online mode for execution but Maven is currently offline, skipping"
);
}
}
@Override
public
void
mojoStarted
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
StringBuilder
buffer
=
new
StringBuilder
(
128
);
buffer
.
append
(
"--- "
);
append
(
buffer
,
event
.
getMojoExecution
()
);
append
(
buffer
,
event
.
getProject
()
);
buffer
.
append
(
" ---"
);
logger
.
info
(
""
);
logger
.
info
(
buffer
.
toString
()
);
}
}
@Override
public
void
forkStarted
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
StringBuilder
buffer
=
new
StringBuilder
(
128
);
buffer
.
append
(
">>> "
);
append
(
buffer
,
event
.
getMojoExecution
()
);
append
(
buffer
,
event
.
getProject
()
);
buffer
.
append
(
" >>>"
);
logger
.
info
(
""
);
logger
.
info
(
buffer
.
toString
()
);
}
}
@Override
public
void
forkSucceeded
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
)
{
StringBuilder
buffer
=
new
StringBuilder
(
128
);
buffer
.
append
(
"<<< "
);
append
(
buffer
,
event
.
getMojoExecution
()
);
append
(
buffer
,
event
.
getProject
()
);
buffer
.
append
(
" <<<"
);
logger
.
info
(
""
);
logger
.
info
(
buffer
.
toString
()
);
}
}
private
void
append
(
StringBuilder
buffer
,
MojoExecution
me
)
{
buffer
.
append
(
me
.
getArtifactId
()
).
append
(
':'
).
append
(
me
.
getVersion
()
);
buffer
.
append
(
':'
).
append
(
me
.
getGoal
()
);
if
(
me
.
getExecutionId
()
!=
null
)
{
buffer
.
append
(
" ("
).
append
(
me
.
getExecutionId
()
).
append
(
')'
);
}
}
private
void
append
(
StringBuilder
buffer
,
MavenProject
project
)
{
buffer
.
append
(
" @ "
).
append
(
project
.
getArtifactId
()
);
}
@Override
public
void
forkedProjectStarted
(
ExecutionEvent
event
)
{
if
(
logger
.
isInfoEnabled
()
&&
event
.
getMojoExecution
().
getForkedExecutions
().
size
()
>
1
)
{
logger
.
info
(
chars
(
' '
,
LINE_LENGTH
)
);
logger
.
info
(
chars
(
'>'
,
LINE_LENGTH
)
);
logger
.
info
(
"Forking "
+
event
.
getProject
().
getName
()
+
" "
+
event
.
getProject
().
getVersion
()
);
logger
.
info
(
chars
(
'>'
,
LINE_LENGTH
)
);
}
}
}
maven3-agent/pom.xml
浏览文件 @
380b7269
...
...
@@ -4,7 +4,7 @@
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
</parent>
<artifactId>
maven3-agent
</artifactId>
<name>
Hudson Maven3 CLI Agent
</name>
...
...
maven3-interceptor/pom.xml
浏览文件 @
380b7269
...
...
@@ -4,7 +4,7 @@
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
</parent>
<artifactId>
maven3-interceptor
</artifactId>
<name>
Hudson Maven3 Interceptor
</name>
...
...
pom.xml
浏览文件 @
380b7269
...
...
@@ -32,7 +32,7 @@ THE SOFTWARE.
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
<packaging>
pom
</packaging>
<name>
Hudson main module
</name>
...
...
remoting/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
<relativePath>
../pom.xml
</relativePath>
</parent>
...
...
test/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<artifactId>
pom
</artifactId>
<groupId>
org.jvnet.hudson.main
</groupId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
org.jvnet.hudson.main
</groupId>
...
...
test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
浏览文件 @
380b7269
...
...
@@ -30,6 +30,7 @@ import hudson.*;
import
hudson.Util
;
import
hudson.model.*
;
import
hudson.model.Queue.Executable
;
import
hudson.security.ACL
;
import
hudson.security.AbstractPasswordBasedSecurityRealm
;
import
hudson.security.GroupDetails
;
import
hudson.security.SecurityRealm
;
...
...
@@ -100,6 +101,7 @@ import net.sourceforge.htmlunit.corejs.javascript.ContextFactory.Listener;
import
org.acegisecurity.AuthenticationException
;
import
org.acegisecurity.BadCredentialsException
;
import
org.acegisecurity.GrantedAuthority
;
import
org.acegisecurity.context.SecurityContextHolder
;
import
org.acegisecurity.userdetails.UserDetails
;
import
org.acegisecurity.userdetails.UsernameNotFoundException
;
import
org.apache.commons.httpclient.NameValuePair
;
...
...
@@ -316,6 +318,8 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
@Override
protected
void
runTest
()
throws
Throwable
{
System
.
out
.
println
(
"=== Starting "
+
getClass
().
getSimpleName
()
+
"."
+
getName
());
// so that test code has all the access to the system
SecurityContextHolder
.
getContext
().
setAuthentication
(
ACL
.
SYSTEM
);
super
.
runTest
();
}
...
...
test/src/test/java/hudson/maven/Maven3BuildTest.java
浏览文件 @
380b7269
...
...
@@ -133,6 +133,19 @@ public class Maven3BuildTest extends HudsonTestCase {
assertFalse
(
mmsb
.
getProject
().
getModules
().
isEmpty
());
}
@Bug
(
8484
)
public
void
testMultiModMavenNonRecursive
()
throws
Exception
{
MavenInstallation
mavenInstallation
=
configureMaven3
();
MavenModuleSet
m
=
createMavenProject
();
m
.
setMaven
(
mavenInstallation
.
getName
()
);
m
.
getReporters
().
add
(
new
TestReporter
());
m
.
setScm
(
new
ExtractResourceSCM
(
getClass
().
getResource
(
"maven-multimod.zip"
)));
m
.
setGoals
(
"-N validate"
);
assertTrue
(
"MavenModuleSet.isNonRecursive() should be true"
,
m
.
isNonRecursive
());
buildAndAssertSuccess
(
m
);
assertEquals
(
"not only one module"
,
1
,
m
.
getModules
().
size
());
}
private
static
class
TestReporter
extends
MavenReporter
{
@Override
public
boolean
end
(
MavenBuild
build
,
Launcher
launcher
,
BuildListener
listener
)
throws
InterruptedException
,
IOException
{
...
...
test/src/test/java/hudson/maven/MavenMultiModuleTest.java
浏览文件 @
380b7269
...
...
@@ -261,6 +261,18 @@ public class MavenMultiModuleTest extends HudsonTestCase {
}
}
@Bug
(
8484
)
public
void
testMultiModMavenNonRecursive
()
throws
Exception
{
configureDefaultMaven
(
"apache-maven-2.2.1"
,
MavenInstallation
.
MAVEN_21
);
MavenModuleSet
m
=
createMavenProject
();
m
.
getReporters
().
add
(
new
TestReporter
());
m
.
setScm
(
new
ExtractResourceSCM
(
getClass
().
getResource
(
"maven-multimod.zip"
)));
m
.
setGoals
(
"-N validate"
);
assertTrue
(
"MavenModuleSet.isNonRecursive() should be true"
,
m
.
isNonRecursive
());
buildAndAssertSuccess
(
m
);
assertEquals
(
"not only one module"
,
1
,
m
.
getModules
().
size
());
}
/*
public void testParallelMultiModMavenWsExists() throws Exception {
configureDefaultMaven();
...
...
test/src/test/java/hudson/model/QueueTest.java
浏览文件 @
380b7269
...
...
@@ -206,8 +206,8 @@ public class QueueTest extends HudsonTestCase {
StringBuilder
causes
=
new
StringBuilder
();
for
(
Cause
c
:
ca
.
getCauses
())
causes
.
append
(
c
.
getShortDescription
()
+
"\n"
);
assertEquals
(
"Build causes should have all items, even duplicates"
,
"Started by user
anonymous
\nStarted by an SCM change\n"
+
"Started by user
anonymous
\nStarted by timer\n"
"Started by user
SYSTEM
\nStarted by an SCM change\n"
+
"Started by user
SYSTEM
\nStarted by timer\n"
+
"Started by remote host 1.2.3.4 with note: test\n"
+
"Started by remote host 4.3.2.1 with note: test\n"
+
"Started by an SCM change\n"
...
...
@@ -220,7 +220,7 @@ public class QueueTest extends HudsonTestCase {
WebClient
wc
=
new
WebClient
();
String
buildPage
=
wc
.
getPage
(
build
,
""
).
asText
().
replace
(
'\n'
,
' '
);
assertTrue
(
"Build page should combine duplicates and show counts: "
+
buildPage
,
buildPage
.
contains
(
"Started by user
anonymous
(2 times) "
buildPage
.
contains
(
"Started by user
SYSTEM
(2 times) "
+
"Started by an SCM change (3 times) "
+
"Started by timer (2 times) "
+
"Started by remote host 1.2.3.4 with note: test (2 times) "
...
...
ui-samples-plugin/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
</parent>
<artifactId>
ui-samples-plugin
</artifactId>
...
...
war/pom.xml
浏览文件 @
380b7269
...
...
@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>
org.jvnet.hudson.main
</groupId>
<artifactId>
pom
</artifactId>
<version>
1.39
4
-SNAPSHOT
</version>
<version>
1.39
5
-SNAPSHOT
</version>
<relativePath>
../pom.xml
</relativePath>
</parent>
...
...
@@ -135,7 +135,7 @@ THE SOFTWARE.
<!-- this is really just a patched version of maven-jetty-plugin to workaround issue #932 -->
<groupId>
org.jvnet.hudson.tools
</groupId>
<artifactId>
maven-hudson-dev-plugin
</artifactId>
<version>
6.1.7
</version>
<version>
6.1.7
-hudson-1
</version>
<configuration>
<contextPath>
${contextPath}
</contextPath>
<connectors>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录