Alexis Lucido
02/14/2022, 10:58 AMKevin Kho
source {}.format
to make the command is a bit concerning because this gets evaluated during Flow registration, not during runtime. I don’t know if that’s what you intended, but it would be better if you had a task that returned this instead to defer the execution to runtime.
You are right that exit code 1 sounds like a permission issue. Your attempts to get more logs also look right. I don’t know why you aren’t getting more.
There is a way to get the whole traceback to show in the logs. I can give an example snippet, but in this case I don’t think it’ll generate anythingdef custom_task(func=None, **task_init_kwargs):
if func is None:
return partial(custom_task, **task_init_kwargs)
@wraps(func)
def safe_func(**kwargs):
try:
return func(**kwargs)
except Exception as e:
print(f"Full Traceback: {traceback.format_exc()}")
raise RuntimeError(type(e)) from None # from None is necessary to not log the stacktrace
safe_func.__name__ = func.__name__
return task(safe_func, **task_init_kwargs)
@custom_task
def abc(x):
return x
Alexis Lucido
02/14/2022, 5:46 PMKevin Kho
workflows_compute()…
. This is computed during build time, not run time so you might not have it during the Flow run. you need it in a task to defer executionAlexis Lucido
02/15/2022, 4:04 PMKevin Kho
Alexis Lucido
02/15/2022, 5:18 PMKevin Kho
workflows_compute
is a module. I understand. Will take a look again at the codesource{}.format
is skill a bit concerning in the Flow because I think that is evaluated during build timeAlexis Lucido
02/16/2022, 8:17 AMKevin Kho
Alexis Lucido
03/03/2022, 10:59 AMkill_geckodriver_task = ShellTask(
log_stderr=True, return_all=True, stream_output=True)
with Flow('kill_geckodriver', schedule=schedules_prefect[
'kill_geckodriver']) as kill_geckodriver:
kill_geckodriver_task(command='pkill geckodriver; pkill firefox')
Here is the traceback:
Looking up flow metadata... Done
Creating run for flow 'kill_geckodriver'... Done
└── Name: gabby-skua
└── UUID: 54bd621e-a8c0-409f-a8f6-f6d19c34890b
└── Labels: ['agentless-run-13ef9b7f']
└── Parameters: {}
└── Context: {}
└── URL: <http://localhost:8080/default/flow-run/54bd621e-a8c0-409f-a8f6-f6d19c34890b>
Executing flow run...
└── 11:55:03 | INFO | Creating subprocess to execute flow run...
└── 11:55:03 | INFO | Beginning Flow run for 'kill_geckodriver'
└── 11:55:03 | INFO | Task 'ShellTask': Starting task run...
└── 11:55:03 | ERROR | Command failed with exit code 1
└── 11:55:03 | INFO | FAIL signal raised: FAIL('Command failed with exit code 1')
└── 11:55:04 | INFO | Task 'ShellTask': Finished task run for task with final state: 'Failed'
└── 11:55:04 | INFO | Flow run FAILED: some reference tasks failed.
Flow run failed!
These commands raise Exception only when run through Prefect. I can run dummy stuff like "echo 1" with a Shell task though.Kevin Kho
Alexis Lucido
03/04/2022, 9:53 AMkill_process_task = ShellTask(
log_stderr=True, return_all=True, stream_output=True)
with Flow('kill_geckodriver', schedule=schedules_prefect[
'kill_geckodriver']) as kill_geckodriver:
kill_process_task(command='source bash/kill_geckodriver.sh')
kill_process_task(command='source bash/kill_firefox.sh')
Then, the scripts (I only write one of both but they are identical, except for the process killed):
#!/bin/bash
pkill geckodriver
pkillexitstatus=$?
if [ "$pkillexitstatus" -eq "0" ]; then
echo "One or more processes matched the criteria and have been killed. Operation successful."
return 0
elif [ "$pkillexitstatus" -eq "1" ]; then
echo "No processes matched. Operation successful."
return 0
elif [ "$pkillexitstatus" -eq "2" ]; then
echo "Syntax error in the command line. Failure."
return 1
elif [ "$pkillexitstatus" -eq "3" ]; then
echo "Fatal error. Failure."
return 1
else
echo "UNEXPECTED. Failure."
return 1
fi
In the end, that was a Linux issue... We had troubles with geckodriver processes not correctly killed by our Python tasks so we added this maintenance flow, and we'd rather keep it as a security. Thanks a lot Kevin!Kevin Kho