Retrieving the netnsid of a network namespace in Python - python

When trying to find the correct peer network interface of a veth pair that lives in a different namespace, that end is not only indicated by its iflink property, but also by a link-netnsid. This link-netnsid is a network namespace ID which is only meaningful within the current network namespace.
The Linux kernel doesn't offer to map a netnsid to a network namespace inode number, which is the only unique identification. However, Linux offers the RTM_GETNSID request that maps a network namespace identified either by fd (NETNSA_FD) or by PID (NETNSA_PID) to the local netnsid.
How do I make such a RTM_GETNSID request in Python, preferably using the pyroute2 library? So far, I could not successfully request the netnsid for the namespace identified by PID, but only get back an invalid argument error 22, using the following script:
from pyroute2 import IPRoute
from pyroute2.netlink import NLM_F_REQUEST
import pyroute2.netlink.rtnl as rtnl
import pyroute2.netlink.rtnl.nsidmsg as nsidmsg
netstack = IPRoute()
req = nsidmsg.nsidmsg()
req['rtgen_family'] = 0
# 12345 is PID of a process inside another network namespace
req['attrs'] = [('NETNSA_PID', 12345)]
ret = netstack.nlm_request(req, rtnl.RTM_GETNSID, NLM_F_REQUEST)

It turns out that my code actually is correct, but there's a bug in pyroute2 causing the RTNETLINK message to be a few octets too short (visible in strace). As a temporary hack around this library bug it is sufficient to set two attributes, so that the kernel accepts the RTNETLINK packet and works on it, even if it isn't fully correct.
from pyroute2 import IPRoute
from pyroute2.netlink import NLM_F_REQUEST
import pyroute2.netlink.rtnl as rtnl
import pyroute2.netlink.rtnl.nsidmsg as nsidmsg
netstack = IPRoute()
req = nsidmsg.nsidmsg()
req['rtgen_family'] = 0
# 12345 is PID of a process inside another network namespace
req['attrs'] = [('NETNSA_PID', 12345), ('NETNSA_PID', 0] # hack around pyroute 0.5.0 bug
ret = netstack.nlm_request(req, rtnl.RTM_GETNSID, NLM_F_REQUEST)

Related

Building the SeeingWand on Raspberry Pi Zero and have coding issues

This is my first posting, so please forgive any lack of decorum
I am building a SeeingWand as outlined in MagPi issue #71.
I have installed and tested all the HW. Then install the python code, the original; code was python2.7, I have update the code to run under python3, but get a strange error when i run the code:
The system displays that the http module does not have a .client attribute.
The documentation says it does. I have tried .client and .server attributes both give the same error. What am i doing wrong?
I have tried several coding variations and several builds of the raspberry OS (Raspbian) mostly give the same errors
import picamera, http, urllib, base64, json, re
from os import system
from gpiozero import Button
CHANGE {MS_API_KEY} BELOW WITH YOUR MICROSOFT VISION API KEY
ms_api_key = "{MS_API_KEY}"
camera button - this is the BCM number, not the pin number
camera_button = Button(27)
setup camera
camera = picamera.PiCamera()
setup vision API
headers = {
'Content-Type': 'application/octet-stream',
'Ocp-Apim-Subscription-Key': ms_api_key,
}
params = urllib.parse.urlencode({
'visualFeatures': 'Description',
})
loop forever waiting for button press
while True:
camera_button.wait_for_press()
camera.capture('/tmp/image.jpg')
body = open('/tmp/image.jpg', "rb").read()
try:
conn = http.client.HTTPsConnection('westcentralus.api.cognitive.microsoft.com')
conn.request("POST", "/vision/v1.0/analyze?%s"%params, body, headers)
response = conn.getresponse()
analysis=json.loads(response.read())
image_caption = analysis["description"]["captions"][0]["text"].capitalize()
# validate text before system() call; use subprocess in next version
if re.match("^[a-zA-z ]+$", image_caption):
system('espeak -ven+f3 -k5 -s120 "' + image_caption + '"')
else :
system('espeak -ven+f3 -k5 -s120 "i do not know what i just saw"')
conn.close()
except Exception as e:
print (e.args)
The system displays an error stating that the http module does not have a .client attribute.
The documentation says it does. I have tried .client and .server attributes both give the same error. What am i doing wrong?
Expected results are:
when i push button 1 I expect the camera to take a picture
when i push button 2 i expect to access MSFT Azure to identify the picture using AI
the final output is for the Wand to access the audio hat and describe what the Wand is "looking" at.
try adding an import like this:
import http.client
Edit: http is a Python package. Even if the package contains some modules, it does not automatically import those modules when you import the package, unless the __init__.py for that package does so on your behalf. In the case of http, the __init__.py is empty, so you get nothing gratis just for importing the package.

python to jython by execnet doesn't run

I'm trying to run a example from http://codespeak.net/execnet/example/hybridpython.html but python freezes on line:
gw = execnet.makegateway("popen//python=jython")
Example:
import execnet
gw = execnet.makegateway("popen//python=jython")
channel = gw.remote_exec("""
from java.util import Vector
v = Vector()
v.add('aaa')
v.add('bbb')
for val in v:
channel.send(val)
""")
for item in channel:
print (item)
I'm on Debian Jessie
If you read the documentation, the following is defined
def makegateway(self, spec=None):
"""create and configure a gateway to a Python interpreter.
The ``spec`` string encodes the target gateway type
and configuration information. The general format is::
key1=value1//key2=value2//...
If you leave out the ``=value`` part a True value is assumed.
Valid types: ``popen``, ``ssh=hostname``, ``socket=host:port``.
Valid configuration::
id=<string> specifies the gateway id
***python=<path> specifies which python interpreter to execute***
execmodel=model 'thread', 'eventlet', 'gevent' model for execution
chdir=<path> specifies to which directory to change
nice=<path> specifies process priority of new process
env:NAME=value specifies a remote environment variable setting.
If no spec is given, self.defaultspec is used.
"""
meaning you should write:
gw = execnet.makegateway("popen//python=C:\\..\\jython2.7.0\\bin\\jython")

WLST execute stored variable "connect()" statement

So, I am passing a environment variable from bash to python;
#!/usr/bin/env python2
import os
#connect("weblogic", "weblogic", url=xxx.xxx.xxx.xxx:xxxx)
os.environ['bash_variable']
via wlst.sh I can print exported bash_variable, but how do I execute stored variable? Basically, I am trying to remove the original connect statement and pass a variable that has said information. Thanks
Question though, why wouldn't you called the script with the variable as an argument and use sys.argv[] ?
By example something like this.
import os
import sys
import traceback
from java.io import *
from java.lang import *
wlDomain = sys.argv[1]
wlDomPath = sys.argv[2]
wlNMHost = sys.argv[3]
wlNMPort = sys.argv[4]
wlDPath="%s/%s" %(wlDomPath,wlDomain)
wlNMprop="/apps/bea/wls/scripts/.shadow/NM.prop"
try:
print "Connection to Node Manager"
print ""
loadProperties(wlNMprop)
nmConnect(username=NMuser,password=NMpass,host=wlNMHost,port=wlNMPort,domainName=wlDomain,domainDir=wlDPath,mType='ssl',verbose='true')
except:
print "Fatal Error : No Connection to Node Manager"
exit()
print "Connected to Node Manager"
The NM.prop file is a 600 file with the username/password for the NM.
EDIT :
So from what I understand you want to do something like this :
URLS = ['t3s://Host1:Port1','t3s://Host2:Port2','t3s://Host3:Port3']
for urls in URLS:
connect('somebody','password',urls)
{bunch of commands}
disconnect()
And the values of the list URLS would be define by the environment.
The way I see it you have 3 choices :
Have 1 script per environment, more or less identical save for the URLS list
Have 1 script but with a conditionnal branching on sys.argv[1] (the environment as a parameter) and create the list there.
Have 1 script which use a parameter file for each environment according to the environment. Each parameter file containing the list in question.
Something like that :
propENV = sys.argv[1]
propPath = "/path1/path2"
propFile = "%s/%s" %(propPath,propENV)
loadProperties(propFile)
I would probably use the properties file option myself as it is more flexible from an operational standpoint...at least IMHO.

How to check whether screen is off in Mac/Python?

How do I check whether the screen is off due to the Energy Saver settings in System Preferences under Mac/Python?
Quick and dirty solution: call ioreg and parse the output.
import subprocess
import re
POWER_MGMT_RE = re.compile(r'IOPowerManagement.*{(.*)}')
def display_status():
output = subprocess.check_output(
'ioreg -w 0 -c IODisplayWrangler -r IODisplayWrangler'.split())
status = POWER_MGMT_RE.search(output).group(1)
return dict((k[1:-1], v) for (k, v) in (x.split('=') for x in
status.split(',')))
In my computer, the value for CurrentPowerState is 4 when the screen is on and 1 when the screen is off.
Better solution: use ctypes to get that information directly from IOKit.
The only way i can think off is by using OSX pmset Power Management CML Tool
DESCRIPTION
pmset changes and reads power management settings such as idle sleep timing, wake on administrative
access, automatic restart on power loss, etc.
Refer to the following link, it will provide a great deal of information that should aid you in accomplishing exactly what you are looking for.
http://managingamac.blogspot.com/2012/12/power-assertions-in-python.html
I will include the code provided by the link for "saving and documentation" purposes:
#!/usr/bin/python
import ctypes
import CoreFoundation
import objc
import subprocess
import time
def SetUpIOFramework():
# load the IOKit library
framework = ctypes.cdll.LoadLibrary(
'/System/Library/Frameworks/IOKit.framework/IOKit')
# declare parameters as described in IOPMLib.h
framework.IOPMAssertionCreateWithName.argtypes = [
ctypes.c_void_p, # CFStringRef
ctypes.c_uint32, # IOPMAssertionLevel
ctypes.c_void_p, # CFStringRef
ctypes.POINTER(ctypes.c_uint32)] # IOPMAssertionID
framework.IOPMAssertionRelease.argtypes = [
ctypes.c_uint32] # IOPMAssertionID
return framework
def StringToCFString(string):
# we'll need to convert our strings before use
return objc.pyobjc_id(
CoreFoundation.CFStringCreateWithCString(
None, string,
CoreFoundation.kCFStringEncodingASCII).nsstring())
def AssertionCreateWithName(framework, a_type,
a_level, a_reason):
# this method will create an assertion using the IOKit library
# several parameters
a_id = ctypes.c_uint32(0)
a_type = StringToCFString(a_type)
a_reason = StringToCFString(a_reason)
a_error = framework.IOPMAssertionCreateWithName(
a_type, a_level, a_reason, ctypes.byref(a_id))
# we get back a 0 or stderr, along with a unique c_uint
# representing the assertion ID so we can release it later
return a_error, a_id
def AssertionRelease(framework, assertion_id):
# releasing the assertion is easy, and also returns a 0 on
# success, or stderr otherwise
return framework.IOPMAssertionRelease(assertion_id)
def main():
# let's create a no idle assertion for 30 seconds
no_idle = 'NoIdleSleepAssertion'
reason = 'Test of Pythonic power assertions'
# first, we'll need the IOKit framework
framework = SetUpIOFramework()
# next, create the assertion and save the ID!
ret, a_id = AssertionCreateWithName(framework, no_idle, 255, reason)
print '\n\nCreating power assertion: status %s, id %s\n\n' % (ret, a_id)
# subprocess a call to pmset to verify the assertion worked
subprocess.call(['pmset', '-g', 'assertions'])
time.sleep(5)
# finally, release the assertion of the ID we saved earlier
AssertionRelease(framework, a_id)
print '\n\nReleasing power assertion: id %s\n\n' % a_id
# verify the assertion has been removed
subprocess.call(['pmset', '-g', 'assertions'])
if __name__ == '__main__':
main()
https://opensource.apple.com/source/PowerManagement/PowerManagement-211/pmset/pmset.c
The code relies on IOPMLib, which functions to make assertions, schedule power events, measure thermals, and more.
https://developer.apple.com/documentation/iokit/iopmlib_h
To call these functions through Python, we must go through the IOKit Framework.
https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/Introduction/Introduction.html
In order for us to manipulate C data types in Python, we'll use a foreign function interface called ctypes.
http://python.net/crew/theller/ctypes/
Here's the wrapper the author describe's on the page; written by Michael Lynn. The code i posted from the Author's link above is a rewrite of this code to make it more understandable.
https://github.com/pudquick/pypmset/blob/master/pypmset.py

udisks FilesystemUnmount appears to not exist when calling from python

I'm trying to unmount a filesystem that I mounted using FilesystemMount, but I keep getting UnknownMethod exceptions. I've verified that I can call the method on the Device interface via D-Feet, but trying to do it via dbus directly doesn't appear to work at all. I've tried using the following arguments:
''
None
[]
['']
The following code demonstrates the problem:
import dbus
bus = dbus.SystemBus()
proxy = bus.get_object('org.freedesktop.UDisks', '/dev/fd0')
dev = dbus.Interface(proxy, 'org.freedesktop.UDisks.Device')
dev.FilesystemUnmount(['force'])
Exception:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: Method "FilesystemUmount" with signature "as" on interface "org.freedesktop.UDisks.Device" doesn't exist
Turns out that the problem is that FilesystemUnmount will only take an ObjectPath that udisks handed out. So by adding a check for that and then looking it up I got it to work. See the code below.
import dbus
path = '/dev/fd0'
bus = dbus.SystemBus()
if not isinstance(path, dbus.ObjectPath):
manager_obj = bus.get_object('org.freedesktop.UDisks',
'/org/freedesktop/UDisks')
manager = dbus.Interface(manager_obj, 'org.freedesktop.UDisks')
path = manager.FindDeviceByDeviceFile(path)
proxy = bus.get_object('org.freedesktop.UDisks', path)
dev = dbus.Interface(proxy, 'org.freedesktop.UDisks.Device')
dev.FilesystemUnmount('')

Categories

Resources