xref: /aosp_15_r20/external/skia/infra/bots/recipe_modules/flavor/resources/win_ssh_cmd.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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