-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathawsr
executable file
·132 lines (111 loc) · 3.17 KB
/
awsr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/python
# Licensed under http://www.apache.org/licenses/LICENSE-2.0
import os
import sys
import tempfile
rd = tempfile.gettempdir() + "/awsr_rd"
wr = tempfile.gettempdir() + "/awsr_wr"
def run_client():
with open(rd, "w") as out:
out.write(" ".join(sys.argv))
out.write("\n")
if "-" in sys.argv:
while True:
data = sys.stdin.read(4096)
if data == "":
break
out.write(data)
last = None
with open(wr, "r") as inp:
while True:
result = inp.read(4096)
if len(result) == 0:
break
if last is not None:
sys.stdout.write(last)
sys.stdout.write(result[:-1])
last = result[-1:]
return ord(last)
def run_daemon():
from awscli.clidriver import CLIOperationCaller, LOG, create_clidriver, HISTORY_RECORDER
def patchedInit(self, session):
self._session = session
self._client = None
def patchedInvoke(self, service_name, operation_name, parameters, parsed_globals):
if self._client is None:
LOG.debug("Creating new %s client" % service_name)
self._client = self._session.create_client(
service_name, region_name=parsed_globals.region,
endpoint_url=parsed_globals.endpoint_url,
verify=parsed_globals.verify_ssl)
client = self._client
response = self._make_client_call(
client, operation_name, parameters, parsed_globals)
self._display_response(operation_name, response, parsed_globals)
return 0
CLIOperationCaller.__init__ = patchedInit
CLIOperationCaller.invoke = patchedInvoke
driver = create_clidriver()
while True:
with open(rd, "r") as inp:
os.dup2(inp.fileno(), 0)
args = bytes()
while True:
ch = os.read(inp.fileno(), 1)
if ch == b"\n" or ch == b"":
break
args += ch
args = args.decode("utf-8").split(" ")[1:]
if len(args) > 0 and args[0] == "exit":
sys.exit(0)
sys.stdin = inp
old_stdout = sys.stdout
try:
with open(wr, "w") as sys.stdout:
try:
rc = driver.main(args)
except SystemExit as e:
rc = 2
# encode return code in the last byte of stdout
sys.stdout.write(chr(rc))
HISTORY_RECORDER.record('CLI_RC', rc, 'CLI')
except BrokenPipeError:
pass
sys.stdout = old_stdout
def main():
if not os.access(rd, os.R_OK | os.W_OK):
os.mkfifo(rd)
if not os.access(wr, os.R_OK | os.W_OK):
os.mkfifo(wr)
if os.environ.get("AWSR_CLIENT") == "True":
rc = run_client()
sys.exit(rc)
elif os.environ.get("AWSR_DAEMON") == "True":
try:
run_daemon()
finally:
os.remove(rd)
os.remove(wr)
return
# fork if awsr daemon is not already running
import psutil
import subprocess
ps = psutil.process_iter(attrs=["cmdline"])
procs = 0
for p in ps:
cmd = p.info["cmdline"]
if cmd and len(cmd) > 1 and cmd[0].endswith("python") and cmd[1] == sys.argv[0]:
procs += 1
if procs < 2:
sys.stderr.write("Forking new awsr background process\n")
with open(os.devnull, 'r+b', 0) as DEVNULL:
# new instance will see env var, and run itself as daemon
p = subprocess.Popen(sys.argv, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, close_fds=True, env={
"AWSR_DAEMON": "True",
"AWS_PROFILE": os.environ.get("AWS_PROFILE", "default"),
})
run_client()
else:
run_client()
if __name__ == "__main__":
main()