overlord: ghost: add option to reset ghost
Add an option to allow reseting ghost. When ghost is reset, propterties
are also reloaded from file, enabling us to dynamically reload
propterties.
BUG=chromium:517520
TEST=manually
Change-Id: I77b73d390e31f72ba0731f68c92f979258c29fc8
Reviewed-on: https://chromium-review.googlesource.com/300831
Commit-Ready: Wei-Ning Huang <wnhuang@chromium.org>
Tested-by: Wei-Ning Huang <wnhuang@chromium.org>
Reviewed-by: Hsu Wei-Cheng <mojahsu@chromium.org>
diff --git a/py/tools/ghost.py b/py/tools/ghost.py
index a8425b9..94af7c1 100755
--- a/py/tools/ghost.py
+++ b/py/tools/ghost.py
@@ -310,7 +310,8 @@
RANDOM_MID = '##random_mid##'
def __init__(self, overlord_addrs, mode=AGENT, mid=None, sid=None,
- terminal_sid=None, tty_device=None, command=None, file_op=None):
+ prop_file=None, terminal_sid=None, tty_device=None,
+ command=None, file_op=None):
"""Constructor.
Args:
@@ -320,6 +321,7 @@
id is randomly generated.
sid: session ID. If the connection is requested by overlord, sid should
be set to the corresponding session id assigned by overlord.
+ prop_file: properties file filename.
terminal_sid: the terminal session ID associate with this client. This is
use for file download.
tty_device: the terminal device to open, if tty_device is None, as pseudo
@@ -343,6 +345,9 @@
self._machine_id = self.GetMachineID()
self._session_id = sid if sid is not None else str(uuid.uuid4())
self._terminal_session_id = terminal_sid
+ self._ttyname_to_sid = {}
+ self._terminal_sid_to_pid = {}
+ self._prop_file = prop_file
self._properties = {}
self._tty_device = tty_device
self._shell_command = command
@@ -357,8 +362,6 @@
self._target_identity_file = os.path.join(os.path.dirname(
os.path.abspath(os.path.realpath(__file__))), 'ghost_rsa')
self._download_queue = Queue.Queue()
- self._ttyname_to_sid = {}
- self._terminal_sid_to_pid = {}
def SetIgnoreChild(self, status):
# Only ignore child for Agent since only it could spawn child Ghost.
@@ -432,12 +435,13 @@
self.SetIgnoreChild(False)
os.execve(python, [python, scriptpath] + sys.argv[1:], os.environ)
- def LoadPropertiesFromFile(self, filename):
+ def LoadProperties(self):
try:
- with open(filename, 'r') as f:
- self._properties = json.loads(f.read())
+ if self._prop_file:
+ with open(self._prop_file, 'r') as f:
+ self._properties = json.loads(f.read())
except Exception as e:
- logging.exception('LoadPropertiesFromFile: ' + str(e))
+ logging.exception('LoadProperties: ' + str(e))
def CloseSockets(self):
# Close sockets opened by parent process, since we don't use it anymore.
@@ -463,7 +467,8 @@
if pid == 0:
self.CloseSockets()
g = Ghost([self._connected_addr], mode, Ghost.RANDOM_MID, sid,
- terminal_sid, tty_device, command, file_op)
+ terminal_sid=terminal_sid, tty_device=tty_device,
+ command=command, file_op=file_op)
g.Start()
sys.exit(0)
else:
@@ -570,6 +575,7 @@
self._buf = ''
self._last_ping = 0
self._requests = {}
+ self.LoadProperties()
def SendMessage(self, msg):
"""Serialize the message and send it through the socket."""
@@ -1199,19 +1205,24 @@
'properties')
parser.add_argument('--download', metavar='FILE', dest='download', type=str,
default=None, help='file to download')
+ parser.add_argument('--reset', dest='reset', default=False,
+ action='store_true',
+ help='reset ghost and reload all configs')
parser.add_argument('overlord_ip', metavar='OVERLORD_IP', type=str,
nargs='*', help='overlord server address')
args = parser.parse_args()
+ if args.reset:
+ GhostRPCServer().Reconnect()
+ sys.exit()
+
if args.download:
DownloadFile(args.download)
addrs = [('localhost', _OVERLORD_PORT)]
addrs += [(x, _OVERLORD_PORT) for x in args.overlord_ip]
- g = Ghost(addrs, Ghost.AGENT, args.mid)
- if args.prop_file:
- g.LoadPropertiesFromFile(args.prop_file)
+ g = Ghost(addrs, Ghost.AGENT, args.mid, prop_file=args.prop_file)
g.Start(args.lan_disc, args.rpc_server, args.forward_ssh)