• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.device.cloud;
17 
18 import com.android.tradefed.device.TestDeviceOptions;
19 import com.android.tradefed.log.LogUtil.CLog;
20 import com.android.tradefed.util.CommandResult;
21 import com.android.tradefed.util.CommandStatus;
22 import com.android.tradefed.util.FileUtil;
23 import com.android.tradefed.util.GceRemoteCmdFormatter;
24 import com.android.tradefed.util.GceRemoteCmdFormatter.ScpMode;
25 import com.android.tradefed.util.IRunUtil;
26 
27 import java.io.File;
28 import java.io.IOException;
29 import java.util.Arrays;
30 import java.util.List;
31 
32 /** Utility class to handle file from a remote instance */
33 public class RemoteFileUtil {
34 
35     /**
36      * Fetch a remote file in the container instance.
37      *
38      * @param remoteInstance The {@link GceAvdInfo} that describe the device.
39      * @param options a {@link TestDeviceOptions} describing the device options to be used for the
40      *     GCE device.
41      * @param runUtil a {@link IRunUtil} to execute commands.
42      * @param timeout in millisecond for the fetch to complete
43      * @param remoteFilePath The remote path where to find the file.
44      * @return The pulled filed if successful, null otherwise
45      */
fetchRemoteFile( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remoteFilePath)46     public static File fetchRemoteFile(
47             GceAvdInfo remoteInstance,
48             TestDeviceOptions options,
49             IRunUtil runUtil,
50             long timeout,
51             String remoteFilePath) {
52         String fileName = new File(remoteFilePath).getName();
53         File localFile = null;
54         try {
55             localFile =
56                     FileUtil.createTempFile(
57                             FileUtil.getBaseName(fileName) + "_", FileUtil.getExtension(fileName));
58             if (fetchRemoteFile(
59                     remoteInstance, options, runUtil, timeout, remoteFilePath, localFile)) {
60                 return localFile;
61             }
62         } catch (IOException e) {
63             CLog.e(e);
64         }
65         FileUtil.deleteFile(localFile);
66         return null;
67     }
68 
69     /**
70      * Fetch a remote file in the device or container instance.
71      *
72      * @param remoteInstance The {@link GceAvdInfo} that describe the device.
73      * @param options a {@link TestDeviceOptions} describing the device options to be used for the
74      *     GCE device.
75      * @param runUtil a {@link IRunUtil} to execute commands.
76      * @param timeout in millisecond for the fetch to complete
77      * @param remoteFilePath The remote path where to find the file.
78      * @param localFile The local {@link File} where the remote file will be pulled
79      * @return True if successful, False otherwise
80      */
fetchRemoteFile( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remoteFilePath, File localFile)81     public static boolean fetchRemoteFile(
82             GceAvdInfo remoteInstance,
83             TestDeviceOptions options,
84             IRunUtil runUtil,
85             long timeout,
86             String remoteFilePath,
87             File localFile) {
88         return internalScpExec(
89                 remoteInstance,
90                 options,
91                 null,
92                 runUtil,
93                 timeout,
94                 remoteFilePath,
95                 localFile,
96                 ScpMode.PULL);
97     }
98 
99     /**
100      * Fetch a remote directory from the remote host.
101      *
102      * @param remoteInstance The {@link GceAvdInfo} that describe the device.
103      * @param options a {@link TestDeviceOptions} describing the device options to be used for the
104      *     GCE device.
105      * @param runUtil a {@link IRunUtil} to execute commands.
106      * @param timeout in millisecond for the fetch to complete
107      * @param remoteDirPath The remote path where to find the directory.
108      * @param localDir The local directory where to put the pulled files.
109      * @return True if successful, False otherwise
110      */
fetchRemoteDir( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remoteDirPath, File localDir)111     public static boolean fetchRemoteDir(
112             GceAvdInfo remoteInstance,
113             TestDeviceOptions options,
114             IRunUtil runUtil,
115             long timeout,
116             String remoteDirPath,
117             File localDir) {
118         return internalScpExec(
119                 remoteInstance,
120                 options,
121                 Arrays.asList("-r"),
122                 runUtil,
123                 timeout,
124                 remoteDirPath,
125                 localDir,
126                 ScpMode.PULL);
127     }
128 
129     /**
130      * Fetch a remote directory from the remote host.
131      *
132      * @param remoteInstance The {@link GceAvdInfo} that describe the device.
133      * @param options a {@link TestDeviceOptions} describing the device options to be used for the
134      *     GCE device.
135      * @param runUtil a {@link IRunUtil} to execute commands.
136      * @param timeout in millisecond for the fetch to complete
137      * @param remoteDirPath The remote path where to find the directory.
138      * @return The pulled directory {@link File} if successful, null otherwise
139      */
fetchRemoteDir( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remoteDirPath)140     public static File fetchRemoteDir(
141             GceAvdInfo remoteInstance,
142             TestDeviceOptions options,
143             IRunUtil runUtil,
144             long timeout,
145             String remoteDirPath) {
146         String dirName = new File(remoteDirPath).getName();
147         File localFile = null;
148         try {
149             localFile = FileUtil.createTempDir(dirName);
150             if (internalScpExec(
151                     remoteInstance,
152                     options,
153                     Arrays.asList("-r"),
154                     runUtil,
155                     timeout,
156                     remoteDirPath,
157                     localFile,
158                     ScpMode.PULL)) {
159                 return localFile;
160             }
161         } catch (IOException e) {
162             CLog.e(e);
163         }
164         FileUtil.deleteFile(localFile);
165         return null;
166     }
167 
168     /**
169      * Check if a file (or directory) exists on the remote instance
170      *
171      * @param remoteInstance The {@link GceAvdInfo} that describe the device.
172      * @param options a {@link TestDeviceOptions} describing the device options to be used for the
173      *     GCE device.
174      * @param runUtil a {@link IRunUtil} to execute commands.
175      * @param timeout in millisecond for the fetch to complete
176      * @param remotePath The remote path where to find the file.
177      * @return whether the file exists or not
178      */
doesRemoteFileExist( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remotePath)179     public static boolean doesRemoteFileExist(
180             GceAvdInfo remoteInstance,
181             TestDeviceOptions options,
182             IRunUtil runUtil,
183             long timeout,
184             String remotePath) {
185         List<String> sshCmd =
186                 GceRemoteCmdFormatter.getSshCommand(
187                         options.getSshPrivateKeyPath(),
188                         null,
189                         options.getInstanceUser(),
190                         remoteInstance.hostAndPort().getHost(),
191                         "ls",
192                         remotePath);
193         CommandResult resSsh = runUtil.runTimedCmd(timeout, sshCmd.toArray(new String[0]));
194         return resSsh != null && CommandStatus.SUCCESS.equals(resSsh.getStatus());
195     }
196 
197     /**
198      * Push a {@link File} from the local host to the remote instance
199      *
200      * @param remoteInstance The {@link GceAvdInfo} that describe the device.
201      * @param options a {@link TestDeviceOptions} describing the device options to be used for the
202      *     GCE device.
203      * @param scpArgs extra args to be passed to the scp command
204      * @param runUtil a {@link IRunUtil} to execute commands.
205      * @param timeout in millisecond for the fetch to complete
206      * @param remoteFilePath The remote path where to find the file.
207      * @param localFile The local {@link File} where the remote file will be pulled
208      * @return True if successful, False otherwise
209      */
pushFileToRemote( GceAvdInfo remoteInstance, TestDeviceOptions options, List<String> scpArgs, IRunUtil runUtil, long timeout, String remoteFilePath, File localFile)210     public static boolean pushFileToRemote(
211             GceAvdInfo remoteInstance,
212             TestDeviceOptions options,
213             List<String> scpArgs,
214             IRunUtil runUtil,
215             long timeout,
216             String remoteFilePath,
217             File localFile) {
218         return internalScpExec(
219                 remoteInstance,
220                 options,
221                 scpArgs,
222                 runUtil,
223                 timeout,
224                 remoteFilePath,
225                 localFile,
226                 ScpMode.PUSH);
227     }
228 
internalScpExec( GceAvdInfo remoteInstance, TestDeviceOptions options, List<String> scpArgs, IRunUtil runUtil, long timeout, String remoteFilePath, File localFile, ScpMode mode)229     private static boolean internalScpExec(
230             GceAvdInfo remoteInstance,
231             TestDeviceOptions options,
232             List<String> scpArgs,
233             IRunUtil runUtil,
234             long timeout,
235             String remoteFilePath,
236             File localFile,
237             ScpMode mode) {
238         List<String> scpCmd =
239                 GceRemoteCmdFormatter.getScpCommand(
240                         options.getSshPrivateKeyPath(),
241                         scpArgs,
242                         options.getInstanceUser(),
243                         remoteInstance.hostAndPort().getHost(),
244                         remoteFilePath,
245                         localFile.getAbsolutePath(),
246                         mode);
247         CommandResult resScp = runUtil.runTimedCmd(timeout, scpCmd.toArray(new String[0]));
248         if (!CommandStatus.SUCCESS.equals(resScp.getStatus())) {
249             StringBuilder builder = new StringBuilder();
250             builder.append("Issue when ");
251             if (ScpMode.PULL.equals(mode)) {
252                 builder.append("pulling ");
253             } else {
254                 builder.append("pushing ");
255             }
256             builder.append(String.format("file, status: %s", resScp.getStatus()));
257             CLog.e(builder.toString());
258             CLog.e("%s", resScp.getStderr());
259             return false;
260         } else {
261             return true;
262         }
263     }
264 }
265