• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 
17 package vogar;
18 
19 import com.google.common.annotations.VisibleForTesting;
20 import com.google.common.collect.ImmutableList;
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.util.List;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27 import vogar.android.DeviceFilesystem;
28 import vogar.commands.Command;
29 
30 /**
31  * Runs actions on a remote host using SSH.
32  */
33 public final class SshTarget extends Target {
34     private final Log log;
35     private final String host;
36     private final int port;
37     private final DeviceFilesystem deviceFilesystem;
38     private final ImmutableList<String> sshCommandPrefixList;
39 
40     @VisibleForTesting
SshTarget(Log log, String hostAndPort)41     public SshTarget(Log log, String hostAndPort) {
42         this.log = log;
43         int colon = hostAndPort.indexOf(":");
44         if (colon != -1) {
45             host = hostAndPort.substring(0, colon);
46             port = Integer.parseInt(hostAndPort.substring(colon + 1));
47         } else {
48             host = hostAndPort;
49             port = 22;
50         }
51         sshCommandPrefixList = ImmutableList.of("ssh", "-p", Integer.toString(port), host, "-C");
52         deviceFilesystem = new DeviceFilesystem(log, sshCommandPrefixList);
53     }
54 
defaultDeviceDir()55     public static File defaultDeviceDir() {
56         return new File("/data/local/tmp/vogar");
57     }
58 
targetProcessPrefix()59     @Override protected ImmutableList<String> targetProcessPrefix() {
60         return sshCommandPrefixList;
61     }
62 
await(File nonEmptyDirectory)63     @Override public void await(File nonEmptyDirectory) {
64     }
65 
rm(File file)66     @Override public void rm(File file) {
67         new Command.Builder(log)
68                 .args(sshCommandPrefixList)
69                 .args("rm", "-r", file.getPath())
70                 .permitNonZeroExitStatus(true)
71                 .execute();
72     }
73 
getDeviceUserName()74     @Override public String getDeviceUserName() {
75         // TODO: move this to device set up
76         // The default environment doesn't include $USER, so dalvikvm doesn't set "user.name".
77         // DeviceDalvikVm uses this to set "user.name" manually with -D.
78         String line = new Command.Builder(log)
79                 .args(sshCommandPrefixList)
80                 .args("id")
81                 .execute().get(0);
82         // TODO: use 'id -un' when we don't need to support anything older than M
83         Matcher m = Pattern.compile("^uid=\\d+\\((\\S+)\\) gid=\\d+\\(\\S+\\).*").matcher(line);
84         return m.matches() ? m.group(1) : "root";
85     }
86 
mkdirs(File file)87     @Override public void mkdirs(File file) {
88         deviceFilesystem.mkdirs(file);
89     }
90 
forwardTcp(final int port)91     @Override public void forwardTcp(final int port) {
92         try {
93             new Command(log, "ssh", "-p", Integer.toString(port), host,
94                     "-L", port + ":" + host + ":" + port, "-N").start();
95         } catch (IOException e) {
96             throw new RuntimeException(e);
97         }
98     }
99 
push(File local, File remote)100     @Override public void push(File local, File remote) {
101         new Command(log, "scp", "-r", "-P", Integer.toString(port),
102                 local.getPath(), host + ":" + remote.getPath()).execute();
103     }
104 
ls(File directory)105     @Override public List<File> ls(File directory) throws FileNotFoundException {
106         return deviceFilesystem.ls(directory);
107     }
108 
pull(File remote, File local)109     @Override public void pull(File remote, File local) {
110         new Command(log, "scp", "-r", "-P", Integer.toString(port),
111                 host + ":" + remote.getPath(), local.getPath()).execute();
112     }
113 }
114