分析 slave 上的remtoe fs 目录什么时候创建, 创建的权限为什么是700??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
首先在hudson/plugins/sshslaves/SSHLauncher.java文件中
这个方法是 启动 ssh slave的 入口
public void launch(final SlaveComputer computer, final TaskListener listener) throws InterruptedException {


connection = new Connection(host, port);
launcherExecutorService = Executors.newSingleThreadExecutor(new NamingThreadFactory(Executors.defaultThreadFactory(), "SSHLauncher.launch for '" + computer.getName() + "' node"));

然后其中加了一个 回调. 这个回调会在后面调用,这里使用先加上了.
Set<Callable<Boolean>> callables = new HashSet<>();
callables.add(new Callable<Boolean>() {
copyAgentJar(listener, workingDirectory); //
});//添加回调结束


final ExecutorService srv = launcherExecutorService;

回调是在这里真正调用的
results = srv.invokeAll(callables);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

/**
* Method copies the agent jar to the remote system.
*
* @param listener The listener.
* @param workingDirectory The directory into which the agent jar will be copied.
*
* @throws IOException If something goes wrong.
*/
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
value="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE",
justification="there is a bug related with Java 11 bytecode see https://github.com/spotbugs/spotbugs/issues/756")
private void copyAgentJar(TaskListener listener, String workingDirectory) throws IOException, InterruptedException {
String fileName = workingDirectory + SLASH_AGENT_JAR;

listener.getLogger().println(Messages.SSHLauncher_StartingSFTPClient(getTimestamp()));
SFTPClient sftpClient = null;
try {
sftpClient = new SFTPClient(connection);

try {
SFTPv3FileAttributes fileAttributes = sftpClient._stat(workingDirectory);
if (fileAttributes==null) {
listener.getLogger().println(Messages.SSHLauncher_RemoteFSDoesNotExist(getTimestamp(), workingDirectory));
sftpClient.mkdirs(workingDirectory, 0700);
} else if (fileAttributes.isRegularFile()) {
throw new IOException(Messages.SSHLauncher_RemoteFSIsAFile(workingDirectory));
}

listener.getLogger().println(Messages.SSHLauncher_CopyingAgentJar(getTimestamp()));
byte[] agentJar = new Slave.JnlpJar(AGENT_JAR).readFully();

// If the agent jar already exists see if it needs to be updated
boolean overwrite = true;
if (sftpClient.exists(fileName)) {
String sourceAgentHash = getMd5Hash(agentJar);
String existingAgentHash = getMd5Hash(readInputStreamIntoByteArrayAndClose(sftpClient.read(fileName)));
listener.getLogger().println(MessageFormat.format( "Source agent hash is {0}. "
+ "Installed agent hash is {1}", sourceAgentHash, existingAgentHash));

overwrite = !sourceAgentHash.equals(existingAgentHash);
}

if (overwrite) {
try {
// try to delete the file in case the agent we are copying is shorter than the agent
// that is already there
sftpClient.rm(fileName);
} catch (IOException e) {
// the file did not exist... so no need to delete it!
}

try (OutputStream os = sftpClient.writeToFile(fileName)) {
os.write(agentJar);
listener.getLogger()
.println(Messages.SSHLauncher_CopiedXXXBytes(getTimestamp(), agentJar.length));
} catch (Error error) {
throw error;
} catch (Throwable e) {
throw new IOException(Messages.SSHLauncher_ErrorCopyingAgentJarTo(fileName), e);
}
}else{
listener.getLogger().println("Verified agent jar. No update is necessary.");
}
} catch (Error error) {
throw error;
} catch (Throwable e) {
throw new IOException(Messages.SSHLauncher_ErrorCopyingAgentJarInto(workingDirectory), e);
}
} catch (IOException e) {
if (sftpClient == null) {
e.printStackTrace(listener.error(Messages.SSHLauncher_StartingSCPClient(getTimestamp())));
// lets try to recover if the agent doesn't have an SFTP service
copySlaveJarUsingSCP(listener, workingDirectory);
} else {
throw e;
}
} finally {
if (sftpClient != null) {
sftpClient.close();
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* Starts the agent process.
*
* @param computer The computer.
* @param listener The listener.
* @param java The full path name of the java executable to use.
* @param workingDirectory The working directory from which to start the java process.
* @throws IOException If something goes wrong.
*/
private void startAgent(SlaveComputer computer, final TaskListener listener, String java, String workingDirectory) throws IOException {
session = connection.openSession();
expandChannelBufferSize(session, listener);
String cmd = "cd \"" + workingDirectory + "\" && " + java + " " + getJvmOptions() + " -jar " + AGENT_JAR +
getWorkDirParam(workingDirectory);

//This will wrap the cmd with prefix commands and suffix commands if they are set.
cmd = getPrefixStartSlaveCmd() + cmd + getSuffixStartSlaveCmd();

listener.getLogger().println(Messages.SSHLauncher_StartingAgentProcess(getTimestamp(), cmd));
session.execCommand(cmd);

session.pipeStderr(new DelegateNoCloseOutputStream(listener.getLogger()));

try {
computer.setChannel(session.getStdout(), session.getStdin(), listener.getLogger(), null);
} catch (InterruptedException e) {
session.close();
throw new IOException(Messages.SSHLauncher_AbortedDuringConnectionOpen(), e);
} catch (IOException e) {
try {
// often times error this early means the JVM has died, so let's see if we can capture all stderr
// and exit code
throw new AbortException(getSessionOutcomeMessage(session, false));
} catch (InterruptedException x) {
throw new IOException(e);
}
}
}

Remote_root_directory and Remoting_Work_directory分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

分析得到 slave上 可以设置2中 directory. 一种是 Remote_root_directory 一种是 Remoting_Work_directory.

.
├── Remote_root_directory
│   ├── remoting.jar
│   └── workspace
│   └── test
└── Remoting_Work_directory
└── remoting
├── jarCache
│   ├── 04
│   │   └── D04F08030B7FF8337135F2FE2724A7.jar
└── logs
├── remoting.log.0
└── remoting.log.0.lck
Remote_root_directory 目录在这个方法中被创建 private void copyAgentJar(TaskListener listener, String workingDirectory) throws IOException, InterruptedException {
是通过这个创建的 sftpClient.mkdirs(workingDirectory, 0700);



Remoting_Work_directory.目录在这个方法中被创建 private void startAgent(SlaveComputer computer, final TaskListener listener, String java, String workingDirectory) throws IOException {
是通过这个创建的session.execCommand(cmd);
其中cmd是 java -jar remoting.jar -workDir /tmp/mamh/Remoting_Work_directory -jar-cache /tmp/mamh/Remoting_Work_directory/remoting/jarCache
也就是说 Remoting_Work_directory 是在 remoteing.jar 这个包里面的创建的了



这个目录Remoting_Work_directory 主要存放了一些 remote相关的 缓存的jar包, 日志文件等.这个是 ssh-slave 插件 提供的一个设置项, 可以在 高级选项 展开看到的

这个目录Remote_root_directory 主要放了一个 remoting.jar 文件 和我们的jenkins job的 workspace 目录()