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).
Scheduler debug information is being unified under /sys/kernel/debug/sched
for Linux v5.13. Plug in awareness for the new path while still trying the
old one(s) for backwards compatibility.
When Target.conn property is required while the current connection is
already in use, provide a fresh connection to avoid deadlocks. This is
enabled by the @call_conn decorator that is used on all Target methods
that use self.conn directly.
Check that all CPUs are effectively online after a call to
target.hotplug.online_all(), as hotplug issues are common and failure to
bring back up a CPU can be quite problematic.
When SFTP is not available on OpenSSH, paramiko will raise a generic
exception:
paramiko.ssh_exception.SSHException: EOF during negotiation
In order to make it easier to debug, raise a TargetStableError telling
the user to enable SFTP on their server. On OpenSSH, this means
installing the sftp subsystem and enabling it in sshd_config.