Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FIY695
jenkins
提交
d184d53b
J
jenkins
项目概览
FIY695
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
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,发现更多精彩内容 >>
提交
d184d53b
编写于
3月 09, 2012
作者:
K
Kohsuke Kawaguchi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[JENKINS-9118]
Tar/untar now correctly supports symlinks.
上级
48daab0f
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
118 addition
and
4 deletion
+118
-4
changelog.html
changelog.html
+2
-0
core/src/main/java/hudson/FilePath.java
core/src/main/java/hudson/FilePath.java
+71
-2
core/src/main/java/hudson/Util.java
core/src/main/java/hudson/Util.java
+9
-1
core/src/main/java/hudson/util/DirScanner.java
core/src/main/java/hudson/util/DirScanner.java
+12
-0
core/src/test/java/hudson/FilePathTest.java
core/src/test/java/hudson/FilePathTest.java
+23
-0
pom.xml
pom.xml
+1
-1
未找到文件。
changelog.html
浏览文件 @
d184d53b
...
...
@@ -55,6 +55,8 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div
id=
"trunk"
style=
"display:none"
>
<!--=TRUNK-BEGIN=-->
<ul
class=
image
>
<li
class=
bug
>
tar/untar now correctly handles symlinks.
<li
class=
bug
>
Fixed a bug in the auto-overwrite of bundled plugins on Windows.
(
<a
href=
"https://issues.jenkins-ci.org/browse/JENKINS-12514"
>
issue 12514
</a>
)
...
...
core/src/main/java/hudson/FilePath.java
浏览文件 @
d184d53b
...
...
@@ -46,8 +46,9 @@ import hudson.util.IOException2;
import
hudson.util.HeadBufferingStream
;
import
hudson.util.FormValidation
;
import
hudson.util.IOUtils
;
import
static
hudson
.
Util
.*;
import
static
hudson
.
util
.
jna
.
GNUCLibrary
.
LIBC
;
import
static
hudson
.
Util
.
fixEmpty
;
import
static
hudson
.
FilePath
.
TarCompression
.
GZIP
;
import
hudson.org.apache.tools.tar.TarInputStream
;
import
hudson.util.io.Archiver
;
...
...
@@ -75,6 +76,7 @@ import java.io.OutputStream;
import
java.io.Serializable
;
import
java.io.Writer
;
import
java.io.OutputStreamWriter
;
import
java.lang.reflect.Field
;
import
java.net.URI
;
import
java.net.URL
;
import
java.net.URLConnection
;
...
...
@@ -331,6 +333,15 @@ public final class FilePath implements Serializable {
zip
(
os
,(
FileFilter
)
null
);
}
public
void
zip
(
FilePath
dst
)
throws
IOException
,
InterruptedException
{
OutputStream
os
=
dst
.
write
();
try
{
zip
(
os
);
}
finally
{
os
.
close
();
}
}
/**
* Creates a zip file from this directory by using the specified filter,
* and sends the result to the given output stream.
...
...
@@ -529,6 +540,39 @@ public final class FilePath implements Serializable {
}));
}
/**
* Creates a symlink to the specified target.
*
* @param target
* The file that the symlink should point to.
* @param listener
* If symlink creation requires a help of an external process, the error will be reported here.
* @since 1.456
*/
public
void
symlinkTo
(
final
String
target
,
final
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
act
(
new
FileCallable
<
Void
>()
{
public
Void
invoke
(
File
f
,
VirtualChannel
channel
)
throws
IOException
,
InterruptedException
{
Util
.
createSymlink
(
f
.
getParentFile
(),
target
,
f
.
getName
(),
listener
);
return
null
;
}
});
}
/**
* Resolves symlink, if the given file is a symlink. Otherwise return null.
* <p>
* If the resolution fails, report an error.
*
* @since 1.456
*/
public
String
readLink
()
throws
IOException
,
InterruptedException
{
return
act
(
new
FileCallable
<
String
>()
{
public
String
invoke
(
File
f
,
VirtualChannel
channel
)
throws
IOException
,
InterruptedException
{
return
Util
.
resolveSymlink
(
f
);
}
});
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
...
...
@@ -1756,7 +1800,13 @@ public final class FilePath implements Serializable {
File
parent
=
f
.
getParentFile
();
if
(
parent
!=
null
)
parent
.
mkdirs
();
IOUtils
.
copy
(
t
,
f
);
byte
linkFlag
=
(
Byte
)
LINKFLAG_FIELD
.
get
(
te
);
if
(
linkFlag
==
TarEntry
.
LF_SYMLINK
)
{
new
FilePath
(
f
).
symlinkTo
(
te
.
getLinkName
(),
TaskListener
.
NULL
);
}
else
{
IOUtils
.
copy
(
t
,
f
);
}
f
.
setLastModified
(
te
.
getModTime
().
getTime
());
int
mode
=
te
.
getMode
()&
0777
;
if
(
mode
!=
0
&&
!
Functions
.
isWindows
())
// be defensive
...
...
@@ -1765,6 +1815,11 @@ public final class FilePath implements Serializable {
}
}
catch
(
IOException
e
)
{
throw
new
IOException2
(
"Failed to extract "
+
name
,
e
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
// process this later
throw
new
IOException2
(
"Failed to extract "
+
name
,
e
);
}
catch
(
IllegalAccessException
e
)
{
throw
new
IOException2
(
"Failed to extract "
+
name
,
e
);
}
finally
{
t
.
close
();
}
...
...
@@ -2124,4 +2179,18 @@ public final class FilePath implements Serializable {
return
o1
.
length
()-
o2
.
length
();
}
};
private
static
final
Field
LINKFLAG_FIELD
=
getTarEntryLinkFlagField
();
private
static
Field
getTarEntryLinkFlagField
()
{
try
{
Field
f
=
TarEntry
.
class
.
getDeclaredField
(
"linkFlag"
);
f
.
setAccessible
(
true
);
return
f
;
}
catch
(
SecurityException
e
)
{
throw
new
AssertionError
(
e
);
}
catch
(
NoSuchFieldException
e
)
{
throw
new
AssertionError
(
e
);
}
}
}
core/src/main/java/hudson/Util.java
浏览文件 @
d184d53b
...
...
@@ -1022,6 +1022,14 @@ public class Util {
}
}
/**
* @deprecated as of 1.456
* Use {@link #resolveSymlink(File)}
*/
public
static
String
resolveSymlink
(
File
link
,
TaskListener
listener
)
throws
InterruptedException
,
IOException
{
return
resolveSymlink
(
link
);
}
/**
* Resolves symlink, if the given file is a symlink. Otherwise return null.
* <p>
...
...
@@ -1030,7 +1038,7 @@ public class Util {
* @param listener
* If we rely on an external command to resolve symlink, this is it.
*/
public
static
String
resolveSymlink
(
File
link
,
TaskListener
listener
)
throws
InterruptedException
,
IOException
{
public
static
String
resolveSymlink
(
File
link
)
throws
InterruptedException
,
IOException
{
if
(
Functions
.
isWindows
())
return
null
;
String
filename
=
link
.
getAbsolutePath
();
...
...
core/src/main/java/hudson/util/DirScanner.java
浏览文件 @
d184d53b
...
...
@@ -101,6 +101,18 @@ public abstract class DirScanner implements Serializable {
DirectoryScanner
ds
=
fs
.
getDirectoryScanner
(
new
org
.
apache
.
tools
.
ant
.
Project
());
for
(
String
f
:
ds
.
getIncludedFiles
())
{
File
file
=
new
File
(
dir
,
f
);
if
(
visitor
.
understandsSymlink
())
{
try
{
String
target
=
Util
.
resolveSymlink
(
file
,
TaskListener
.
NULL
);
if
(
target
!=
null
)
{
visitor
.
visitSymlink
(
file
,
target
,
f
);
continue
;
}
}
catch
(
InterruptedException
e
)
{
throw
(
IOException
)
new
InterruptedIOException
().
initCause
(
e
);
}
}
visitor
.
visit
(
file
,
f
);
}
}
...
...
core/src/test/java/hudson/FilePathTest.java
浏览文件 @
d184d53b
...
...
@@ -23,6 +23,8 @@
*/
package
hudson
;
import
hudson.FilePath.TarCompression
;
import
hudson.model.TaskListener
;
import
hudson.remoting.LocalChannel
;
import
hudson.remoting.VirtualChannel
;
import
hudson.util.IOException2
;
...
...
@@ -356,4 +358,25 @@ public class FilePathTest extends ChannelTestCase {
}
}
public
void
testSymlinkInTar
()
throws
Exception
{
if
(
Functions
.
isWindows
())
return
;
// can't test on Windows
FilePath
tmp
=
new
FilePath
(
Util
.
createTempDir
());
try
{
FilePath
in
=
tmp
.
child
(
"in"
);
in
.
mkdirs
();
in
.
child
(
"a"
).
touch
(
0
);
in
.
child
(
"b"
).
symlinkTo
(
"a"
,
TaskListener
.
NULL
);
FilePath
tar
=
tmp
.
child
(
"test.tar"
);
in
.
tar
(
tar
.
write
(),
"**/*"
);
FilePath
dst
=
in
.
child
(
"dst"
);
tar
.
untar
(
dst
,
TarCompression
.
NONE
);
assertEquals
(
"a"
,
dst
.
child
(
"b"
).
readLink
());
}
finally
{
tmp
.
deleteRecursive
();
}
}
}
pom.xml
浏览文件 @
d184d53b
...
...
@@ -136,7 +136,7 @@ THE SOFTWARE.
<dependency>
<groupId>
org.apache.ant
</groupId>
<artifactId>
ant
</artifactId>
<version>
1.8.
0
</version>
<version>
1.8.
3
</version>
</dependency>
<dependency>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录