hwd

hwd wraps around pyudev‘s Device objects to provide functionality specific to different types of hardware. Currently, hwd provides a base wrapper class that provides common information such as bus, vendor, and model, and classes for wrapping storage and network devices.

hwd is being developed at Outernet specifically for integration of hardware management functionality into Librarian that runs on Outernet receives. As such, there are no plans for adding support for devices that are common on personal computers.

Installing

hwd is in early development, and is therefore not yet published on a PyPI repository. To install the latest development version from GitHub, use this command:

pip install https://github.com/Outernet-Project/hwd/archive/develop.zip

Basic usage

To use the wrapper classes, you need pyudev.Device objects. You can obtain them using pyudev API, or using the devices_by_subsystem() helper function.

Once you have one or more Device objects, you can instantiate the wrapper classes, passing the Device object to the constructor.

API documentation

Base wrapper class

Basic usage

Wrapper class provides access to common basic information about all device types.

Example:

>>> devs = list(udev.devices_by_subsystem('net'))
>>> device = wrapper.Wrapper(devs[0])
>>> device.bus
u'pci'
>>> device.model
u'Wireless 7260 (Dual Band Wireless-AC 7260)'
>>> device.name
u'wlp2s0'
>>> device.vendor
u'Intel Corporate'
>>> device.system_path
u'/sys/devices/pci0000:00/0000:00:1c.3/0000:02:00.0/net/wlp2s0'
>>> device.devid
(u'0x8086', u'0x08b1')

Module contents

class hwd.wrapper.Wrapper(dev)

Generic wrapper class that wraps pyudev.Device instances.

dev is a pyudev.Device instance. Device’s sys_name property is stored as name property on the wrapper instance.

aliases

Return a list of device aliases (symlinks) that match this device. This list also includes the device node so it can be treated as a list of all filesystem objects that point to this device.

bus

Device’s bus. If device is not on any bus, this property evaluates to None.

device

The underlaying pyudev.Device instance can be accessed by using the device property. This propety is cached, so only one lookup is performed to obtain the device object. This cache is invalidated by refresh() method.

devid

Two-tuple containing device’s vendor ID and model ID (hex).

model

First non-empty value from the following list:

  • model name from model database
  • model name as reported by the device driver
  • model ID (hex)

If none of the above attributes are available, evaluates to None.

node

Device node. Not all devices have a node. In case a device has no node, this property evaluates to None.

refresh()

Clears the device cache.

Note

This method does not cause immediate lookup of the udev context. Lookup is done when the device property is accessed.

system_path

System path of the device.

vendor

First non-empty value from the following list:

  • organization name (OUI) from device database
  • vendor from vendor database
  • vendor as reported by the device driver
  • vendor ID (hex)

If none of the above attributes are available, evaluates to None.

Network device wrappers

Basic usage

Module contents

class hwd.network.NetIface(dev)

Wrapper for pyudev.Device objects of ‘net’ subclass.

ipv4addr

IPv4 address.

ipv4gateway

IPv4 default gateway.

ipv4netmask

IPv4 netmask.

ipv6addr

IPv6 address.

ipv6gateway

IPv6 default gateway.

ipv6netmask

IPv6 netmask.

is_connected

Whether there is carrier.

mac

NIC’s MAC address.

type

NIC type. Not all network devices have this value. For wireless devices this value is 'wlan', and for loopback devices, the value is 'loop'. When the value is missing, 'eth' is returned as most ethernet devices authors have encountered have this value missing.

Storage device wrappers

Quick example

Basic usage of storage wrappers uses the disk device type wrapped in Disk wrapper, and accessing disk and partition information using properties on that object. All partitions are accessible through the object’s partitions attribute, so it is not necessary to separately wrap partition objects (though there is nothing wrong with that).

Example:

>>> devs = list(udev.devices_by_subsystem('block'))
>>> device = storage.Disk(devs[0])
>>> device.bus
u'ata'
>>> device.size
256060514304
>>> device.sectors
500118192
>>> device.part_table_type
u'gpt'
>>> p1 = device.partitions[0]
>>> p1.offset
4097
>>> p1.size
314573312
>>> p1.format
u'vfat'

Module contents

class hwd.storage.Disk(dev)

Wrapper for pyudev.Device objects of ‘disk’ type.

is_read_only

Whether disk is read-only. This evaluates to True if disk is read-only.

is_removable

Whether disk is removable. This property evaluates to True if disk is removable. Note that this does not mean disk is USB-attached, and does not necessarily match the common notion of removable devices.

If you wish to know whether a device is USB-attached, check whether the value of the bus property is 'usb'.

part_table_type

Partition table type. Evaluates to either 'dos' or 'gpt'.

partitions

Iterable containing disk’s partition objects. Objects in the iterable are Partition instances.

sectors

Disk size in sectors. If for some reason, this information is not available, this property evaluates to -1.

size

Disk capacity in bytes. This value is obtained by multiplying sector size by 512.

uuid

Partition table UUID. Note that UUIDs for different partition table types have different fomats.

class hwd.storage.Fstat(total, used, free, pct_used, pct_free)
free

Alias for field number 2

pct_free

Alias for field number 4

pct_used

Alias for field number 3

total

Alias for field number 0

used

Alias for field number 1

class hwd.storage.Mountable

Mixing providing interfaces for mountable storage devices.

mount_points

Iterator of partition’s mount points obtained by reading /proc/mounts. Returns empty list if /proc/mounts is not readable or if there are no mount points.

size

Subclasses using this mixin must implement their own size property which returns the total capacity in bytes.

stat

Return disk usage information for the partition in Fstat format. If disk usage information is not available, then None is returned. Disk usage information is only available for regular filesystems that are mounted.

class hwd.storage.MtabEntry(dev, mdir, fstype, opts, cfreq, cpass)
cfreq

Alias for field number 4

cpass

Alias for field number 5

dev

Alias for field number 0

fstype

Alias for field number 2

mdir

Alias for field number 1

opts

Alias for field number 3

class hwd.storage.Partition(dev, disk=None)

Wrapper for pyudev.Device objects of ‘partition’ type.

As with all wrappers, this class takes dev as its first argument. The optional disk argument can be passed, and is stored as the disk property. This is mostly used by Disk class to maintain a refrence to itself.

format

Fiesystem type. This evaluates to any number of supported file system types such as 'ext4' or 'vfat'.

Note

Extended partitions will have this property evaluate to None.

is_extended

Whether partition is extended.

label

Volume label. This property evaluates to None if no volume label is not set on a partition.

number

Partition number. This specifies a position of the partition in the partition table. If the value is not known for some reason, this property evaluates to -1.

offset

Partition offset in sectors. If this information is not available for some reason, it evaluates to -1.

parent_class

alias of Disk

part_type

Partition type ID. This is expressed in hex string. Note that this is not the same as filesystem type which is available through the part_type property.

scheme

Partition entry scheme. This evaluates to either 'dos' or 'gpt'.

sectors

Partition size in sectors. If this information is not available for some reason, it evaluates to -1.

size

Partition size in bytes. This value is obtained by multiplying the sector size by 512.

usage

Filesystem usage (purpose). In most cases this should evaluate to 'filesystem'. In some cases (e.g., swap partition), it may evaluate to 'other' or some other value.

uuid

Filesystem UUID. Note that this is not the same as the partition UUID (which is not available through this wrapper, other than directly accessing the underlying pyudev.Device object).

class hwd.storage.PartitionBase(dev, disk=None)

Base class for all partition devices. This class encapsulates the base functionality for all mountable partitions. It takes disk as an optional argument, and allows access to parent device from the partition devices.

class hwd.storage.UbiContainer(dev)

Wrapper for pyudev.Device objects of the ‘ubi’ subsytem.

The ‘ubi’ subsystem has two types of devices. The parent devices serve as containers for the actual volumes. This class is meant to be used by containers, rather than volumes.

This class mainly exists to facilitate the PartitionBase API, specifically the API that allows access to parent device.

class hwd.storage.UbiVolume(dev, disk=None)

Wrapper for pyudev.Device objects of the ‘ubi’ subsytem.

The ‘ubi’ subsystem has two types of devices. The parent devices serve as containers for the actual volumes. This class is meant to be used by volumes, rather than their parent devices.

aliases

Aliases for UBI volume. This propery evaluates to device node itself plus the 'ubi${INDEX}:${LABEL}' string. The latter is used to identify the device in /proc/mounts table, and is not really an alias.

label

UBI volume name. For compatibility with Partition API, we name this property ‘label’.

parent_class

alias of UbiContainer

sectors

Simulated number of sectors derived from volume size. This property is provided for compatibility with Partition API.

Warning

The concept does not really apply to UBI volumes, so it’s best to not rely on the value of this property.

size

Volume capacity in bytes. This property evaluates to -1 if size information is not available for any reason.

hwd.storage.mounts()

Iterator yielding mount points that appear in /proc/mounts. If /proc/mounts is not readable or does not exist, this function raises an exception.

udev helpers

hwd.udev.devices_by_subsystem(subsys, only=<function <lambda>>)

Iterator that yields devices that belong to specified subsystem. Returned values are pydev.Device instances.

The only argument can be used to further filter devices. It should be a function that takes a pyudev.Device object, and returns True or False to indicate whether device should be returned.

Example:

>>> devices_by_subsystem('net')
[Device('/sys/devices/pci0000:00/0000:00:1c.3/0000:02:00.0/net/wlp2s0'),
 Device('/sys/devices/virtual/net/lo')]