-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0914b30
commit 1065b3a
Showing
7 changed files
with
627 additions
and
336 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
__author__ = 'Ondrej Mular <[email protected]>' | ||
__all__ = ["FencingPyCurl"] | ||
|
||
import pycurl | ||
import sys | ||
import atexit | ||
|
@@ -10,14 +7,17 @@ | |
import logging | ||
import pprint | ||
|
||
__all__ = ["FencingPyCurl"] | ||
|
||
## do not add code here. | ||
#BEGIN_VERSION_GENERATION | ||
RELEASE_VERSION = "" | ||
REDHAT_COPYRIGHT = "" | ||
BUILD_DATE = "" | ||
#END_VERSION_GENERATION | ||
|
||
class FencingPyCurl(): | ||
|
||
class FencingPyCurl: | ||
active = False | ||
input_file = None | ||
output_file = None | ||
|
@@ -29,7 +29,10 @@ class FencingPyCurl(): | |
pycurl_obj = None | ||
|
||
def __init__(self): | ||
if not FencingPyCurl.active and (FencingPyCurl.input_file or FencingPyCurl.output_file): | ||
if ( | ||
not FencingPyCurl.active and | ||
(FencingPyCurl.input_file or FencingPyCurl.output_file) | ||
): | ||
FencingPyCurl.active = True | ||
logging.debug("FencingPyCurl is active now") | ||
if FencingPyCurl.active: | ||
|
@@ -48,7 +51,11 @@ def __init__(self): | |
with open(FencingPyCurl.input_file, "r") as f: | ||
FencingPyCurl.actions = json.load(f) | ||
except Exception as e: | ||
logging.debug("Reading input file (%s) failed: %s" % (FencingPyCurl.input_file, e.message)) | ||
logging.debug( | ||
"Reading input file '{file}' failed: {msg}".format( | ||
file=FencingPyCurl.input_file, msg=e.message | ||
) | ||
) | ||
|
||
if FencingPyCurl.output_file: | ||
logging.debug("output file detected") | ||
|
@@ -68,14 +75,17 @@ def setopt(self, opt, value): | |
return self.pycurl_obj.setopt(opt, value) | ||
|
||
def perform(self): | ||
req_ind = FencingPyCurl.request_index | ||
actions = FencingPyCurl.actions | ||
if FencingPyCurl.active: | ||
if FencingPyCurl.input_file: | ||
perform_start = time.time() | ||
if self.options["request"] == FencingPyCurl.actions[FencingPyCurl.request_index]["request"]: | ||
self.options["response"] = FencingPyCurl.actions[FencingPyCurl.request_index]["response"] | ||
if self.options["request"] == actions[req_ind]["request"]: | ||
self.options["response"] = actions[req_ind]["response"] | ||
if self.write_function: | ||
self.write_function(self.options["response"]["output"]) | ||
diff = FencingPyCurl.actions[FencingPyCurl.request_index]["time"]["perform_duration"] - (time.time() - perform_start) | ||
duration = actions[req_ind]["time"]["perform_duration"] | ||
diff = duration - (time.time() - perform_start) | ||
if diff > 0: | ||
logging.debug("sleeping for: %s" % str(diff)) | ||
time.sleep(diff) | ||
|
@@ -84,15 +94,17 @@ def perform(self): | |
print "Request:" | ||
pprint.pprint(self.options["request"]) | ||
print "Expected:" | ||
pprint.pprint(FencingPyCurl.actions[FencingPyCurl.request_index]["request"]) | ||
pprint.pprint(actions[req_ind]["request"]) | ||
raise Exception("Invalid request") | ||
else: | ||
response = self.options["response"] | ||
start_time = time.time() | ||
self.pycurl_obj.perform() | ||
self.options["time"]["perform_duration"] = FencingPyCurl.last_request_time - start_time | ||
self.options["response"]["output"] = self.output_buffer.getvalue() | ||
duration = FencingPyCurl.last_request_time - start_time | ||
self.options["time"]["perform_duration"] = duration | ||
response["output"] = self.output_buffer.getvalue() | ||
if self.write_function: | ||
self.write_function(self.options["response"]["output"]) | ||
self.write_function(response["output"]) | ||
if FencingPyCurl.output_file: | ||
FencingPyCurl.actions.append(self.options) | ||
FencingPyCurl.request_index += 1 | ||
|
@@ -124,31 +136,44 @@ def close(self): | |
@staticmethod | ||
def save_log_to_file(): | ||
if FencingPyCurl.output_file and FencingPyCurl.actions: | ||
logging.debug("Writing log to file: %s" % FencingPyCurl.output_file) | ||
logging.debug( | ||
"Writing log to file: {0}".format(FencingPyCurl.output_file) | ||
) | ||
try: | ||
with open(FencingPyCurl.output_file, "w") as f: | ||
json.dump(FencingPyCurl.actions, f, sort_keys=True, indent=4, separators=(',', ': ')) | ||
json.dump( | ||
FencingPyCurl.actions, | ||
f, | ||
sort_keys=True, | ||
indent=4, | ||
separators=(',', ': ') | ||
) | ||
except Exception as e: | ||
logging.debug("Writing log to file (%s) failed: %s" % (FencingPyCurl.output_file, e.message)) | ||
logging.debug( | ||
"Writing log to file '{file}' failed: {msg}".format( | ||
file=FencingPyCurl.output_file, msg=e.message | ||
) | ||
) | ||
|
||
|
||
def get_and_remove_arg(arg, has_value=True): | ||
logging.debug("Getting arg: %s (has_value: %s)" % (arg, str(has_value))) | ||
logging.debug("Getting arg: '{0}'".format(arg)) | ||
if not has_value: | ||
if arg in sys.argv: | ||
sys.argv.remove(arg) | ||
logging.debug("%s: True" % arg) | ||
logging.debug(arg + ": True") | ||
return True | ||
if arg in sys.argv: | ||
index = sys.argv.index(arg) | ||
sys.argv.remove(arg) | ||
if len(sys.argv) > index: | ||
value = sys.argv[index] | ||
sys.argv.remove(value) | ||
logging.debug("%s: %s" % (arg, value)) | ||
logging.debug("{arg}: {val}".format(arg=arg, val=value)) | ||
return value | ||
return None | ||
|
||
|
||
FencingPyCurl.input_file = get_and_remove_arg("--fencing_pycurl-log-in") | ||
FencingPyCurl.output_file = get_and_remove_arg("--fencing_pycurl-log-out") | ||
|
||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
name = "Simple Status" | ||
actions = [ { "command" : "status", "return_code" : "^[02]$" }, { "command" : "sleep(1)", "return_code" : "^0$" } ] | ||
actions = [ { "command" : "status", "return_code" : "^[02]$" }] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,20 @@ | ||
#!/usr/bin/python | ||
|
||
__author__ = 'Ondrej Mular <[email protected]>' | ||
|
||
import sys | ||
import os | ||
import subprocess | ||
import logging | ||
import json | ||
import time | ||
|
||
INPUT_FILE = os.environ["BINMITM_INPUT"] if "BINMITM_INPUT" in os.environ else None | ||
OUTPUT_FILE = os.environ["BINMITM_OUTPUT"] if "BINMITM_OUTPUT" in os.environ else None | ||
COUNTER_FILE = os.environ["BINMITM_COUNTER_FILE"] if "BINMITM_COUNTER_FILE" in os.environ else ".binmitm_counter" | ||
ENV_VARS = os.environ["BINMITM_ENV"].split(",") if "BINMITM_ENV" in os.environ else [] | ||
INPUT_FILE = os.environ["BINMITM_INPUT"]\ | ||
if "BINMITM_INPUT" in os.environ else None | ||
OUTPUT_FILE = os.environ["BINMITM_OUTPUT"]\ | ||
if "BINMITM_OUTPUT" in os.environ else None | ||
COUNTER_FILE = os.environ["BINMITM_COUNTER_FILE"]\ | ||
if "BINMITM_COUNTER_FILE" in os.environ else ".binmitm_counter" | ||
ENV_VARS = os.environ["BINMITM_ENV"].split(",")\ | ||
if "BINMITM_ENV" in os.environ else [] | ||
IGNORE_TIMING = "BINMITM_IGNORE_TIMING" in os.environ | ||
DEBUG = "BINMITM_DEBUG" in os.environ | ||
|
||
|
@@ -22,18 +24,24 @@ def log_debug(msg): | |
logging.error(msg) | ||
|
||
|
||
def exit(ret): | ||
def _exit(ret): | ||
if COUNTER_FILE and os.path.isfile(COUNTER_FILE): | ||
try: | ||
os.remove(COUNTER_FILE) | ||
except Exception as e: | ||
log_debug("Unable to delete counter file (%s): %s" % (COUNTER_FILE, e.message)) | ||
log_debug("Unable to delete counter file ({0}): {1}".format( | ||
COUNTER_FILE, e.message | ||
)) | ||
try: | ||
with open(COUNTER_FILE, "w") as f: | ||
f.write("0\n") | ||
log_debug("0 written into counter file (%s)" % COUNTER_FILE) | ||
log_debug( | ||
"0 written into counter file ({0})".format(COUNTER_FILE) | ||
) | ||
except Exception as e: | ||
log_debug("Unable to write 0 to counter file (%s): %s" % (COUNTER_FILE, e.message)) | ||
log_debug("Unable to write 0 to counter file ({0}): {1}".format( | ||
COUNTER_FILE, e.message | ||
)) | ||
sys.exit(ret) | ||
|
||
|
||
|
@@ -45,41 +53,52 @@ def get_count(max_count): | |
count = int(f.readline().strip()) | ||
f.seek(0) | ||
f.truncate() | ||
f.write("%d\n" % ((count+1)%max_count)) | ||
f.write("{0}\n".format((count+1) % max_count)) | ||
except Exception as e: | ||
log_debug("Unable to read/write from/to '%s': %s" % (COUNTER_FILE, e.message)) | ||
log_debug("Unable to read/write from/to '{0}': {1}".format( | ||
COUNTER_FILE, e.message | ||
)) | ||
else: | ||
if max_count != 1: | ||
try: | ||
with open(COUNTER_FILE, "w") as f: | ||
f.write("1\n") | ||
except Exception as e: | ||
log_debug("Unable to write to '%s': %s" % (COUNTER_FILE, e.message)) | ||
log_debug("Unable to write to '{0}': {1}".format( | ||
COUNTER_FILE, e.message | ||
)) | ||
return count | ||
|
||
|
||
def record(argv): | ||
output = OUTPUT_FILE and not INPUT_FILE | ||
env = os.environ.copy() | ||
|
||
cur_output = {} | ||
cur_output["request"] = {} | ||
cur_output["response"] = {} | ||
cur_output["time"] = {} | ||
cur_output["request"]["argv"] = argv | ||
cur_output["request"]["env"] = {} | ||
cur_output = { | ||
"request": { | ||
"argv": argv, | ||
"env": {} | ||
}, | ||
"response": {}, | ||
"time": {} | ||
} | ||
|
||
for e in ENV_VARS: | ||
if e in env: | ||
cur_output["request"]["env"][e] = env[e] | ||
|
||
proc_start_time = time.time() | ||
process = None | ||
|
||
try: | ||
process = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) | ||
process = subprocess.Popen( | ||
argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env | ||
) | ||
except OSError as e: | ||
log_debug("Unable to run command '%s': %s" % (" ".join(argv), e.message)) | ||
exit(127) | ||
log_debug("Unable to run command '{0}': {1}".format( | ||
" ".join(argv), e.message | ||
)) | ||
_exit(127) | ||
|
||
status = process.wait() | ||
cur_output["time"]["perform_duration"] = time.time() - proc_start_time | ||
|
@@ -104,7 +123,10 @@ def record(argv): | |
try: | ||
output_values = json.load(f) | ||
except: | ||
log_debug("Parsing output file '%s' failed. It is considered as empty." % OUTPUT_FILE) | ||
log_debug( | ||
"Parsing output file '{0}' failed. It is " | ||
"considered as empty.".format(OUTPUT_FILE) | ||
) | ||
|
||
output_values.append(cur_output) | ||
f.truncate() | ||
|
@@ -113,11 +135,10 @@ def record(argv): | |
else: | ||
with open(OUTPUT_FILE, "w") as f: | ||
json.dump([cur_output], f, indent=4) | ||
except ValueError as e: | ||
log_debug("Unable to parse output file: %s" % e.message) | ||
except IOError as e: | ||
log_debug("Unable to open output file '%s': %s" % (OUTPUT_FILE, e.message)) | ||
|
||
except (IOError, ValueError) as e: | ||
log_debug("Unable to store data to file '{0}': {1}".format( | ||
OUTPUT_FILE, e.message | ||
)) | ||
sys.exit(status) | ||
|
||
|
||
|
@@ -129,45 +150,54 @@ def replay(argv): | |
try: | ||
with open(INPUT_FILE) as f: | ||
input_values = json.load(f) | ||
except ValueError as e: | ||
log_debug("Unable to parse input file: %s" % e.message) | ||
except IOError as e: | ||
log_debug("Unable to open input file '%s': %s" % (INPUT_FILE, e.message)) | ||
except (ValueError, IOError) as e: | ||
log_debug("Unable to parse input file '{0}': {1}".format( | ||
OUTPUT_FILE, e.message | ||
)) | ||
|
||
if not input_values: | ||
log_debug("Empty input") | ||
exit(127) | ||
_exit(127) | ||
|
||
input_number = get_count(len(input_values)) | ||
if input_number >= len(input_values): | ||
log_debug("Unable to get current input") | ||
exit(127) | ||
_exit(127) | ||
|
||
cur_input = input_values[input_number] | ||
if cur_input["request"]["argv"] != argv: | ||
log_debug("Expected different command (Expected: '%s', Given: '%s')" % (" ".join(cur_input["request"]["argv"]), " ".join(argv))) | ||
exit(127) | ||
log_debug( | ||
"Expected different command (Expected: '{0}', Given: '{1}')".format( | ||
" ".join(cur_input["request"]["argv"]), | ||
" ".join(argv) | ||
) | ||
) | ||
_exit(127) | ||
|
||
env.update(cur_input["request"]["env"]) | ||
sys.stderr.write(cur_input["response"]["stderr"]) | ||
sys.stdout.write(cur_input["response"]["stdout"]) | ||
|
||
if not IGNORE_TIMING: | ||
time_left = cur_input["time"]["perform_duration"] - (time.time() - start_time) | ||
time_left = cur_input["time"]["perform_duration"] - ( | ||
time.time() - start_time | ||
) | ||
|
||
if time_left > 0: | ||
log_debug("Sleeping for %f s" % time_left) | ||
log_debug("Sleeping for {0} s".format(time_left)) | ||
time.sleep(time_left) | ||
else: | ||
log_debug("Uooops! We are runnig %f s longer." % abs(time_left)) | ||
log_debug("Uooops! We are running {0} s longer.".format( | ||
abs(time_left) | ||
)) | ||
|
||
sys.exit(cur_input["response"]["return_code"]) | ||
|
||
|
||
def main(argv): | ||
if not argv: | ||
print "No command to run" | ||
exit(127) | ||
_exit(127) | ||
if INPUT_FILE: | ||
replay(argv) | ||
else: | ||
|
@@ -176,4 +206,3 @@ def main(argv): | |
|
||
if __name__ == "__main__": | ||
main(sys.argv[1:]) | ||
|
Oops, something went wrong.