Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
dae1565e
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,发现更多精彩内容 >>
提交
dae1565e
编写于
11月 19, 2010
作者:
K
Kohsuke Kawaguchi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
service installation is made UAC aware
上级
cf9b3d93
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
107 addition
and
11 deletion
+107
-11
core/pom.xml
core/pom.xml
+1
-1
core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
.../src/main/java/hudson/lifecycle/WindowsInstallerLink.java
+4
-6
core/src/main/java/hudson/lifecycle/WindowsSlaveInstaller.java
...src/main/java/hudson/lifecycle/WindowsSlaveInstaller.java
+49
-4
core/src/main/java/hudson/util/jna/Kernel32Utils.java
core/src/main/java/hudson/util/jna/Kernel32Utils.java
+53
-0
未找到文件。
core/pom.xml
浏览文件 @
dae1565e
...
...
@@ -737,7 +737,7 @@ THE SOFTWARE.
<dependency>
<groupId>
com.sun.winsw
</groupId>
<artifactId>
winsw
</artifactId>
<version>
1.
8
</version>
<version>
1.
9
</version>
<classifier>
bin
</classifier>
<type>
exe
</type>
<scope>
provided
</scope>
<!-- this isn't really a dependency that Maven should care about, so putting 'provided' -->
...
...
core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
浏览文件 @
dae1565e
...
...
@@ -30,7 +30,6 @@ import hudson.AbortException;
import
hudson.Extension
;
import
hudson.util.StreamTaskListener
;
import
hudson.util.jna.DotNet
;
import
hudson.Launcher.LocalLauncher
;
import
org.kohsuke.stapler.QueryParameter
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
...
...
@@ -127,9 +126,8 @@ public class WindowsInstallerLink extends ManagementLink {
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
StreamTaskListener
task
=
new
StreamTaskListener
(
baos
);
task
.
getLogger
().
println
(
"Installing a service"
);
int
r
=
new
LocalLauncher
(
task
).
launch
()
.
cmds
(
new
File
(
dir
,
"hudson.exe"
).
getPath
(),
"install"
)
.
stdout
(
task
.
getLogger
()).
pwd
(
dir
).
join
();
int
r
=
WindowsSlaveInstaller
.
runElevated
(
new
File
(
dir
,
"hudson.exe"
),
"install"
,
task
,
dir
);
if
(
r
!=
0
)
{
sendError
(
baos
.
toString
(),
req
,
rsp
);
return
;
...
...
@@ -197,8 +195,8 @@ public class WindowsInstallerLink extends ManagementLink {
}
LOGGER
.
info
(
"Starting a Windows service"
);
StreamTaskListener
task
=
StreamTaskListener
.
fromStdout
();
int
r
=
new
LocalLauncher
(
task
).
launch
().
cmds
(
new
File
(
installationDir
,
"hudson.exe"
),
"start"
)
.
stdout
(
task
).
pwd
(
installationDir
).
join
(
);
int
r
=
WindowsSlaveInstaller
.
runElevated
(
new
File
(
installationDir
,
"hudson.exe"
),
"start"
,
task
,
installationDir
);
task
.
getLogger
().
println
(
r
==
0
?
"Successfully started"
:
"start service failed. Exit code="
+
r
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
...
...
core/src/main/java/hudson/lifecycle/WindowsSlaveInstaller.java
浏览文件 @
dae1565e
...
...
@@ -23,30 +23,37 @@
*/
package
hudson.lifecycle
;
import
com.sun.jna.Native
;
import
hudson.Launcher.LocalLauncher
;
import
hudson.Util
;
import
hudson.model.TaskListener
;
import
hudson.remoting.Callable
;
import
hudson.remoting.Engine
;
import
hudson.remoting.jnlp.MainDialog
;
import
hudson.remoting.jnlp.MainMenu
;
import
hudson.util.StreamTaskListener
;
import
hudson.util.jna.DotNet
;
import
hudson.util.jna.Kernel32Utils
;
import
hudson.util.jna.SHELLEXECUTEINFO
;
import
hudson.util.jna.Shell32
;
import
org.apache.commons.io.FileUtils
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.io.output.ByteArrayOutputStream
;
import
javax.swing.*
;
import
static
javax
.
swing
.
JOptionPane
.
ERROR_MESSAGE
;
import
static
javax
.
swing
.
JOptionPane
.
OK_CANCEL_OPTION
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionListener
;
import
java.awt.event.KeyEvent
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.net.URL
;
import
static
hudson
.
util
.
jna
.
SHELLEXECUTEINFO
.*;
import
static
javax
.
swing
.
JOptionPane
.*;
/**
* @author Kohsuke Kawaguchi
*/
...
...
@@ -89,6 +96,44 @@ public class WindowsSlaveInstaller implements Callable<Void,RuntimeException>, A
return
null
;
}
/**
* Invokes slave.exe with a SCM management command.
*
* <p>
* If it fails in a way that indicates the presence of UAC, retry in an UAC compatible manner.
*/
static
int
runElevated
(
File
slaveExe
,
String
command
,
TaskListener
out
,
File
pwd
)
throws
IOException
,
InterruptedException
{
try
{
return
new
LocalLauncher
(
out
).
launch
().
cmds
(
slaveExe
,
command
).
stdout
(
out
).
pwd
(
pwd
).
join
();
}
catch
(
IOException
e
)
{
if
(
e
.
getMessage
().
contains
(
"CreateProcess"
)
&&
e
.
getMessage
().
contains
(
"=740"
))
{
// fall through
}
else
{
throw
e
;
}
}
// error code 740 is ERROR_ELEVATION_REQUIRED, indicating that
// we run in UAC-enabled Windows and we need to run this in an elevated privilege
SHELLEXECUTEINFO
sei
=
new
SHELLEXECUTEINFO
();
sei
.
fMask
=
SEE_MASK_NOCLOSEPROCESS
;
sei
.
lpVerb
=
"runas"
;
sei
.
lpFile
=
slaveExe
.
getAbsolutePath
();
sei
.
lpParameters
=
"/redirect redirect.log "
+
command
;
sei
.
lpDirectory
=
pwd
.
getAbsolutePath
();
sei
.
nShow
=
SW_HIDE
;
if
(!
Shell32
.
INSTANCE
.
ShellExecuteEx
(
sei
))
throw
new
IOException
(
"Failed to shellExecute: "
+
Native
.
getLastError
());
try
{
return
Kernel32Utils
.
waitForExitProcess
(
sei
.
hProcess
);
}
finally
{
FileInputStream
fin
=
new
FileInputStream
(
new
File
(
pwd
,
"redirect.log"
));
IOUtils
.
copy
(
fin
,
out
.
getLogger
());
fin
.
close
();
}
}
/**
* Called when the install menu is selected
*/
...
...
@@ -131,7 +176,7 @@ public class WindowsSlaveInstaller implements Callable<Void,RuntimeException>, A
// install as a service
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
StreamTaskListener
task
=
new
StreamTaskListener
(
baos
);
r
=
new
LocalLauncher
(
task
).
launch
().
cmds
(
slaveExe
,
"install"
).
stdout
(
task
).
pwd
(
dir
).
join
(
);
r
=
runElevated
(
slaveExe
,
"install"
,
task
,
dir
);
if
(
r
!=
0
)
{
JOptionPane
.
showMessageDialog
(
dialog
,
baos
.
toString
(),
"Error"
,
ERROR_MESSAGE
);
...
...
@@ -148,7 +193,7 @@ public class WindowsSlaveInstaller implements Callable<Void,RuntimeException>, A
public
void
run
()
{
try
{
StreamTaskListener
task
=
StreamTaskListener
.
fromStdout
();
int
r
=
new
LocalLauncher
(
task
).
launch
().
cmds
(
slaveExe
,
"start"
).
stdout
(
task
).
pwd
(
dir
).
join
(
);
int
r
=
runElevated
(
slaveExe
,
"start"
,
task
,
dir
);
task
.
getLogger
().
println
(
r
==
0
?
"Successfully started"
:
"start service failed. Exit code="
+
r
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
...
...
core/src/main/java/hudson/util/jna/Kernel32Utils.java
0 → 100644
浏览文件 @
dae1565e
/*
* 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.util.jna
;
import
com.sun.jna.Pointer
;
import
com.sun.jna.ptr.IntByReference
;
/**
*
* @author Kohsuke Kawaguchi
*/
public
class
Kernel32Utils
{
/**
* Given the process handle, waits for its completion and returns the exit code.
*/
public
static
int
waitForExitProcess
(
Pointer
hProcess
)
throws
InterruptedException
{
while
(
true
)
{
if
(
Thread
.
interrupted
())
throw
new
InterruptedException
();
Kernel32
.
INSTANCE
.
WaitForSingleObject
(
hProcess
,
1000
);
IntByReference
exitCode
=
new
IntByReference
();
exitCode
.
setValue
(-
1
);
Kernel32
.
INSTANCE
.
GetExitCodeProcess
(
hProcess
,
exitCode
);
int
v
=
exitCode
.
getValue
();
if
(
v
!=
Kernel32
.
STILL_ACTIVE
)
{
return
v
;
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录