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.device.cloud.GceRemoteCmdFormatter.ScpMode; 20 import com.android.tradefed.log.LogUtil.CLog; 21 import com.android.tradefed.util.CommandResult; 22 import com.android.tradefed.util.CommandStatus; 23 import com.android.tradefed.util.FileUtil; 24 import com.android.tradefed.util.IRunUtil; 25 26 import java.io.File; 27 import java.io.IOException; 28 import java.util.List; 29 30 /** Utility class to handle file from a remote instance */ 31 public class RemoteFileUtil { 32 33 /** 34 * Fetch a remote file in the container instance. 35 * 36 * @param remoteInstance The {@link GceAvdInfo} that describe the device. 37 * @param options a {@link TestDeviceOptions} describing the device options to be used for the 38 * GCE device. 39 * @param runUtil a {@link IRunUtil} to execute commands. 40 * @param timeout in millisecond for the fetch to complete 41 * @param remoteFilePath The remote path where to find the file. 42 * @return True if successful, False otherwise 43 */ fetchRemoteFile( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remoteFilePath)44 public static File fetchRemoteFile( 45 GceAvdInfo remoteInstance, 46 TestDeviceOptions options, 47 IRunUtil runUtil, 48 long timeout, 49 String remoteFilePath) { 50 String fileName = new File(remoteFilePath).getName(); 51 File localFile = null; 52 try { 53 localFile = 54 FileUtil.createTempFile( 55 FileUtil.getBaseName(fileName), FileUtil.getExtension(fileName)); 56 if (fetchRemoteFile( 57 remoteInstance, options, runUtil, timeout, remoteFilePath, localFile)) { 58 return localFile; 59 } 60 } catch (IOException e) { 61 CLog.e(e); 62 } 63 FileUtil.deleteFile(localFile); 64 return null; 65 } 66 67 /** 68 * Fetch a remote file in the device or container instance. 69 * 70 * @param remoteInstance The {@link GceAvdInfo} that describe the device. 71 * @param options a {@link TestDeviceOptions} describing the device options to be used for the 72 * GCE device. 73 * @param runUtil a {@link IRunUtil} to execute commands. 74 * @param timeout in millisecond for the fetch to complete 75 * @param remoteFilePath The remote path where to find the file. 76 * @param localFile The local {@link File} where the remote file will be pulled 77 * @return True if successful, False otherwise 78 */ fetchRemoteFile( GceAvdInfo remoteInstance, TestDeviceOptions options, IRunUtil runUtil, long timeout, String remoteFilePath, File localFile)79 public static boolean fetchRemoteFile( 80 GceAvdInfo remoteInstance, 81 TestDeviceOptions options, 82 IRunUtil runUtil, 83 long timeout, 84 String remoteFilePath, 85 File localFile) { 86 return internalScpExec( 87 remoteInstance, 88 options, 89 null, 90 runUtil, 91 timeout, 92 remoteFilePath, 93 localFile, 94 ScpMode.PULL); 95 } 96 97 /** 98 * Push a {@link File} from the local host to the remote instance 99 * 100 * @param remoteInstance The {@link GceAvdInfo} that describe the device. 101 * @param options a {@link TestDeviceOptions} describing the device options to be used for the 102 * GCE device. 103 * @param scpArgs extra args to be passed to the scp command 104 * @param runUtil a {@link IRunUtil} to execute commands. 105 * @param timeout in millisecond for the fetch to complete 106 * @param remoteFilePath The remote path where to find the file. 107 * @param localFile The local {@link File} where the remote file will be pulled 108 * @return True if successful, False otherwise 109 */ pushFileToRemote( GceAvdInfo remoteInstance, TestDeviceOptions options, List<String> scpArgs, IRunUtil runUtil, long timeout, String remoteFilePath, File localFile)110 public static boolean pushFileToRemote( 111 GceAvdInfo remoteInstance, 112 TestDeviceOptions options, 113 List<String> scpArgs, 114 IRunUtil runUtil, 115 long timeout, 116 String remoteFilePath, 117 File localFile) { 118 return internalScpExec( 119 remoteInstance, 120 options, 121 scpArgs, 122 runUtil, 123 timeout, 124 remoteFilePath, 125 localFile, 126 ScpMode.PUSH); 127 } 128 internalScpExec( GceAvdInfo remoteInstance, TestDeviceOptions options, List<String> scpArgs, IRunUtil runUtil, long timeout, String remoteFilePath, File localFile, ScpMode mode)129 private static boolean internalScpExec( 130 GceAvdInfo remoteInstance, 131 TestDeviceOptions options, 132 List<String> scpArgs, 133 IRunUtil runUtil, 134 long timeout, 135 String remoteFilePath, 136 File localFile, 137 ScpMode mode) { 138 List<String> scpCmd = 139 GceRemoteCmdFormatter.getScpCommand( 140 options.getSshPrivateKeyPath(), 141 scpArgs, 142 options.getInstanceUser(), 143 remoteInstance.hostAndPort().getHostText(), 144 remoteFilePath, 145 localFile.getAbsolutePath(), 146 mode); 147 CommandResult resScp = runUtil.runTimedCmd(timeout, scpCmd.toArray(new String[0])); 148 if (!CommandStatus.SUCCESS.equals(resScp.getStatus())) { 149 StringBuilder builder = new StringBuilder(); 150 builder.append("Issue when "); 151 if (ScpMode.PULL.equals(mode)) { 152 builder.append("pulling "); 153 } else { 154 builder.append("pushing "); 155 } 156 builder.append(String.format("file, status: %s", resScp.getStatus())); 157 CLog.e(builder.toString()); 158 CLog.e("%s", resScp.getStderr()); 159 return false; 160 } else { 161 return true; 162 } 163 } 164 } 165