1#!/usr/bin/env python 2# Copyright 2019 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6 7from __future__ import print_function 8import base64 9import re 10import subprocess 11import sys 12 13 14# Usage: win_ssh_cmd.py <user@host> <cmd shell string> [<fail errorlevel>] 15# Runs the given command over ssh and exits with 0 if the command succeeds or 1 16# if the command fails. The command is considered to fail if the errorlevel is 17# greater than or equal to <fail errorlevel>. 18 19 20SENTINEL = 'win_ssh_cmd remote command successful' 21 22 23def main(user_host, cmd, fail_errorlevel): 24 ssh_cmd = ['ssh', '-oConnectTimeout=15', '-oBatchMode=yes', user_host, 25 '(' + cmd + ') & if not errorlevel %s echo %s' % ( 26 fail_errorlevel, SENTINEL)] 27 # True if we saw a line matching SENTINEL. 28 saw_sentinel = False 29 print('Original command:\n%s\nFull command:\n%s' % ( 30 cmd, ' '.join([repr(s) for s in ssh_cmd])), file=sys.stderr) 31 proc = subprocess.Popen(ssh_cmd, stdout=subprocess.PIPE) 32 for line in iter(proc.stdout.readline, ''): 33 stripped = line.strip() 34 if stripped == SENTINEL: 35 saw_sentinel = True 36 else: 37 print(stripped) 38 proc.wait() 39 sys.stdout.flush() 40 if proc.returncode != 0: 41 sys.exit(proc.returncode) 42 if not saw_sentinel: 43 sys.exit(1) 44 sys.exit(0) 45 46 47if __name__ == '__main__': 48 if len(sys.argv) < 3: 49 print('USAGE: %s <user@host> <cmd shell string> [<fail errorlevel>]' % 50 sys.argv[0], file=sys.stderr) 51 sys.exit(1) 52 arg_fail_errorlevel = 1 if len(sys.argv) < 4 else sys.argv[3] 53 main(sys.argv[1], sys.argv[2], arg_fail_errorlevel) 54