overlord: allow explicitly specify upload destination
Add a 'dest' option to the HTTP upload API to allow explicit specify
upload destination. The order for determine upload destination is:
1. If dest is specified
2. If terminal_sid is specified
3. HOME directory
4. /tmp
BUG=chromium:517520
TEST=use the ovl command in CL:291940.
`ovl push test_file /some/dir/`
`ovl push test_file /some/dir`
Change-Id: I4b5c60110daa178a2fa253f998da50a92204f186
Reviewed-on: https://chromium-review.googlesource.com/302241
Commit-Ready: Wei-Ning Huang <aitjcize@gmail.com>
Tested-by: Wei-Ning Huang <aitjcize@gmail.com>
Tested-by: Wei-Ning Huang <wnhuang@chromium.org>
Reviewed-by: Rong Chang <rongchang@chromium.org>
diff --git a/py/tools/ghost.py b/py/tools/ghost.py
index 8c68ce2..4ba4ba7 100755
--- a/py/tools/ghost.py
+++ b/py/tools/ghost.py
@@ -330,9 +330,8 @@
tty_device: the terminal device to open, if tty_device is None, as pseudo
terminal will be opened instead.
command: the command to execute when we are in SHELL mode.
- file_op: a tuple (action, filepath, pid). action is either 'download' or
- 'upload'. pid is the pid of the target shell, used to determine where
- the current working is and thus where to upload to.
+ file_op: a tuple (action, filepath). action is either 'download' or
+ 'upload'.
port: port number to forward.
"""
assert mode in [Ghost.AGENT, Ghost.TERMINAL, Ghost.SHELL, Ghost.FILE,
@@ -785,19 +784,8 @@
def StartUploadServer(self):
logging.info('StartUploadServer: started')
-
try:
filepath = self._file_op[1]
-
- if not filepath.startswith('/'):
- target_dir = os.getenv('HOME', '/tmp')
-
- # Get the client's working dir, which is our target upload dir
- if self._file_op[2]:
- target_dir = os.readlink('/proc/%d/cwd' % self._file_op[2])
-
- filepath = os.path.join(target_dir, filepath)
-
dirname = os.path.dirname(filepath)
if not os.path.exists(dirname):
try:
@@ -871,16 +859,59 @@
self._last_ping = self.Timestamp()
self.SendRequest('ping', {}, timeout_handler, 5)
- def HanldeFileDownloadRequest(self, msg):
+ def HandleFileDownloadRequest(self, msg):
params = msg['params']
+ filepath = params['filename']
+ if not os.path.isabs(filepath):
+ filepath = os.path.join(os.getenv('HOME', '/tmp'), filepath)
+
try:
- os.stat(params['filename'])
+ os.stat(filepath)
except OSError as e:
- self.SendResponse(msg, str(e))
- return
+ return self.SendResponse(msg, str(e))
self.SpawnGhost(self.FILE, params['sid'],
- file_op=('download', params['filename'], None))
+ file_op=('download', filepath))
+ self.SendResponse(msg, SUCCESS)
+
+ def HandleFileUploadRequest(self, msg):
+ params = msg['params']
+
+ # Resolve upload filepath
+ filename = params['filename']
+ dest_path = filename
+
+ # If dest is specified, use it first
+ dest_path = params.get('dest', '')
+ if dest_path:
+ if not os.path.isabs(dest_path):
+ dest_path = os.path.join(os.getenv('HOME', '/tmp'), dest_path)
+
+ if os.path.isdir(dest_path):
+ dest_path = os.path.join(dest_path, filename)
+ else:
+ target_dir = os.getenv('HOME', '/tmp')
+
+ # Terminal session ID found, upload to it's current working directory
+ if params.has_key('terminal_sid'):
+ pid = self._terminal_sid_to_pid.get(params['terminal_sid'], None)
+ if pid:
+ target_dir = os.readlink('/proc/%d/cwd' % pid)
+
+ dest_path = os.path.join(target_dir, filename)
+
+ try:
+ os.makedirs(os.path.dirname(dest_path))
+ except Exception:
+ pass
+
+ try:
+ with open(dest_path, 'w') as _:
+ pass
+ except Exception as e:
+ return self.SendResponse(msg, str(e))
+
+ self.SpawnGhost(self.FILE, params['sid'], file_op=('upload', dest_path))
self.SendResponse(msg, SUCCESS)
def HandleRequest(self, msg):
@@ -897,14 +928,11 @@
self.SpawnGhost(self.SHELL, params['sid'], command=params['command'])
self.SendResponse(msg, SUCCESS)
elif command == 'file_download':
- self.HanldeFileDownloadRequest(msg)
+ self.HandleFileDownloadRequest(msg)
elif command == 'clear_to_download':
self.StartDownloadServer()
elif command == 'file_upload':
- pid = self._terminal_sid_to_pid.get(params['terminal_sid'], None)
- self.SpawnGhost(self.FILE, params['sid'],
- file_op=('upload', params['filename'], pid))
- self.SendResponse(msg, SUCCESS)
+ self.HandleFileUploadRequest(msg)
elif command == 'forward':
self.SpawnGhost(self.FORWARD, params['sid'], port=params['port'])
self.SendResponse(msg, SUCCESS)
@@ -963,7 +991,7 @@
ttyname, filename = self._download_queue.get()
sid = self._ttyname_to_sid[ttyname]
self.SpawnGhost(self.FILE, terminal_sid=sid,
- file_op=('download', filename, None))
+ file_op=('download', filename))
def Listen(self):
try: