Both move_all_tasks_to() and move_tasks() take a list of grep patterns
to exclude.
It turned out that move_all_tasks_to() was calling move_tasks() with a
string instead of a list, leading to broken quoting.
Fix that by passing the pattern list to move_tasks() and let
move_tasks() add the "-e" option in front of it. Also add a
DeprecationWarning in move_tasks() if someone passes a string instead of
an iterable of strings.
Rather than systematically clearing the buffer on reset(), record the
timestamp of the last entry and use it to filter-out old entries in
DmesgCollector.entries property.
This also allows detecting if the ring buffer has ran out of memory, or
if something has cleared the buffer while collecting, leading to missing
entries.
Currently, it is not possible to push/pull files with a relative path when
the destination doesn't exist. This is due to the basename resolution. Fix
this behaviour.
Change default FtraceCollector(tracing_path=...) to None, and
auto-detect mount point when None is given.
Also expose an FtraceCollector.find_tracing_path() method so that user
code can also access this path without having to instantiate an
FtraceCollector.
Check that the function exists and then run it, to avoid endless
copy-pasting.
Also call it with "$@", which will achieve proper CLI params forwarding
unlike "$*" which will not.
The command used to detect the presence of a filepath can return
the wrong value if only accessible by the superuser.
Pass the `as_root` parameter to the detection function to ensure
that files that are to be pulled with elevated permissions are
also queried with elevated permission.
Some Android devices do not have 'su'. But if they are already
rooted, there's no reason to fail. Circumvent this scenario by never
using 'su' for device already rooted.
Use target.list_directory(as_root=target.is_rooted) instead of doing it
as a normal user for paths in /sys/kernel/debug. Since this
list_directory() call can be used with multiple path, we do not force
as_root=True but we increase the chance of it working.
__getstate__ is also used by the copy module, but allows pickling the
class as well. This is useful when using the multiprocessing API, which
requires pickling the Target object to send it to the new process.
The default versions used for sphinx and docuilts on
readthedocs are no longer compatible. Explicitly list
the package versions that should be used when building
the documentation.
SSH servers seem to have a maximum number of opened channels, after
which paramiko will raise an exception:
Could not open an SSH channel: ChannelException(2, 'Connect failed')
Memoizing the SFTPClient object based on the timeout setting leads to
many opened sessions, since the timeout is typically adjusted, e.g. to
match the size of the file when pulling an ftrace trace.dat file.
Solve that by memoizing the SFTPClient based only on the connection
object, with a maximum number of 1 cached object, and update its timeout
setting inplace.
Avoid an execute() by doing the check in the same command. This also
allows to return early if the write is fast, and to extend for longer if
the write is slow. The speed at which you can observe a write in sysfs
depends on the backing kernel handlers, so there is a wide variety of
situations.
Also, make a more fine grained error detection by allowing the write
itself to fail, which can happen when writing invalid values to sysfs.
Add Target{Stable,Transient}CalledProcessError exceptions, with an
.returncode and .output attributes, raised by Target.execute(),
mirroring subprocess.CalledProcessError.
This is very useful in client code that uses "exit N" to signal an
abnormal condition, and then inspects the output to find out more.
Handle in one place the decision of what is the real destination of each
file in push/pull operations.
The following can now be assumed by the connection:
* The destination does not exist.
* The folder containing the destination does exist.
This ensures consistent errors and behaviors across all connection
types, at the cost of:
* At least an extra execute() per source (up to 2 if the destination
is a file that needs to be removed to make room).
* For now, globbing will lead to a separate request for each file,
rather than a merged one. This is because the destination of each
source is prepared so that the connection will not have any
interpretation work to do.
Since we have the guarantee to have a different SshConnection per
thread, we can memoize paramiko's SFTPClient. This provides a great
performance boost.
The main path is reading /proc/config.gz. If it does not exists, the
following paths are tested:
'/boot/config', '/boot/config-$(uname -r)'
Since the 2nd path contains a command to be executed, remove quoting of
the path when using "cat".
Newer Android versions do not include any of the attributes that we're
currently looking for in the "dumpsys power" output. Instead they have
"mWakefulness" which can either be "Asleep" or "Awake". Adjust the regex to
look for that attribute as well.
Build of commit 2191498dc35d629003591f727b604120fabbe02d, which is a few
commits after 2.9.1 release. This version has been in use in LISA for
months now so it should work well.
Add a communicate() method in the style of Popen.communicate().
Unlike Popen.communicate, it will raise a CalledProcessError if the
command exit with non-zero code.
The Popen object created for background command currently has no stdin
pipe, preventing the user from writing to it (it will be None instead of
being a file-like object).
Fix that by passing stdin=subprocess.PIPE to Popen constructor.
When using an ssh background command, the data is read from paramiko as
it comes and stored in a buffering pipe by a thread. Currently, the
ParamikoBackgroundCommand API will report the command as having
completed as soon as paramiko reports it. This however does not
necessarily mean that the pipe-filling thread is finished copying the
streams, and the client will end up assuming there is no more data to
read even though it's not the case.
Fix that by ensuring that when poll() returns non-None, the output
streams are ready to be drained.
Move methods related to the scp command into TelnetConnection, since
SshConnection do not use it at all anymore (it has been replaced by the
"scp" python package, piggy backing on paramiko).