Index: sky/tools/skydb |
diff --git a/sky/tools/skydb b/sky/tools/skydb |
index c810c7df46f7a50e006e20878543308a653b4e99..07248c9b1d30d88e2deb8e436f153b9e4a9e89e5 100755 |
--- a/sky/tools/skydb |
+++ b/sky/tools/skydb |
@@ -6,8 +6,11 @@ |
from skypy.paths import Paths |
from skypy.skyserver import SkyServer |
import argparse |
+import json |
import logging |
import os |
+import requests |
+import signal |
import skypy.configuration as configuration |
import subprocess |
import urlparse |
@@ -19,13 +22,17 @@ SUPPORTED_MIME_TYPES = [ |
'text/plain', |
] |
- |
HTTP_PORT = 9999 |
+PID_FILE_PATH = "/tmp/skydb.pids" |
class SkyDebugger(object): |
def __init__(self): |
self.paths = None |
+ self.pids = {} |
+ # FIXME: This is not android aware nor aware of the port |
+ # skyserver is listening on. |
+ self.base_url = 'http://localhost:7777' |
def _server_root_and_url_from_path_arg(self, url_or_path): |
# This is already a valid url we don't need a local server. |
@@ -46,19 +53,8 @@ class SkyDebugger(object): |
def _in_chromoting(self): |
return os.environ.get('CHROME_REMOTE_DESKTOP_SESSION', False) |
- def main(self): |
- logging.basicConfig(level=logging.INFO) |
- |
- parser = argparse.ArgumentParser(description='Sky launcher/debugger') |
- parser.add_argument('--gdb', action='store_true') |
- parser.add_argument('--use-osmesa', action='store_true', |
- default=self._in_chromoting()) |
- parser.add_argument('url_or_path', nargs='?', type=str) |
- parser.add_argument('--show-command', action='store_true', |
- help='Display the shell command and exit') |
- configuration.add_arguments(parser) |
- args = parser.parse_args() |
- |
+ def _build_mojo_shell_command(self, args): |
+ sky_server = None |
self.paths = Paths(os.path.join('out', args.configuration)) |
content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer') |
@@ -73,33 +69,126 @@ class SkyDebugger(object): |
if args.use_osmesa: |
shell_command.append('--args-for=mojo:native_viewport_service --use-osmesa') |
- server_root = None |
- |
if args.url_or_path: |
# Check if we need a local server for the url/path arg: |
server_root, url = \ |
self._server_root_and_url_from_path_arg(args.url_or_path) |
+ sky_server = SkyServer(self.paths, HTTP_PORT, args.configuration, |
+ server_root) |
+ |
prompt_args = '--args-for=mojo:sky_debugger_prompt %s' % url |
shell_command.append(prompt_args) |
if args.gdb: |
shell_command = ['gdb', '--args'] + shell_command |
- if server_root: |
- with SkyServer(self.paths, HTTP_PORT, args.configuration, |
- server_root): |
- subprocess.check_call(shell_command) |
- else: |
- subprocess.check_call(shell_command) |
+ return shell_command, sky_server |
+ |
+ def start_command(self, args): |
+ shell_command, sky_server = self._build_mojo_shell_command(args) |
if args.show_command: |
print " ".join(shell_command) |
+ return |
+ |
+ self.stop_command([]) # Quit any existing process. |
+ |
+ if sky_server: |
+ self.pids['sky_server_pid'] = sky_server.start() |
+ # self.pids['sky_server_port'] = sky_server.port |
+ # self.pids['sky_server_root'] = sky_server.root |
+ self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid |
+ |
+ def _kill_if_exists(self, key, name): |
+ pid = self.pids.pop(key, None) |
+ if not pid: |
+ logging.info('No pid for %s, nothing to do.' % name) |
+ return |
+ logging.info('Killing %s (%s).' % (name, pid)) |
+ try: |
+ os.kill(pid, signal.SIGTERM) |
+ except OSError: |
+ logging.info('%s (%s) already gone.' % (name, pid)) |
+ |
+ def stop_command(self, args): |
+ # FIXME: Send /quit to sky prompt instead of killing. |
+ # self._send_command_to_sky('/quit') |
+ self._kill_if_exists('mojo_shell_pid', 'mojo_shell') |
+ self._kill_if_exists('sky_server_pid', 'sky_server') |
+ |
+ def load_command(self, args): |
+ # Should resolve paths to relative urls like start does. |
+ # self.pids['sky_server_root'] and port should help. |
+ self._send_command_to_sky('/load', args.url_or_path) |
+ |
+ def _send_command_to_sky(self, command_path, payload=None): |
+ url = self.base_url + command_path |
+ if payload: |
+ response = requests.post(url, payload) |
else: |
- subprocess.check_call(shell_command) |
+ response = requests.get(url) |
+ print response.text |
+ |
+ # FIXME: These could be made into a context object with __enter__/__exit__. |
+ def _load_pid_file(self, path): |
+ try: |
+ with open(path, 'r') as pid_file: |
+ return json.load(pid_file) |
+ except: |
+ if os.path.exists(path): |
+ logging.warn('Failed to read pid file: %s' % path) |
+ return {} |
+ |
+ def _write_pid_file(self, path, pids): |
+ try: |
+ with open(path, 'w') as pid_file: |
+ json.dump(pids, pid_file) |
+ except: |
+ logging.warn('Failed to write pid file: %s' % path) |
+ |
+ def _add_basic_command(self, subparsers, name, url_path, help_text): |
+ parser = subparsers.add_parser(name, help=help_text) |
+ command = lambda args: self._send_command_to_sky(url_path) |
+ parser.set_defaults(func=command) |
+ |
+ def main(self): |
+ logging.basicConfig(level=logging.INFO) |
+ |
+ self.pids = self._load_pid_file(PID_FILE_PATH) |
+ |
+ parser = argparse.ArgumentParser(description='Sky launcher/debugger') |
+ subparsers = parser.add_subparsers(help='sub-command help') |
+ |
+ start_parser = subparsers.add_parser('start', |
+ help='launch a new mojo_shell with sky') |
+ configuration.add_arguments(start_parser) |
+ start_parser.add_argument('--gdb', action='store_true') |
+ start_parser.add_argument('--use-osmesa', action='store_true', |
+ default=self._in_chromoting()) |
+ start_parser.add_argument('url_or_path', nargs='?', type=str) |
+ start_parser.add_argument('--show-command', action='store_true', |
+ help='Display the shell command and exit') |
+ start_parser.set_defaults(func=self.start_command) |
+ |
+ stop_parser = subparsers.add_parser('stop', |
+ help=('stop sky (as listed in %s)' % PID_FILE_PATH)) |
+ stop_parser.set_defaults(func=self.stop_command) |
+ |
+ self._add_basic_command(subparsers, 'trace', '/trace', |
+ 'toggle tracing') |
+ self._add_basic_command(subparsers, 'reload', '/reload', |
+ 'reload the current page') |
+ self._add_basic_command(subparsers, 'inspect', '/inspect', |
+ 'stop the running sky instance') |
+ |
+ load_parser = subparsers.add_parser('load', |
+ help='load a new page in the currently running sky') |
+ load_parser.add_argument('url_or_path', type=str) |
+ load_parser.set_defaults(func=self.load_command) |
+ |
+ args = parser.parse_args() |
+ args.func(args) |
- def shutdown(self): |
- print "Quitting" |
- if self._sky_server: |
- self._sky_server.terminate() |
+ self._write_pid_file(PID_FILE_PATH, self.pids) |
if __name__ == '__main__': |